mirror of
https://github.com/vdukhovni/postfix
synced 2025-09-02 15:15:24 +00:00
postfix-2.3-20050627
This commit is contained in:
committed by
Viktor Dukhovni
parent
df5802491a
commit
6122cc449d
@@ -10931,8 +10931,34 @@ Apologies for any names omitted.
|
|||||||
util/attr_print0.c, global/dsb_scan.c, global/dsn_print.c,
|
util/attr_print0.c, global/dsb_scan.c, global/dsn_print.c,
|
||||||
global/rcpt_buf,c global/rcpt_print.c, global/deliver_pass.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:
|
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
|
Laptop friendliness: make the qmgr remember when the next
|
||||||
deferred queue scan needs to be done, and have the pickup
|
deferred queue scan needs to be done, and have the pickup
|
||||||
server stat() the maildrop directory before searching it.
|
server stat() the maildrop directory before searching it.
|
||||||
|
@@ -281,11 +281,16 @@ LMTP(8) LMTP(8)
|
|||||||
P.O. Box 704
|
P.O. Box 704
|
||||||
Yorktown Heights, NY 10598, USA
|
Yorktown Heights, NY 10598, USA
|
||||||
|
|
||||||
Alterations for LMTP by:
|
Modifications for LMTP by:
|
||||||
Philip A. Prindeville
|
Philip A. Prindeville
|
||||||
Mirapoint, Inc.
|
Mirapoint, Inc.
|
||||||
USA.
|
USA.
|
||||||
|
|
||||||
|
SASL support originally by:
|
||||||
|
Till Franke
|
||||||
|
SuSE Rhein/Main AG
|
||||||
|
65760 Eschborn, Germany
|
||||||
|
|
||||||
Additional work on LMTP by:
|
Additional work on LMTP by:
|
||||||
Amos Gouaux
|
Amos Gouaux
|
||||||
University of Texas at Dallas
|
University of Texas at Dallas
|
||||||
|
@@ -6206,7 +6206,7 @@ The default time unit is s (seconds).
|
|||||||
<p>
|
<p>
|
||||||
The maximal number of MX (mail exchanger) IP addresses that can
|
The maximal number of MX (mail exchanger) IP addresses that can
|
||||||
result from mail exchanger lookups, or zero (no limit). Prior to
|
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>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
|
@@ -50,6 +50,12 @@ SMTP-SINK(1) SMTP-SINK(1)
|
|||||||
Reject the specified commands with a hard (5xx)
|
Reject the specified commands with a hard (5xx)
|
||||||
error code. This option implies <b>-p</b>.
|
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>-F</b> Disable XFORWARD support.
|
||||||
|
|
||||||
<b>-h</b> <i>hostname</i>
|
<b>-h</b> <i>hostname</i>
|
||||||
@@ -73,21 +79,34 @@ SMTP-SINK(1) SMTP-SINK(1)
|
|||||||
Disconnect (without replying) after receiving one
|
Disconnect (without replying) after receiving one
|
||||||
of the specified commands.
|
of the specified commands.
|
||||||
|
|
||||||
<b>-r</b> <i>command,command,...</i>
|
Examples of commands are HELO, EHLO, LHLO, MAIL,
|
||||||
Reject the specified commands with a soft (4xx)
|
RCPT, VRFY, DATA, ., RSET, NOOP, and QUIT. Separate
|
||||||
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
|
|
||||||
command names by white space or commas, and use
|
command names by white space or commas, and use
|
||||||
quotes to protect white space from the shell. Com-
|
quotes to protect white space from the shell. Com-
|
||||||
mand names are case-insensitive.
|
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)
|
<b>-t</b> <i>timeout</i> (default: 100)
|
||||||
Limit the time for receiving a command or sending a
|
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.
|
<b>-v</b> Show the SMTP conversations.
|
||||||
|
|
||||||
@@ -96,7 +115,7 @@ SMTP-SINK(1) SMTP-SINK(1)
|
|||||||
mand.
|
mand.
|
||||||
|
|
||||||
[<b>inet:</b>][<i>host</i>]:<i>port</i>
|
[<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
|
interface) TCP port <i>port</i>. Both <i>host</i> and <i>port</i> may be
|
||||||
specified in numeric or symbolic form.
|
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>.
|
Listen on the UNIX-domain socket at <i>pathname</i>.
|
||||||
|
|
||||||
<i>backlog</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.
|
tions, as defined by the <b>listen</b>(2) system call.
|
||||||
|
|
||||||
<b>SEE ALSO</b>
|
<b>SEE ALSO</b>
|
||||||
<a href="smtp-source.1.html">smtp-source(1)</a>, SMTP/LMTP message generator
|
<a href="smtp-source.1.html">smtp-source(1)</a>, SMTP/LMTP message generator
|
||||||
|
|
||||||
<b>LICENSE</b>
|
<b>LICENSE</b>
|
||||||
The Secure Mailer license must be distributed with this
|
The Secure Mailer license must be distributed with this
|
||||||
software.
|
software.
|
||||||
|
|
||||||
<b>AUTHOR(S)</b>
|
<b>AUTHOR(S)</b>
|
||||||
|
@@ -523,6 +523,11 @@ SMTP(8) SMTP(8)
|
|||||||
Coventry,
|
Coventry,
|
||||||
CV1 4LY, United Kingdom.
|
CV1 4LY, United Kingdom.
|
||||||
|
|
||||||
|
SASL support originally by:
|
||||||
|
Till Franke
|
||||||
|
SuSE Rhein/Main AG
|
||||||
|
65760 Eschborn, Germany
|
||||||
|
|
||||||
Connection caching in cooperation with:
|
Connection caching in cooperation with:
|
||||||
Victor Duchovni
|
Victor Duchovni
|
||||||
Morgan Stanley
|
Morgan Stanley
|
||||||
|
@@ -962,6 +962,11 @@ SMTPD(8) SMTPD(8)
|
|||||||
P.O. Box 704
|
P.O. Box 704
|
||||||
Yorktown Heights, NY 10598, USA
|
Yorktown Heights, NY 10598, USA
|
||||||
|
|
||||||
|
SASL support originally by:
|
||||||
|
Till Franke
|
||||||
|
SuSE Rhein/Main AG
|
||||||
|
65760 Eschborn, Germany
|
||||||
|
|
||||||
TLS support originally by:
|
TLS support originally by:
|
||||||
Lutz Jaenicke
|
Lutz Jaenicke
|
||||||
BTU Cottbus
|
BTU Cottbus
|
||||||
|
@@ -49,6 +49,11 @@ Do not announce ENHANCEDSTATUSCODES support.
|
|||||||
.IP "\fB-f \fIcommand,command,...\fR"
|
.IP "\fB-f \fIcommand,command,...\fR"
|
||||||
Reject the specified commands with a hard (5xx) error code.
|
Reject the specified commands with a hard (5xx) error code.
|
||||||
This option implies \fB-p\fR.
|
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
|
.IP \fB-F\fR
|
||||||
Disable XFORWARD support.
|
Disable XFORWARD support.
|
||||||
.IP "\fB-h\fI hostname\fR"
|
.IP "\fB-h\fI hostname\fR"
|
||||||
@@ -66,15 +71,26 @@ a CISCO PIX system. Implies \fB-e\fR.
|
|||||||
.IP "\fB-q \fIcommand,command,...\fR"
|
.IP "\fB-q \fIcommand,command,...\fR"
|
||||||
Disconnect (without replying) after receiving one of the
|
Disconnect (without replying) after receiving one of the
|
||||||
specified commands.
|
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"
|
.IP "\fB-r \fIcommand,command,...\fR"
|
||||||
Reject the specified commands with a soft (4xx) error code.
|
Reject the specified commands with a soft (4xx) error code.
|
||||||
This option implies \fB-p\fR.
|
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"
|
.IP "\fB-s \fIcommand,command,...\fR"
|
||||||
Log the named commands to syslogd.
|
Log the named commands to syslogd.
|
||||||
Examples of commands that can be logged are HELO, EHLO, LHLO, MAIL,
|
.sp
|
||||||
RCPT, VRFY, RSET, NOOP, and QUIT. Separate command names by white
|
Examples of commands are HELO, EHLO, LHLO, MAIL, RCPT, VRFY,
|
||||||
space or commas, and use quotes to protect white space from the
|
DATA, ., RSET, NOOP, and QUIT. Separate command names by
|
||||||
shell. Command names are case-insensitive.
|
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)"
|
.IP "\fB-t \fItimeout\fR (default: 100)"
|
||||||
Limit the time for receiving a command or sending a response.
|
Limit the time for receiving a command or sending a response.
|
||||||
The time limit is specified in seconds.
|
The time limit is specified in seconds.
|
||||||
|
@@ -3437,7 +3437,7 @@ The default time unit is s (seconds).
|
|||||||
.SH smtp_mx_address_limit (default: 5)
|
.SH smtp_mx_address_limit (default: 5)
|
||||||
The maximal number of MX (mail exchanger) IP addresses that can
|
The maximal number of MX (mail exchanger) IP addresses that can
|
||||||
result from mail exchanger lookups, or zero (no limit). Prior to
|
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
|
.PP
|
||||||
This feature is available in Postfix 2.1 and later.
|
This feature is available in Postfix 2.1 and later.
|
||||||
.SH smtp_mx_session_limit (default: 2)
|
.SH smtp_mx_session_limit (default: 2)
|
||||||
|
@@ -259,11 +259,16 @@ IBM T.J. Watson Research
|
|||||||
P.O. Box 704
|
P.O. Box 704
|
||||||
Yorktown Heights, NY 10598, USA
|
Yorktown Heights, NY 10598, USA
|
||||||
|
|
||||||
Alterations for LMTP by:
|
Modifications for LMTP by:
|
||||||
Philip A. Prindeville
|
Philip A. Prindeville
|
||||||
Mirapoint, Inc.
|
Mirapoint, Inc.
|
||||||
USA.
|
USA.
|
||||||
|
|
||||||
|
SASL support originally by:
|
||||||
|
Till Franke
|
||||||
|
SuSE Rhein/Main AG
|
||||||
|
65760 Eschborn, Germany
|
||||||
|
|
||||||
Additional work on LMTP by:
|
Additional work on LMTP by:
|
||||||
Amos Gouaux
|
Amos Gouaux
|
||||||
University of Texas at Dallas
|
University of Texas at Dallas
|
||||||
|
@@ -429,6 +429,11 @@ Canal Basin,
|
|||||||
Coventry,
|
Coventry,
|
||||||
CV1 4LY, United Kingdom.
|
CV1 4LY, United Kingdom.
|
||||||
|
|
||||||
|
SASL support originally by:
|
||||||
|
Till Franke
|
||||||
|
SuSE Rhein/Main AG
|
||||||
|
65760 Eschborn, Germany
|
||||||
|
|
||||||
Connection caching in cooperation with:
|
Connection caching in cooperation with:
|
||||||
Victor Duchovni
|
Victor Duchovni
|
||||||
Morgan Stanley
|
Morgan Stanley
|
||||||
|
@@ -779,6 +779,11 @@ IBM T.J. Watson Research
|
|||||||
P.O. Box 704
|
P.O. Box 704
|
||||||
Yorktown Heights, NY 10598, USA
|
Yorktown Heights, NY 10598, USA
|
||||||
|
|
||||||
|
SASL support originally by:
|
||||||
|
Till Franke
|
||||||
|
SuSE Rhein/Main AG
|
||||||
|
65760 Eschborn, Germany
|
||||||
|
|
||||||
TLS support originally by:
|
TLS support originally by:
|
||||||
Lutz Jaenicke
|
Lutz Jaenicke
|
||||||
BTU Cottbus
|
BTU Cottbus
|
||||||
|
@@ -3829,7 +3829,7 @@ The default time unit is s (seconds).
|
|||||||
<p>
|
<p>
|
||||||
The maximal number of MX (mail exchanger) IP addresses that can
|
The maximal number of MX (mail exchanger) IP addresses that can
|
||||||
result from mail exchanger lookups, or zero (no limit). Prior to
|
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>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
|
@@ -315,6 +315,11 @@ static const char *cleanup_act(CLEANUP_STATE *state, char *context,
|
|||||||
if (state->reason == 0) {
|
if (state->reason == 0) {
|
||||||
if (*optional_text) {
|
if (*optional_text) {
|
||||||
state->reason = dsn_prepend("5.7.1", 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 {
|
} else {
|
||||||
detail = cleanup_stat_detail(CLEANUP_STAT_CONT);
|
detail = cleanup_stat_detail(CLEANUP_STAT_CONT);
|
||||||
state->reason = dsn_prepend(detail->dsn, detail->text);
|
state->reason = dsn_prepend(detail->dsn, detail->text);
|
||||||
|
@@ -20,7 +20,7 @@
|
|||||||
* Patches change both the patchlevel and the release date. Snapshots have no
|
* Patches change both the patchlevel and the release date. Snapshots have no
|
||||||
* patchlevel; they change the release date only.
|
* patchlevel; they change the release date only.
|
||||||
*/
|
*/
|
||||||
#define MAIL_RELEASE_DATE "20050623"
|
#define MAIL_RELEASE_DATE "20050627"
|
||||||
#define MAIL_VERSION_NUMBER "2.3"
|
#define MAIL_VERSION_NUMBER "2.3"
|
||||||
|
|
||||||
#define VAR_MAIL_VERSION "mail_version"
|
#define VAR_MAIL_VERSION "mail_version"
|
||||||
|
@@ -225,11 +225,16 @@
|
|||||||
/* P.O. Box 704
|
/* P.O. Box 704
|
||||||
/* Yorktown Heights, NY 10598, USA
|
/* Yorktown Heights, NY 10598, USA
|
||||||
/*
|
/*
|
||||||
/* Alterations for LMTP by:
|
/* Modifications for LMTP by:
|
||||||
/* Philip A. Prindeville
|
/* Philip A. Prindeville
|
||||||
/* Mirapoint, Inc.
|
/* Mirapoint, Inc.
|
||||||
/* USA.
|
/* USA.
|
||||||
/*
|
/*
|
||||||
|
/* SASL support originally by:
|
||||||
|
/* Till Franke
|
||||||
|
/* SuSE Rhein/Main AG
|
||||||
|
/* 65760 Eschborn, Germany
|
||||||
|
/*
|
||||||
/* Additional work on LMTP by:
|
/* Additional work on LMTP by:
|
||||||
/* Amos Gouaux
|
/* Amos Gouaux
|
||||||
/* University of Texas at Dallas
|
/* University of Texas at Dallas
|
||||||
|
@@ -389,6 +389,11 @@
|
|||||||
/* Coventry,
|
/* Coventry,
|
||||||
/* CV1 4LY, United Kingdom.
|
/* CV1 4LY, United Kingdom.
|
||||||
/*
|
/*
|
||||||
|
/* SASL support originally by:
|
||||||
|
/* Till Franke
|
||||||
|
/* SuSE Rhein/Main AG
|
||||||
|
/* 65760 Eschborn, Germany
|
||||||
|
/*
|
||||||
/* Connection caching in cooperation with:
|
/* Connection caching in cooperation with:
|
||||||
/* Victor Duchovni
|
/* Victor Duchovni
|
||||||
/* Morgan Stanley
|
/* Morgan Stanley
|
||||||
|
@@ -355,7 +355,7 @@ int smtp_session_passivate(SMTP_SESSION *session, VSTRING *dest_prop,
|
|||||||
/*
|
/*
|
||||||
* Append the passivated SASL attributes.
|
* Append the passivated SASL attributes.
|
||||||
*/
|
*/
|
||||||
#ifdef USE_SASL
|
#ifdef notdef
|
||||||
if (smtp_sasl_enable)
|
if (smtp_sasl_enable)
|
||||||
smtp_sasl_passivate(endp_prop, session);
|
smtp_sasl_passivate(endp_prop, session);
|
||||||
#endif
|
#endif
|
||||||
@@ -460,7 +460,7 @@ SMTP_SESSION *smtp_session_activate(int fd, VSTRING *dest_prop,
|
|||||||
/*
|
/*
|
||||||
* Re-activate the SASL attributes.
|
* Re-activate the SASL attributes.
|
||||||
*/
|
*/
|
||||||
#ifdef USE_SASL
|
#ifdef notdef
|
||||||
if (smtp_sasl_enable && smtp_sasl_activate(session, endp_props) < 0) {
|
if (smtp_sasl_enable && smtp_sasl_activate(session, endp_props) < 0) {
|
||||||
vstream_fdclose(session->stream);
|
vstream_fdclose(session->stream);
|
||||||
session->stream = 0;
|
session->stream = 0;
|
||||||
|
@@ -721,6 +721,11 @@
|
|||||||
/* P.O. Box 704
|
/* P.O. Box 704
|
||||||
/* Yorktown Heights, NY 10598, USA
|
/* Yorktown Heights, NY 10598, USA
|
||||||
/*
|
/*
|
||||||
|
/* SASL support originally by:
|
||||||
|
/* Till Franke
|
||||||
|
/* SuSE Rhein/Main AG
|
||||||
|
/* 65760 Eschborn, Germany
|
||||||
|
/*
|
||||||
/* TLS support originally by:
|
/* TLS support originally by:
|
||||||
/* Lutz Jaenicke
|
/* Lutz Jaenicke
|
||||||
/* BTU Cottbus
|
/* 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
|
* Report trouble. XXX Should log a warning only if we are going to
|
||||||
* that attackers can't flood our logfiles.
|
* 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
|
if (naddr > 1
|
||||||
|| (strict_rfc821 && (non_addr || *STR(arg->vstrval) != '<'))) {
|
|| (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
|
* 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
|
* command in which invalid character codes have been employed, and for
|
||||||
* which there are no other reasons for rejection, MUST reject that
|
* which there are no other reasons for rejection, MUST reject that
|
||||||
* command with a 501 response. So much for the principle of "be liberal
|
* command with a 501 response. Postfix attempts to be 8-bit clean.
|
||||||
* in what you accept, be strict in what you send".
|
|
||||||
*/
|
*/
|
||||||
if (var_helo_required && state->helo_name == 0) {
|
if (var_helo_required && state->helo_name == 0) {
|
||||||
state->error_mask |= MAIL_ERROR_POLICY;
|
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");
|
smtpd_chat_reply(state, "501 5.1.3 Bad recipient address syntax");
|
||||||
return (-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
|
/* Not: state->addr_buf */
|
||||||
if (SMTPD_STAND_ALONE(state) == 0
|
if (SMTPD_STAND_ALONE(state) == 0
|
||||||
&& (err = smtpd_check_rcpt(state, argv[1].strval)) != 0) {
|
&& (err = smtpd_check_rcpt(state, argv[1].strval)) != 0) {
|
||||||
smtpd_chat_reply(state, "%s", err);
|
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
|
* When the "." and quit replies are pipelined, make sure they are
|
||||||
* flushed now, to avoid repeated mail deliveries in case of a crash in
|
* flushed now, to avoid repeated mail deliveries in case of a crash in
|
||||||
* the "clean up before disconnect" code.
|
* 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);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2945,7 +2957,7 @@ static void chat_reset(SMTPD_STATE *state, int threshold)
|
|||||||
|
|
||||||
#ifdef USE_TLS
|
#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)
|
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.
|
* verification unless TLS is required.
|
||||||
*/
|
*/
|
||||||
state->tls_context =
|
state->tls_context =
|
||||||
tls_server_start(smtpd_tls_ctx, state->client,
|
tls_server_start(smtpd_tls_ctx, state->client,
|
||||||
var_smtpd_starttls_tmout,
|
var_smtpd_starttls_tmout,
|
||||||
state->name, state->addr, &(state->tls_info),
|
state->name, state->addr, &(state->tls_info),
|
||||||
(var_smtpd_tls_req_ccert && state->tls_enforce_tls));
|
(var_smtpd_tls_req_ccert && state->tls_enforce_tls));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* When the TLS handshake fails, the conversation is in an unknown state.
|
* 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?.
|
* recipient checks, address mapping, header_body_checks?.
|
||||||
*/
|
*/
|
||||||
smtpd_input_transp_mask =
|
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
|
* Sanity checks. The queue_minfree value should be at least as large as
|
||||||
* (process_limit * message_size_limit) but that is unpractical, so we
|
* (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
|
if (var_queue_minfree > 0
|
||||||
&& var_message_limit > 0
|
&& var_message_limit > 0
|
||||||
|
@@ -43,6 +43,11 @@
|
|||||||
/* .IP "\fB-f \fIcommand,command,...\fR"
|
/* .IP "\fB-f \fIcommand,command,...\fR"
|
||||||
/* Reject the specified commands with a hard (5xx) error code.
|
/* Reject the specified commands with a hard (5xx) error code.
|
||||||
/* This option implies \fB-p\fR.
|
/* 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
|
/* .IP \fB-F\fR
|
||||||
/* Disable XFORWARD support.
|
/* Disable XFORWARD support.
|
||||||
/* .IP "\fB-h\fI hostname\fR"
|
/* .IP "\fB-h\fI hostname\fR"
|
||||||
@@ -60,15 +65,26 @@
|
|||||||
/* .IP "\fB-q \fIcommand,command,...\fR"
|
/* .IP "\fB-q \fIcommand,command,...\fR"
|
||||||
/* Disconnect (without replying) after receiving one of the
|
/* Disconnect (without replying) after receiving one of the
|
||||||
/* specified commands.
|
/* 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"
|
/* .IP "\fB-r \fIcommand,command,...\fR"
|
||||||
/* Reject the specified commands with a soft (4xx) error code.
|
/* Reject the specified commands with a soft (4xx) error code.
|
||||||
/* This option implies \fB-p\fR.
|
/* 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"
|
/* .IP "\fB-s \fIcommand,command,...\fR"
|
||||||
/* Log the named commands to syslogd.
|
/* Log the named commands to syslogd.
|
||||||
/* Examples of commands that can be logged are HELO, EHLO, LHLO, MAIL,
|
/* .sp
|
||||||
/* RCPT, VRFY, RSET, NOOP, and QUIT. Separate command names by white
|
/* Examples of commands are HELO, EHLO, LHLO, MAIL, RCPT, VRFY,
|
||||||
/* space or commas, and use quotes to protect white space from the
|
/* DATA, ., RSET, NOOP, and QUIT. Separate command names by
|
||||||
/* shell. Command names are case-insensitive.
|
/* 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)"
|
/* .IP "\fB-t \fItimeout\fR (default: 100)"
|
||||||
/* Limit the time for receiving a command or sending a response.
|
/* Limit the time for receiving a command or sending a response.
|
||||||
/* The time limit is specified in seconds.
|
/* The time limit is specified in seconds.
|
||||||
@@ -141,6 +157,7 @@ typedef struct SINK_STATE {
|
|||||||
int data_state;
|
int data_state;
|
||||||
int (*read_fn) (struct SINK_STATE *);
|
int (*read_fn) (struct SINK_STATE *);
|
||||||
int rcpts;
|
int rcpts;
|
||||||
|
char *push_back_ptr;
|
||||||
} SINK_STATE;
|
} SINK_STATE;
|
||||||
|
|
||||||
#define ST_ANY 0
|
#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 4
|
||||||
#define ST_CR_LF_DOT_CR_LF 5
|
#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_tmout = 100;
|
||||||
static int var_max_line_length = 2048;
|
static int var_max_line_length = 2048;
|
||||||
static char *var_myhostname;
|
static char *var_myhostname;
|
||||||
@@ -170,6 +191,25 @@ static int disable_xclient;
|
|||||||
static int disable_xforward;
|
static int disable_xforward;
|
||||||
static int disable_enh_status;
|
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 */
|
/* ehlo_response - respond to EHLO command */
|
||||||
|
|
||||||
static void ehlo_response(SINK_STATE *state)
|
static void ehlo_response(SINK_STATE *state)
|
||||||
@@ -244,6 +284,32 @@ static void data_event(int unused_event, char *context)
|
|||||||
data_response(state);
|
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 */
|
/* dot_response - response to . command */
|
||||||
|
|
||||||
static void dot_response(SINK_STATE *state)
|
static void dot_response(SINK_STATE *state)
|
||||||
@@ -312,9 +378,7 @@ static int data_read(SINK_STATE *state)
|
|||||||
else
|
else
|
||||||
state->data_state = ST_ANY;
|
state->data_state = ST_ANY;
|
||||||
if (state->data_state == ST_CR_LF_DOT_CR_LF) {
|
if (state->data_state == ST_CR_LF_DOT_CR_LF) {
|
||||||
if (msg_verbose)
|
PUSH_BACK_SET(state, ".\r\n");
|
||||||
msg_info(".");
|
|
||||||
dot_response(state);
|
|
||||||
state->read_fn = command_read;
|
state->read_fn = command_read;
|
||||||
state->data_state = ST_ANY;
|
state->data_state = ST_ANY;
|
||||||
break;
|
break;
|
||||||
@@ -337,6 +401,8 @@ static int data_read(SINK_STATE *state)
|
|||||||
typedef struct SINK_COMMAND {
|
typedef struct SINK_COMMAND {
|
||||||
char *name;
|
char *name;
|
||||||
void (*response) (SINK_STATE *);
|
void (*response) (SINK_STATE *);
|
||||||
|
void (*hard_response) (SINK_STATE *);
|
||||||
|
void (*soft_response) (SINK_STATE *);
|
||||||
int flags;
|
int flags;
|
||||||
} SINK_COMMAND;
|
} SINK_COMMAND;
|
||||||
|
|
||||||
@@ -347,19 +413,20 @@ typedef struct SINK_COMMAND {
|
|||||||
#define FLAG_DISCONNECT (1<<4) /* disconnect */
|
#define FLAG_DISCONNECT (1<<4) /* disconnect */
|
||||||
|
|
||||||
static SINK_COMMAND command_table[] = {
|
static SINK_COMMAND command_table[] = {
|
||||||
"helo", helo_response, 0,
|
"helo", helo_response, hard_err_resp, soft_err_resp, 0,
|
||||||
"ehlo", ehlo_response, 0,
|
"ehlo", ehlo_response, hard_err_resp, soft_err_resp, 0,
|
||||||
"lhlo", ehlo_response, 0,
|
"lhlo", ehlo_response, hard_err_resp, soft_err_resp, 0,
|
||||||
"xclient", ok_response, FLAG_ENABLE,
|
"xclient", ok_response, hard_err_resp, soft_err_resp, FLAG_ENABLE,
|
||||||
"xforward", ok_response, FLAG_ENABLE,
|
"xforward", ok_response, hard_err_resp, soft_err_resp, FLAG_ENABLE,
|
||||||
"auth", ok_response, FLAG_ENABLE,
|
"auth", ok_response, hard_err_resp, soft_err_resp, FLAG_ENABLE,
|
||||||
"mail", mail_response, FLAG_ENABLE,
|
"mail", mail_response, hard_err_resp, soft_err_resp, FLAG_ENABLE,
|
||||||
"rcpt", rcpt_response, FLAG_ENABLE,
|
"rcpt", rcpt_response, hard_err_resp, soft_err_resp, FLAG_ENABLE,
|
||||||
"data", data_response, FLAG_ENABLE,
|
"data", data_response, hard_err_resp, soft_err_resp, FLAG_ENABLE,
|
||||||
"rset", ok_response, FLAG_ENABLE,
|
".", dot_response, dot_resp_hard, dot_resp_soft, FLAG_ENABLE,
|
||||||
"noop", ok_response, FLAG_ENABLE,
|
"rset", ok_response, hard_err_resp, soft_err_resp, FLAG_ENABLE,
|
||||||
"vrfy", ok_response, FLAG_ENABLE,
|
"noop", ok_response, hard_err_resp, soft_err_resp, FLAG_ENABLE,
|
||||||
"quit", quit_response, 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,
|
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
|
* 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.
|
* 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 (;;) {
|
for (;;) {
|
||||||
if ((ch = VSTREAM_GETC(state->stream)) == VSTREAM_EOF)
|
if ((ch = NEXT_CHAR(state)) == VSTREAM_EOF)
|
||||||
return (-1);
|
return (-1);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -467,7 +537,7 @@ static int command_read(SINK_STATE *state)
|
|||||||
* instead of peek_fd() (which uses ioctl FIONREAD). Workaround added
|
* instead of peek_fd() (which uses ioctl FIONREAD). Workaround added
|
||||||
* 20020604.
|
* 20020604.
|
||||||
*/
|
*/
|
||||||
if (vstream_peek(state->stream) <= 0
|
if (PUSH_BACK_PEEK(state) == 0 && vstream_peek(state->stream) <= 0
|
||||||
&& readable(vstream_fileno(state->stream)) <= 0)
|
&& readable(vstream_fileno(state->stream)) <= 0)
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
@@ -501,21 +571,19 @@ static int command_read(SINK_STATE *state)
|
|||||||
smtp_flush(state->stream);
|
smtp_flush(state->stream);
|
||||||
return (0);
|
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. */
|
/* We use raw syslog. Sanitize data content and length. */
|
||||||
if (cmdp->flags & FLAG_SYSLOG)
|
if (cmdp->flags & FLAG_SYSLOG)
|
||||||
syslog(LOG_INFO, "%s %.100s", command, printable(ptr, '?'));
|
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) {
|
if (cmdp->response == data_response && fixed_delay > 0) {
|
||||||
event_request_timer(data_event, (char *) state, fixed_delay);
|
event_request_timer(data_event, (char *) state, fixed_delay);
|
||||||
} else {
|
} else {
|
||||||
@@ -582,7 +650,7 @@ static void read_event(int unused_event, char *context)
|
|||||||
return;
|
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
|
* 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->buffer = vstring_alloc(1024);
|
||||||
state->read_fn = command_read;
|
state->read_fn = command_read;
|
||||||
state->data_state = ST_ANY;
|
state->data_state = ST_ANY;
|
||||||
|
PUSH_BACK_SET(state, "");
|
||||||
smtp_timeout_setup(state->stream, var_tmout);
|
smtp_timeout_setup(state->stream, var_tmout);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@@ -56,7 +56,8 @@
|
|||||||
/* length, and an attribute value pointer.
|
/* length, and an attribute value pointer.
|
||||||
/* .IP "ATTR_TYPE_FUNC (ATTR_PRINT_SLAVE_FN, void *)"
|
/* .IP "ATTR_TYPE_FUNC (ATTR_PRINT_SLAVE_FN, void *)"
|
||||||
/* This argument is followed by a function pointer and generic data
|
/* 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_HASH (HTABLE *)"
|
||||||
/* .IP "ATTR_TYPE_NAMEVAL (NVTABLE *)"
|
/* .IP "ATTR_TYPE_NAMEVAL (NVTABLE *)"
|
||||||
/* The content of the table is sent as a sequence of string-valued
|
/* The content of the table is sent as a sequence of string-valued
|
||||||
|
@@ -51,6 +51,10 @@
|
|||||||
/* .IP "ATTR_TYPE_STR (char *, char *)"
|
/* .IP "ATTR_TYPE_STR (char *, char *)"
|
||||||
/* This argument is followed by an attribute name and a null-terminated
|
/* This argument is followed by an attribute name and a null-terminated
|
||||||
/* string.
|
/* 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_HASH (HTABLE *)"
|
||||||
/* .IP "ATTR_TYPE_NAMEVAL (NVTABLE *)"
|
/* .IP "ATTR_TYPE_NAMEVAL (NVTABLE *)"
|
||||||
/* The content of the table is sent as a sequence of string-valued
|
/* 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_info_list;
|
||||||
HTABLE_INFO **ht;
|
HTABLE_INFO **ht;
|
||||||
int len_val;
|
int len_val;
|
||||||
|
ATTR_PRINT_SLAVE_FN print_fn;
|
||||||
|
void *print_arg;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Sanity check.
|
* Sanity check.
|
||||||
@@ -196,6 +202,11 @@ int attr_vprint64(VSTREAM *fp, int flags, va_list ap)
|
|||||||
if (msg_verbose)
|
if (msg_verbose)
|
||||||
msg_info("send attr %s = [data %d bytes]", attr_name, len_val);
|
msg_info("send attr %s = [data %d bytes]", attr_name, len_val);
|
||||||
break;
|
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:
|
case ATTR_TYPE_HASH:
|
||||||
ht_info_list = htable_list(va_arg(ap, HTABLE *));
|
ht_info_list = htable_list(va_arg(ap, HTABLE *));
|
||||||
for (ht = ht_info_list; *ht; ht++) {
|
for (ht = ht_info_list; *ht; ht++) {
|
||||||
|
@@ -54,6 +54,10 @@
|
|||||||
/* .IP "ATTR_TYPE_DATA (char *, int, char *)"
|
/* .IP "ATTR_TYPE_DATA (char *, int, char *)"
|
||||||
/* This argument is followed by an attribute name, an attribute value
|
/* This argument is followed by an attribute name, an attribute value
|
||||||
/* length, and a pointer to 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_HASH (HTABLE *)"
|
||||||
/* .IP "ATTR_TYPE_NAMEVAL (NVTABLE *)"
|
/* .IP "ATTR_TYPE_NAMEVAL (NVTABLE *)"
|
||||||
/* The content of the table is sent as a sequence of string-valued
|
/* 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;
|
HTABLE_INFO **ht;
|
||||||
static VSTRING *base64_buf;
|
static VSTRING *base64_buf;
|
||||||
int len_val;
|
int len_val;
|
||||||
|
ATTR_PRINT_SLAVE_FN print_fn;
|
||||||
|
void *print_arg;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Sanity check.
|
* Sanity check.
|
||||||
@@ -157,6 +163,11 @@ int attr_vprint_plain(VSTREAM *fp, int flags, va_list ap)
|
|||||||
if (msg_verbose)
|
if (msg_verbose)
|
||||||
msg_info("send attr %s = [data %d bytes]", attr_name, len_val);
|
msg_info("send attr %s = [data %d bytes]", attr_name, len_val);
|
||||||
break;
|
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:
|
case ATTR_TYPE_HASH:
|
||||||
ht_info_list = htable_list(va_arg(ap, HTABLE *));
|
ht_info_list = htable_list(va_arg(ap, HTABLE *));
|
||||||
for (ht = ht_info_list; *ht; ht++) {
|
for (ht = ht_info_list; *ht; ht++) {
|
||||||
|
@@ -95,7 +95,8 @@
|
|||||||
/* This argument is followed by an attribute name and a VSTRING pointer.
|
/* This argument is followed by an attribute name and a VSTRING pointer.
|
||||||
/* .IP "ATTR_TYPE_FUNC (ATTR_SCAN_SLAVE_FN, void *)"
|
/* .IP "ATTR_TYPE_FUNC (ATTR_SCAN_SLAVE_FN, void *)"
|
||||||
/* This argument is followed by a function pointer and a generic data
|
/* 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_HASH (HTABLE *)"
|
||||||
/* .IP "ATTR_TYPE_NAMEVAL (NVTABLE *)"
|
/* .IP "ATTR_TYPE_NAMEVAL (NVTABLE *)"
|
||||||
/* All further input attributes are processed as string attributes.
|
/* All further input attributes are processed as string attributes.
|
||||||
|
@@ -47,7 +47,7 @@
|
|||||||
/* characters. The formatting rules aim to make implementations in PERL
|
/* characters. The formatting rules aim to make implementations in PERL
|
||||||
/* and other languages easy.
|
/* 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
|
/* the attr_scan64() argument list. The input stream may contain additional
|
||||||
/* attributes at any point in the input stream, including additional
|
/* attributes at any point in the input stream, including additional
|
||||||
/* instances of requested attributes.
|
/* instances of requested attributes.
|
||||||
@@ -95,6 +95,10 @@
|
|||||||
/* This argument is followed by an attribute name and a VSTRING pointer.
|
/* This argument is followed by an attribute name and a VSTRING pointer.
|
||||||
/* .IP "ATTR_TYPE_DATA (char *, VSTRING *)"
|
/* .IP "ATTR_TYPE_DATA (char *, VSTRING *)"
|
||||||
/* This argument is followed by an attribute name and a VSTRING pointer.
|
/* 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_HASH (HTABLE *)"
|
||||||
/* .IP "ATTR_TYPE_NAMEVAL (NVTABLE *)"
|
/* .IP "ATTR_TYPE_NAMEVAL (NVTABLE *)"
|
||||||
/* All further input attributes are processed as string attributes.
|
/* 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 int attr_scan64_string(VSTREAM *fp, VSTRING *plain_buf, const char *context)
|
||||||
{
|
{
|
||||||
static VSTRING *base64_buf = 0;
|
static VSTRING *base64_buf = 0;
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
extern int var_line_limit; /* XXX */
|
extern int var_line_limit; /* XXX */
|
||||||
int limit = var_line_limit * 4;
|
int limit = var_line_limit * 4;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
int ch;
|
int ch;
|
||||||
|
|
||||||
@@ -254,6 +260,8 @@ int attr_vscan64(VSTREAM *fp, int flags, va_list ap)
|
|||||||
HTABLE *hash_table;
|
HTABLE *hash_table;
|
||||||
int ch;
|
int ch;
|
||||||
int conversions;
|
int conversions;
|
||||||
|
ATTR_SCAN_SLAVE_FN scan_fn;
|
||||||
|
void *scan_arg;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Sanity check.
|
* Sanity check.
|
||||||
@@ -295,7 +303,7 @@ int attr_vscan64(VSTREAM *fp, int flags, va_list ap)
|
|||||||
if (va_arg(ap, int) !=ATTR_TYPE_END)
|
if (va_arg(ap, int) !=ATTR_TYPE_END)
|
||||||
msg_panic("%s: ATTR_TYPE_HASH not followed by ATTR_TYPE_END",
|
msg_panic("%s: ATTR_TYPE_HASH not followed by ATTR_TYPE_END",
|
||||||
myname);
|
myname);
|
||||||
} else {
|
} else if (wanted_type != ATTR_TYPE_FUNC) {
|
||||||
wanted_name = va_arg(ap, char *);
|
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.
|
* 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.
|
* 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);
|
return (-1);
|
||||||
}
|
}
|
||||||
break;
|
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:
|
case ATTR_TYPE_HASH:
|
||||||
if (ch != ':') {
|
if (ch != ':') {
|
||||||
msg_warn("missing value for string attribute %s from %s",
|
msg_warn("missing value for string attribute %s from %s",
|
||||||
|
@@ -45,7 +45,7 @@
|
|||||||
/* characters. The formatting rules aim to make implementations in PERL
|
/* characters. The formatting rules aim to make implementations in PERL
|
||||||
/* and other languages easy.
|
/* 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
|
/* with the attr_scan_plain() argument list. The input stream may
|
||||||
/* contain additional attributes at any point in the input stream,
|
/* contain additional attributes at any point in the input stream,
|
||||||
/* including additional instances of requested attributes.
|
/* including additional instances of requested attributes.
|
||||||
@@ -93,6 +93,10 @@
|
|||||||
/* This argument is followed by an attribute name and a VSTRING pointer.
|
/* This argument is followed by an attribute name and a VSTRING pointer.
|
||||||
/* .IP "ATTR_TYPE_DATA (char *, VSTRING *)"
|
/* .IP "ATTR_TYPE_DATA (char *, VSTRING *)"
|
||||||
/* This argument is followed by an attribute name and a VSTRING pointer.
|
/* 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_HASH (HTABLE *)"
|
||||||
/* .IP "ATTR_TYPE_NAMEVAL (NVTABLE *)"
|
/* .IP "ATTR_TYPE_NAMEVAL (NVTABLE *)"
|
||||||
/* All further input attributes are processed as string attributes.
|
/* 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
|
#if 0
|
||||||
extern int var_line_limit; /* XXX */
|
extern int var_line_limit; /* XXX */
|
||||||
int limit = var_line_limit * 4;
|
int limit = var_line_limit * 4;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
int ch;
|
int ch;
|
||||||
|
|
||||||
@@ -268,6 +273,8 @@ int attr_vscan_plain(VSTREAM *fp, int flags, va_list ap)
|
|||||||
HTABLE *hash_table;
|
HTABLE *hash_table;
|
||||||
int ch;
|
int ch;
|
||||||
int conversions;
|
int conversions;
|
||||||
|
ATTR_SCAN_SLAVE_FN scan_fn;
|
||||||
|
void *scan_arg;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Sanity check.
|
* 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)
|
if (va_arg(ap, int) !=ATTR_TYPE_END)
|
||||||
msg_panic("%s: ATTR_TYPE_HASH not followed by ATTR_TYPE_END",
|
msg_panic("%s: ATTR_TYPE_HASH not followed by ATTR_TYPE_END",
|
||||||
myname);
|
myname);
|
||||||
} else {
|
} else if (wanted_type != ATTR_TYPE_FUNC) {
|
||||||
wanted_name = va_arg(ap, char *);
|
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.
|
* 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.
|
* 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
|
* Do the requested conversion.
|
||||||
* 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.
|
|
||||||
*/
|
*/
|
||||||
switch (wanted_type) {
|
switch (wanted_type) {
|
||||||
case ATTR_TYPE_NUM:
|
case ATTR_TYPE_NUM:
|
||||||
@@ -413,6 +415,12 @@ int attr_vscan_plain(VSTREAM *fp, int flags, va_list ap)
|
|||||||
"input attribute value")) < 0)
|
"input attribute value")) < 0)
|
||||||
return (-1);
|
return (-1);
|
||||||
break;
|
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:
|
case ATTR_TYPE_HASH:
|
||||||
if (ch != '=') {
|
if (ch != '=') {
|
||||||
msg_warn("missing value for string attribute %s from %s",
|
msg_warn("missing value for string attribute %s from %s",
|
||||||
|
Reference in New Issue
Block a user