mirror of
https://github.com/vdukhovni/postfix
synced 2025-08-30 05:38:06 +00:00
postfix-2.4-20060823
This commit is contained in:
parent
05d7ee7dca
commit
0e961e79a8
@ -12628,9 +12628,10 @@ Apologies for any names omitted.
|
|||||||
limit in the SMTP server didn't work for size limits close
|
limit in the SMTP server didn't work for size limits close
|
||||||
enough to INT_MAX. File: smtpd/smtpd.c.
|
enough to INT_MAX. File: smtpd/smtpd.c.
|
||||||
|
|
||||||
Bugfix: after an SMTP client was rejected with "smtpd_delay_reject
|
Bugfix (introduced Postfix 2.3): after an SMTP client was
|
||||||
= no", the SMTP server would panic as it generated spurious
|
rejected with "smtpd_delay_reject = no", the SMTP server
|
||||||
Milter requests for unrecognized commands. File: smtpd/smtpd.c.
|
would panic as it generated spurious Milter requests for
|
||||||
|
unrecognized commands. File: smtpd/smtpd.c.
|
||||||
|
|
||||||
20060727
|
20060727
|
||||||
|
|
||||||
@ -12640,8 +12641,9 @@ Apologies for any names omitted.
|
|||||||
|
|
||||||
20060805
|
20060805
|
||||||
|
|
||||||
Bugfix: #ifdef damage caused smtp_sasl_start() to be invoked
|
Bugfix (introduced Postfix 2.3): #ifdef damage caused
|
||||||
twice. Reported by C-J Lofstedt. File: smtp/smtp_sasl_proto.c.
|
smtp_sasl_start() to be invoked twice. Reported by C-J
|
||||||
|
Lofstedt. File: smtp/smtp_sasl_proto.c.
|
||||||
|
|
||||||
20060806
|
20060806
|
||||||
|
|
||||||
@ -12650,8 +12652,63 @@ Apologies for any names omitted.
|
|||||||
helpdesk service that solves all their email problems.
|
helpdesk service that solves all their email problems.
|
||||||
Credits to Jonathan Balester. File: bounce/bounce_templates.c.
|
Credits to Jonathan Balester. File: bounce/bounce_templates.c.
|
||||||
|
|
||||||
|
20060807
|
||||||
|
|
||||||
|
Bugfix (introduced Postfix 2.2): when upgrading from Postfix
|
||||||
|
< 2.2 with the third-party TLS patch, the post-install
|
||||||
|
upgrade procedure didn't put a "?" in the existing tlsmgr
|
||||||
|
entry, causing tlsmgr to repeatedly start and exit when TLS
|
||||||
|
support was not compiled in. File: conf/post-install.
|
||||||
|
|
||||||
|
20060812
|
||||||
|
|
||||||
|
Bugfix (introduced < Postfix alpha): safety mechanism in
|
||||||
|
mail_date() didn't work. Found in code review. File:
|
||||||
|
global/mail_date.c.
|
||||||
|
|
||||||
|
20060817
|
||||||
|
|
||||||
|
Test programs for host address->name and name->address
|
||||||
|
lookups to debug name service inconsistencies, typically
|
||||||
|
when the Postfix SMTP server claims that a hostname is
|
||||||
|
"unknown". Files: auxiliary/name-addr-test/*.
|
||||||
|
|
||||||
|
20060822
|
||||||
|
|
||||||
|
Added missing logging for "message to large" etc. Files:
|
||||||
|
smtpd/smtpd.c, cleanup/cleanup_milter.c.
|
||||||
|
|
||||||
|
20060823
|
||||||
|
|
||||||
|
Bugfix (introduced Postfix 2.2): vstream_fdclose() did not
|
||||||
|
flush unwritten output before disconnecting a stream from
|
||||||
|
its file descriptor. File: util/vstream.c.
|
||||||
|
|
||||||
|
Bugfix (introduced Postfix 2.2): segfault when vstream_fclose()
|
||||||
|
attempted to flush unwritten output, after vstream_fdclose()
|
||||||
|
disconnected the stream from its file descriptor. File:
|
||||||
|
util/vstream.c.
|
||||||
|
|
||||||
|
Feature: smtp-sink can capture mail to file, either as one
|
||||||
|
individual message per file, or as multiple messages per
|
||||||
|
file. After an initial implementation by Weidong Cui. File:
|
||||||
|
smtpstone/smtp-sink.c.
|
||||||
|
|
||||||
|
Bugfix (introduced < Postfix alpha): smtp-sink did not
|
||||||
|
correctly recognize DOT-CR-LF immediately after DATA. File:
|
||||||
|
smtpstone/smtp-sink.c.
|
||||||
|
|
||||||
|
Cleanup: smtp-sink now requires that MAIL FROM, RCPT TO and
|
||||||
|
DATA be send in the correct order. This simplified the
|
||||||
|
implementation of the capture to file feature. File:
|
||||||
|
smtpstone/smtp-sink.c.
|
||||||
|
|
||||||
Wish list:
|
Wish list:
|
||||||
|
|
||||||
|
Make null local-part handling configurable: either expand
|
||||||
|
into mailer-daemon (current bahavior) or disallow (strict
|
||||||
|
behavior, currently implemented only in the SMTP server).
|
||||||
|
|
||||||
The type of var_message_limit should be changed from int
|
The type of var_message_limit should be changed from int
|
||||||
to long or better, to take advantage of LP64 architectures.
|
to long or better, to take advantage of LP64 architectures.
|
||||||
This also requires checking all expressions in which
|
This also requires checking all expressions in which
|
||||||
|
@ -49,10 +49,11 @@ Alternatively, for the D.J.B. version of CDB:
|
|||||||
"AUXLIBS=$CDB/cdb.a $CDB/alloc.a $CDB/buffer.a $CDB/unix.a $CDB/byte.a"
|
"AUXLIBS=$CDB/cdb.a $CDB/alloc.a $CDB/buffer.a $CDB/unix.a $CDB/byte.a"
|
||||||
% make
|
% make
|
||||||
|
|
||||||
After postfix has been built with cdb support, you can use "cdb" tables
|
After Postfix has been built with cdb support, you can use "cdb" tables
|
||||||
wherever you can use read-only "hash", "btree" or "dbm" tables. However, the
|
wherever you can use read-only "hash", "btree" or "dbm" tables. However, the
|
||||||
"ppoossttmmaapp --ii" (incremental record insertion) and "ppoossttmmaapp --dd" (incremental
|
"ppoossttmmaapp --ii" (incremental record insertion) and "ppoossttmmaapp --dd" (incremental
|
||||||
record deletion) command-line options are not available. For the same reason
|
record deletion) command-line options are not available. For the same reason
|
||||||
the "cdb" map type cannot be used to store the persistent address verification
|
the "cdb" map type cannot be used to store the persistent address verification
|
||||||
cache for the verify(8) service.
|
cache for the verify(8) service, or to store TLS session information for the
|
||||||
|
tlsmgr(8) service.
|
||||||
|
|
||||||
|
@ -61,24 +61,23 @@ Needless to say, these commands are not available in earlier Postfix versions.
|
|||||||
|
|
||||||
BBuuiillddiinngg PPoossttffiixx wwiitthh DDoovveeccoott SSAASSLL ssuuppppoorrtt
|
BBuuiillddiinngg PPoossttffiixx wwiitthh DDoovveeccoott SSAASSLL ssuuppppoorrtt
|
||||||
|
|
||||||
Dovecot SASL support is available in Postfix 2.3 and later. The Dovecot source
|
Support for the Dovecot version 1 SASL protocol is available in Postfix 2.3 and
|
||||||
code is available via http://www.dovecot.org/. At the time of writing, only
|
later. At the time of writing, only server-side SASL support is available, so
|
||||||
server-side SASL support is available, so you can't use it to authenticate to
|
you can't use it to authenticate to your network provider's server. Dovecot
|
||||||
your network provider's server. Dovecot uses its own daemon process for
|
uses its own daemon process for authentication. This keeps the Postfix build
|
||||||
authentication. This keeps the Postfix build process simple, because there is
|
process simple, because there is no need to link extra libraries into Postfix.
|
||||||
no need to link extra libraries into Postfix.
|
|
||||||
|
|
||||||
To generate the necessary Makefiles, execute the following in the Postfix top-
|
To generate the necessary Makefiles, execute the following in the Postfix top-
|
||||||
level directory:
|
level directory:
|
||||||
|
|
||||||
% make makefiles CCARGS='-DUSE_SASL_AUTH -
|
% make makefiles CCARGS='-DUSE_SASL_AUTH -
|
||||||
DDEF_SASL_SERVER_TYPE=\"dovecot\"'
|
DDEF_SERVER_SASL_TYPE=\"dovecot\"'
|
||||||
|
|
||||||
After this, proceed with "make" as described in the INSTALL document.
|
After this, proceed with "make" as described in the INSTALL document.
|
||||||
|
|
||||||
Notes:
|
Notes:
|
||||||
|
|
||||||
* The "-DDEF_SASL_SERVER_TYPE" stuff is not necessary; it just makes Postfix
|
* The "-DDEF_SERVER_SASL_TYPE" stuff is not necessary; it just makes Postfix
|
||||||
configuration a little more convenient because you don't have to specify
|
configuration a little more convenient because you don't have to specify
|
||||||
the SASL plug-in type in the Postfix main.cf file.
|
the SASL plug-in type in the Postfix main.cf file.
|
||||||
|
|
||||||
|
64
postfix/auxiliary/name-addr-test/getaddrinfo.c
Normal file
64
postfix/auxiliary/name-addr-test/getaddrinfo.c
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
/*
|
||||||
|
* getaddrinfo(3) (name->address lookup) tester.
|
||||||
|
*
|
||||||
|
* Compile with:
|
||||||
|
*
|
||||||
|
* cc -o getaddrinfo getaddrinfo.c (BSD, Linux)
|
||||||
|
*
|
||||||
|
* cc -o getaddrinfo getaddrinfo.c -lsocket -lnsl (SunOS 5.x)
|
||||||
|
*
|
||||||
|
* Run as: getaddrinfo hostname
|
||||||
|
*
|
||||||
|
* Author: Wietse Venema, Eindhoven University of Technology, The Netherlands.
|
||||||
|
*
|
||||||
|
* Author: Wietse Venema, IBM T.J. Watson Research, USA.
|
||||||
|
*/
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#include <netdb.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
char hostbuf[NI_MAXHOST]; /* XXX */
|
||||||
|
struct addrinfo hints;
|
||||||
|
struct addrinfo *res0;
|
||||||
|
struct addrinfo *res;
|
||||||
|
const char *addr;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
#define NO_SERVICE ((char *) 0)
|
||||||
|
|
||||||
|
if (argc != 2) {
|
||||||
|
fprintf(stderr, "usage: %s hostname\n", argv[0]);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
memset((char *) &hints, 0, sizeof(hints));
|
||||||
|
hints.ai_family = PF_UNSPEC;
|
||||||
|
hints.ai_flags = AI_CANONNAME;
|
||||||
|
hints.ai_socktype = SOCK_STREAM;
|
||||||
|
if ((err = getaddrinfo(argv[1], NO_SERVICE, &hints, &res0)) != 0) {
|
||||||
|
fprintf(stderr, "host %s not found\n", argv[1]);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
printf("Hostname:\t%s\n", res0->ai_canonname);
|
||||||
|
printf("Addresses:\t");
|
||||||
|
for (res = res0; res != 0; res = res->ai_next) {
|
||||||
|
addr = (res->ai_family == AF_INET ?
|
||||||
|
(char *) &((struct sockaddr_in *) res->ai_addr)->sin_addr :
|
||||||
|
(char *) &((struct sockaddr_in6 *) res->ai_addr)->sin6_addr);
|
||||||
|
if (inet_ntop(res->ai_family, addr, hostbuf, sizeof(hostbuf)) == 0) {
|
||||||
|
perror("inet_ntop:");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
printf("%s ", hostbuf);
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
freeaddrinfo(res0);
|
||||||
|
exit(0);
|
||||||
|
}
|
46
postfix/auxiliary/name-addr-test/gethostbyaddr.c
Normal file
46
postfix/auxiliary/name-addr-test/gethostbyaddr.c
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
/*
|
||||||
|
* gethostbyaddr tester. compile with:
|
||||||
|
*
|
||||||
|
* cc -o gethostbyaddr gethostbyaddr.c (SunOS 4.x)
|
||||||
|
*
|
||||||
|
* cc -o gethostbyaddr gethostbyaddr.c -lnsl (SunOS 5.x)
|
||||||
|
*
|
||||||
|
* run as: gethostbyaddr address
|
||||||
|
*
|
||||||
|
* Author: Wietse Venema, Eindhoven University of Technology, The Netherlands.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#include <netdb.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
main(argc, argv)
|
||||||
|
int argc;
|
||||||
|
char **argv;
|
||||||
|
{
|
||||||
|
struct hostent *hp;
|
||||||
|
long addr;
|
||||||
|
|
||||||
|
if (argc != 2) {
|
||||||
|
fprintf(stderr, "usage: %s i.p.addres\n", argv[0]);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
addr = inet_addr(argv[1]);
|
||||||
|
if (hp = gethostbyaddr((char *) &addr, sizeof(addr), AF_INET)) {
|
||||||
|
printf("Hostname:\t%s\n", hp->h_name);
|
||||||
|
printf("Aliases:\t");
|
||||||
|
while (hp->h_aliases[0])
|
||||||
|
printf("%s ", *hp->h_aliases++);
|
||||||
|
printf("\n");
|
||||||
|
printf("Addresses:\t");
|
||||||
|
while (hp->h_addr_list[0])
|
||||||
|
printf("%s ", inet_ntoa(*(struct in_addr *) * hp->h_addr_list++));
|
||||||
|
printf("\n");
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
fprintf(stderr, "host %s not found\n", argv[1]);
|
||||||
|
exit(1);
|
||||||
|
}
|
44
postfix/auxiliary/name-addr-test/gethostbyname.c
Normal file
44
postfix/auxiliary/name-addr-test/gethostbyname.c
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
/*
|
||||||
|
* gethostbyname tester. compile with:
|
||||||
|
*
|
||||||
|
* cc -o gethostbyname gethostbyname.c (SunOS 4.x)
|
||||||
|
*
|
||||||
|
* cc -o gethostbyname gethostbyname.c -lnsl (SunOS 5.x)
|
||||||
|
*
|
||||||
|
* run as: gethostbyname hostname
|
||||||
|
*
|
||||||
|
* Author: Wietse Venema, Eindhoven University of Technology, The Netherlands.
|
||||||
|
*/
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#include <netdb.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
main(argc, argv)
|
||||||
|
int argc;
|
||||||
|
char **argv;
|
||||||
|
{
|
||||||
|
struct hostent *hp;
|
||||||
|
|
||||||
|
if (argc != 2) {
|
||||||
|
fprintf(stderr, "usage: %s hostname\n", argv[0]);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
if (hp = gethostbyname(argv[1])) {
|
||||||
|
printf("Hostname:\t%s\n", hp->h_name);
|
||||||
|
printf("Aliases:\t");
|
||||||
|
while (hp->h_aliases[0])
|
||||||
|
printf("%s ", *hp->h_aliases++);
|
||||||
|
printf("\n");
|
||||||
|
printf("Addresses:\t");
|
||||||
|
while (hp->h_addr_list[0])
|
||||||
|
printf("%s ", inet_ntoa(*(struct in_addr *) * hp->h_addr_list++));
|
||||||
|
printf("\n");
|
||||||
|
exit(0);
|
||||||
|
} else {
|
||||||
|
fprintf(stderr, "host %s not found\n", argv[1]);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
}
|
79
postfix/auxiliary/name-addr-test/getnameinfo.c
Normal file
79
postfix/auxiliary/name-addr-test/getnameinfo.c
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
/*
|
||||||
|
* getnameinfo(3) (address->name lookup) tester.
|
||||||
|
*
|
||||||
|
* Compile with:
|
||||||
|
*
|
||||||
|
* cc -o getnameinfo getnameinfo.c (BSD, Linux)
|
||||||
|
*
|
||||||
|
* cc -o getnameinfo getnameinfo.c -lsocket -lnsl (SunOS 5.x)
|
||||||
|
*
|
||||||
|
* Run as: getnameinfo address
|
||||||
|
*
|
||||||
|
* Author: Wietse Venema, Eindhoven University of Technology, The Netherlands.
|
||||||
|
*
|
||||||
|
* Author: Wietse Venema, IBM T.J. Watson Research, USA.
|
||||||
|
*/
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#include <netdb.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
char hostbuf[NI_MAXHOST]; /* XXX */
|
||||||
|
struct addrinfo hints;
|
||||||
|
struct addrinfo *res0;
|
||||||
|
struct addrinfo *res;
|
||||||
|
const char *host;
|
||||||
|
const char *addr;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
#define NO_SERVICE ((char *) 0)
|
||||||
|
|
||||||
|
if (argc != 2) {
|
||||||
|
fprintf(stderr, "usage: %s ipaddres\n", argv[0]);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Convert address to internal form.
|
||||||
|
*/
|
||||||
|
host = argv[1];
|
||||||
|
memset((char *) &hints, 0, sizeof(hints));
|
||||||
|
hints.ai_family = (strchr(host, ':') ? AF_INET6 : AF_INET);
|
||||||
|
hints.ai_socktype = SOCK_STREAM;
|
||||||
|
hints.ai_flags |= AI_NUMERICHOST;
|
||||||
|
if ((err = getaddrinfo(host, NO_SERVICE, &hints, &res0)) != 0) {
|
||||||
|
fprintf(stderr, "getaddrinfo %s: %s\n", host, gai_strerror(err));
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Convert host address to name.
|
||||||
|
*/
|
||||||
|
for (res = res0; res != 0; res = res->ai_next) {
|
||||||
|
err = getnameinfo(res->ai_addr, res->ai_addrlen,
|
||||||
|
hostbuf, sizeof(hostbuf),
|
||||||
|
NO_SERVICE, 0, NI_NAMEREQD);
|
||||||
|
if (err) {
|
||||||
|
fprintf(stderr, "getnameinfo %s: %s\n", host, gai_strerror(err));
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
printf("Hostname:\t%s\n", hostbuf);
|
||||||
|
addr = (res->ai_family == AF_INET ?
|
||||||
|
(char *) &((struct sockaddr_in *) res->ai_addr)->sin_addr :
|
||||||
|
(char *) &((struct sockaddr_in6 *) res->ai_addr)->sin6_addr);
|
||||||
|
if (inet_ntop(res->ai_family, addr, hostbuf, sizeof(hostbuf)) == 0) {
|
||||||
|
perror("inet_ntop:");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
printf("Address:\t%s\n", hostbuf);
|
||||||
|
}
|
||||||
|
freeaddrinfo(res0);
|
||||||
|
exit(0);
|
||||||
|
}
|
@ -643,6 +643,7 @@ EOF
|
|||||||
ed $config_directory/master.cf <<EOF || exit 1
|
ed $config_directory/master.cf <<EOF || exit 1
|
||||||
/^tlsmgr[ ]*fifo[ ]/
|
/^tlsmgr[ ]*fifo[ ]/
|
||||||
s/fifo/unix/
|
s/fifo/unix/
|
||||||
|
s/[0-9][0-9]*/&?/
|
||||||
p
|
p
|
||||||
w
|
w
|
||||||
q
|
q
|
||||||
|
@ -79,10 +79,11 @@ like: </p>
|
|||||||
</pre>
|
</pre>
|
||||||
</blockquote>
|
</blockquote>
|
||||||
|
|
||||||
<p> After postfix has been built with cdb support, you can use
|
<p> After Postfix has been built with cdb support, you can use
|
||||||
"cdb" tables wherever you can use read-only "hash", "btree" or
|
"cdb" tables wherever you can use read-only "hash", "btree" or
|
||||||
"dbm" tables. However, the "<b>postmap -i</b>" (incremental record
|
"dbm" tables. However, the "<b>postmap -i</b>" (incremental record
|
||||||
insertion) and "<b>postmap -d</b>" (incremental record deletion)
|
insertion) and "<b>postmap -d</b>" (incremental record deletion)
|
||||||
command-line options are not available. For the same reason the
|
command-line options are not available. For the same reason the
|
||||||
"cdb" map type cannot be used to store the persistent address
|
"cdb" map type cannot be used to store the persistent address
|
||||||
verification cache for the <a href="verify.8.html">verify(8)</a> service. </p>
|
verification cache for the <a href="verify.8.html">verify(8)</a> service, or to store
|
||||||
|
TLS session information for the <a href="tlsmgr.8.html">tlsmgr(8)</a> service. </p>
|
||||||
|
@ -113,9 +113,8 @@ Postfix versions. </p>
|
|||||||
<h2><a name="build_dovecot">Building Postfix with Dovecot SASL
|
<h2><a name="build_dovecot">Building Postfix with Dovecot SASL
|
||||||
support</a></h2>
|
support</a></h2>
|
||||||
|
|
||||||
<p> Dovecot SASL support is available in Postfix 2.3 and later. The
|
<p> Support for the Dovecot version 1 SASL protocol is available
|
||||||
Dovecot source code is available via <a href="http://www.dovecot.org/">http://www.dovecot.org/</a>. At
|
in Postfix 2.3 and later. At the time
|
||||||
the time
|
|
||||||
of writing, only server-side SASL support is available, so you can't
|
of writing, only server-side SASL support is available, so you can't
|
||||||
use it to authenticate to your network provider's server. Dovecot
|
use it to authenticate to your network provider's server. Dovecot
|
||||||
uses its own daemon process for authentication. This keeps the
|
uses its own daemon process for authentication. This keeps the
|
||||||
@ -127,7 +126,7 @@ in the Postfix top-level directory: </p>
|
|||||||
|
|
||||||
<blockquote>
|
<blockquote>
|
||||||
<pre>
|
<pre>
|
||||||
% make makefiles CCARGS='-DUSE_SASL_AUTH -DDEF_SASL_SERVER_TYPE=\"dovecot\"'
|
% make makefiles CCARGS='-DUSE_SASL_AUTH -DDEF_SERVER_SASL_TYPE=\"dovecot\"'
|
||||||
</pre>
|
</pre>
|
||||||
</blockquote>
|
</blockquote>
|
||||||
|
|
||||||
@ -138,7 +137,7 @@ in the Postfix top-level directory: </p>
|
|||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
|
|
||||||
<li> <p> The "-DDEF_SASL_SERVER_TYPE" stuff is not necessary; it just
|
<li> <p> The "-DDEF_SERVER_SASL_TYPE" stuff is not necessary; it just
|
||||||
makes Postfix configuration a little more convenient because you
|
makes Postfix configuration a little more convenient because you
|
||||||
don't have to specify the SASL plug-in type in the Postfix <a href="postconf.5.html">main.cf</a>
|
don't have to specify the SASL plug-in type in the Postfix <a href="postconf.5.html">main.cf</a>
|
||||||
file. </p>
|
file. </p>
|
||||||
|
@ -147,8 +147,8 @@ MASTER(5) MASTER(5)
|
|||||||
mented by connecting to the service and sending a
|
mented by connecting to the service and sending a
|
||||||
wake up request. A ? at the end of the wake-up
|
wake up request. A ? at the end of the wake-up
|
||||||
time field requests that no wake up events be sent
|
time field requests that no wake up events be sent
|
||||||
before the service is used. Specify 0 for no auto-
|
before the first time a service is used. Specify 0
|
||||||
matic wake up.
|
for no automatic wake up.
|
||||||
|
|
||||||
The <a href="pickup.8.html"><b>pickup</b>(8)</a>, <a href="qmgr.8.html"><b>qmgr</b>(8)</a> and <a href="flush.8.html"><b>flush</b>(8)</a> daemons require
|
The <a href="pickup.8.html"><b>pickup</b>(8)</a>, <a href="qmgr.8.html"><b>qmgr</b>(8)</a> and <a href="flush.8.html"><b>flush</b>(8)</a> daemons require
|
||||||
a wake up timer.
|
a wake up timer.
|
||||||
|
@ -5508,6 +5508,11 @@ may wish to turn on the policy (UCE and mail relaying) and protocol
|
|||||||
error (broken mail software) reports.
|
error (broken mail software) reports.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
<p> NOTE: postmaster notifications may contain confidential information
|
||||||
|
such as SASL passwords or message content. It is the system
|
||||||
|
administrator's responsibility to treat such information with care.
|
||||||
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
The error classes are:
|
The error classes are:
|
||||||
</p>
|
</p>
|
||||||
@ -11823,7 +11828,8 @@ message contains no To: or Cc: message header. </p>
|
|||||||
<p>
|
<p>
|
||||||
The numerical Postfix SMTP server response code when a sender or
|
The numerical Postfix SMTP server response code when a sender or
|
||||||
recipient address is rejected by the <a href="postconf.5.html#reject_unknown_sender_domain">reject_unknown_sender_domain</a>
|
recipient address is rejected by the <a href="postconf.5.html#reject_unknown_sender_domain">reject_unknown_sender_domain</a>
|
||||||
or <a href="postconf.5.html#reject_unknown_recipient_domain">reject_unknown_recipient_domain</a> restriction.
|
or <a href="postconf.5.html#reject_unknown_recipient_domain">reject_unknown_recipient_domain</a> restriction. The response is
|
||||||
|
always 450 in case of a temporary DNS error.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
|
@ -23,6 +23,12 @@ QMQP-SINK(1) QMQP-SINK(1)
|
|||||||
and IPv6 are the default. This program is the complement
|
and IPv6 are the default. This program is the complement
|
||||||
of the <a href="qmqp-source.1.html"><b>qmqp-source</b>(1)</a> program.
|
of the <a href="qmqp-source.1.html"><b>qmqp-source</b>(1)</a> program.
|
||||||
|
|
||||||
|
Note: this is an unsupported test program. No attempt is
|
||||||
|
made to maintain compatibility between successive ver-
|
||||||
|
sions.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
<b>-4</b> Support IPv4 only. This option has no effect when
|
<b>-4</b> Support IPv4 only. This option has no effect when
|
||||||
Postfix is built without IPv6 support.
|
Postfix is built without IPv6 support.
|
||||||
|
|
||||||
|
@ -21,7 +21,11 @@ QMQP-SOURCE(1) QMQP-SOURCE(1)
|
|||||||
protocol. Connections can be made to UNIX-domain and IPv4
|
protocol. Connections can be made to UNIX-domain and IPv4
|
||||||
or IPv6 servers. IPv4 and IPv6 are the default.
|
or IPv6 servers. IPv4 and IPv6 are the default.
|
||||||
|
|
||||||
Options:
|
Note: this is an unsupported test program. No attempt is
|
||||||
|
made to maintain compatibility between successive ver-
|
||||||
|
sions.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
<b>-4</b> Connect to the server with IPv4. This option has no
|
<b>-4</b> Connect to the server with IPv4. This option has no
|
||||||
effect when Postfix is built without IPv6 support.
|
effect when Postfix is built without IPv6 support.
|
||||||
|
@ -20,11 +20,21 @@ SMTP-SINK(1) SMTP-SINK(1)
|
|||||||
away. The purpose is to measure client performance, not
|
away. The purpose is to measure client performance, not
|
||||||
protocol compliance.
|
protocol compliance.
|
||||||
|
|
||||||
|
<b>smtp-sink</b> may also be configured to capture each mail
|
||||||
|
delivery transaction to file. Since disk latencies are
|
||||||
|
large compared to network delays, this mode of operation
|
||||||
|
can reduce the maximal performance by several orders of
|
||||||
|
magnitude.
|
||||||
|
|
||||||
Connections can be accepted on IPv4 or IPv6 endpoints, or
|
Connections can be accepted on IPv4 or IPv6 endpoints, or
|
||||||
on UNIX-domain sockets. IPv4 and IPv6 are the default.
|
on UNIX-domain sockets. IPv4 and IPv6 are the default.
|
||||||
This program is the complement of the <a href="smtp-source.1.html"><b>smtp-source</b>(1)</a> pro-
|
This program is the complement of the <a href="smtp-source.1.html"><b>smtp-source</b>(1)</a> pro-
|
||||||
gram.
|
gram.
|
||||||
|
|
||||||
|
Note: this is an unsupported test program. No attempt is
|
||||||
|
made to maintain compatibility between successive ver-
|
||||||
|
sions.
|
||||||
|
|
||||||
Arguments:
|
Arguments:
|
||||||
|
|
||||||
<b>-4</b> Support IPv4 only. This option has no effect when
|
<b>-4</b> Support IPv4 only. This option has no effect when
|
||||||
@ -43,6 +53,30 @@ SMTP-SINK(1) SMTP-SINK(1)
|
|||||||
|
|
||||||
<b>-C</b> Disable XCLIENT support.
|
<b>-C</b> Disable XCLIENT support.
|
||||||
|
|
||||||
|
<b>-d</b> <i>dump-template</i>
|
||||||
|
Dump each mail transaction to a single-message file
|
||||||
|
whose name is created by expanding the <i>dump-tem-</i>
|
||||||
|
<i>plate</i> via strftime(3) and appending a pseudo-random
|
||||||
|
hexadecimal number (example: "%Y%m%d%H/%M." expands
|
||||||
|
into "2006081203/05.809a62e3"). If the template
|
||||||
|
contains "/" characters, missing directories are
|
||||||
|
created automatically. The message dump format is
|
||||||
|
described below.
|
||||||
|
|
||||||
|
Note: this option keeps one capture file open for
|
||||||
|
every mail transaction in progress.
|
||||||
|
|
||||||
|
<b>-D</b> <i>dump-template</i>
|
||||||
|
Append mail transactions to a multi-message dump
|
||||||
|
file whose name is created by expanding the <i>dump-</i>
|
||||||
|
<i>template</i> via strftime(3). If the template contains
|
||||||
|
"/" characters, missing directories are created
|
||||||
|
automatically. The message dump format is
|
||||||
|
described below.
|
||||||
|
|
||||||
|
Note: this option keeps one capture file open for
|
||||||
|
every mail transaction in progress.
|
||||||
|
|
||||||
<b>-e</b> Do not announce ESMTP support.
|
<b>-e</b> Do not announce ESMTP support.
|
||||||
|
|
||||||
<b>-E</b> Do not announce ENHANCEDSTATUSCODES support.
|
<b>-E</b> Do not announce ENHANCEDSTATUSCODES support.
|
||||||
@ -66,6 +100,13 @@ SMTP-SINK(1) SMTP-SINK(1)
|
|||||||
|
|
||||||
<b>-L</b> Enable LMTP instead of SMTP.
|
<b>-L</b> Enable LMTP instead of SMTP.
|
||||||
|
|
||||||
|
<b>-m</b> <i>count</i> (default: 256)
|
||||||
|
An upper bound on the maximal number of simultane-
|
||||||
|
ous connections that <b>smtp-sink</b> will handle. This
|
||||||
|
prevents the process from running out of file
|
||||||
|
descriptors. Excess connections will stay queued in
|
||||||
|
the TCP/IP stack.
|
||||||
|
|
||||||
<b>-n</b> <i>count</i>
|
<b>-n</b> <i>count</i>
|
||||||
Terminate after <i>count</i> sessions. This is for testing
|
Terminate after <i>count</i> sessions. This is for testing
|
||||||
purposes.
|
purposes.
|
||||||
@ -105,9 +146,19 @@ SMTP-SINK(1) SMTP-SINK(1)
|
|||||||
and use quotes to protect white space from the
|
and use quotes to protect white space from the
|
||||||
shell. Command names are case-insensitive.
|
shell. Command names are case-insensitive.
|
||||||
|
|
||||||
|
<b>-S start-string</b>
|
||||||
|
An optional string that is prepended to each mes-
|
||||||
|
sage that is written to a dump file (see the dump
|
||||||
|
file format description below). The following C
|
||||||
|
escape sequences are supported: \a (bell), \b
|
||||||
|
(backslace), \f (formfeed), \n (newline), \r (car-
|
||||||
|
riage return), \t (horizontal tab), \v (vertical
|
||||||
|
tab), \<i>ddd</i> (up to three octal digits) and \\ (the
|
||||||
|
backslash character).
|
||||||
|
|
||||||
<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.
|
||||||
|
|
||||||
@ -116,7 +167,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.
|
||||||
|
|
||||||
@ -124,9 +175,76 @@ 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>DUMP FILE FORMAT</b>
|
||||||
|
Each dumped message contains a sequence of text lines,
|
||||||
|
terminated with the newline character. The sequence of
|
||||||
|
information is as follows:
|
||||||
|
|
||||||
|
<b>o</b> The optional string specified with the <b>-S</b> option.
|
||||||
|
|
||||||
|
<b>o</b> The <b>smtp-sink</b> generated headers as documented
|
||||||
|
below.
|
||||||
|
|
||||||
|
<b>o</b> The message header and body as received from the
|
||||||
|
SMTP client.
|
||||||
|
|
||||||
|
<b>o</b> An empty line.
|
||||||
|
|
||||||
|
The format of the <b>smtp-sink</b> generated headers is as fol-
|
||||||
|
lows:
|
||||||
|
|
||||||
|
<b>X-Client-Addr:</b> <i>text</i>
|
||||||
|
The client IP address without enclosing []. An IPv6
|
||||||
|
address is prefixed with "ipv6:". This record is
|
||||||
|
always present.
|
||||||
|
|
||||||
|
<b>X-Client-Proto:</b> <i>text</i>
|
||||||
|
The client protocol: SMTP, ESMTP or LMTP. This
|
||||||
|
record is always present.
|
||||||
|
|
||||||
|
<b>X-Helo-Args:</b> <i>text</i>
|
||||||
|
The arguments of the last HELO or EHLO command
|
||||||
|
before this mail delivery transaction. This record
|
||||||
|
is present only if the client sent a recognizable
|
||||||
|
HELO or EHLO command before the DATA command.
|
||||||
|
|
||||||
|
<b>X-Mail-Args:</b> <i>text</i>
|
||||||
|
The arguments, if any, of the MAIL command that
|
||||||
|
started this mail delivery transaction. This record
|
||||||
|
is present only if the client sent a recognizable
|
||||||
|
MAIL command.
|
||||||
|
|
||||||
|
<b>X-Rcpt-Args:</b> <i>text</i>
|
||||||
|
The arguments, if any, of each successive RCPT com-
|
||||||
|
mand within this mail delivery transaction. There
|
||||||
|
may be zero or more of these records. This record
|
||||||
|
is present only if the client sent a recognizable
|
||||||
|
RCPT command.
|
||||||
|
|
||||||
|
<b>Received:</b> <i>text</i>
|
||||||
|
A message header for compatibility with mail pro-
|
||||||
|
cessing software. This three-line header marks the
|
||||||
|
end of the headers provided by <b>smtp-sink</b>, and is
|
||||||
|
formatted as follows:
|
||||||
|
|
||||||
|
<b>from</b> <i>helo</i> <b>([</b><i>addr</i><b>])</b>
|
||||||
|
The HELO or EHLO command argument and client
|
||||||
|
IP address. If the client did not send HELO
|
||||||
|
or EHLO, the client IP address is used
|
||||||
|
instead.
|
||||||
|
|
||||||
|
<b>by</b> <i>host</i> <b>(smtp-sink) with</b> <i>proto</i> <b>id</b> <i>random</i><b>;</b>
|
||||||
|
The hostname specified with the <b>-h</b> option,
|
||||||
|
the client protocol (see <b>X-Client-Proto</b>
|
||||||
|
above), and the pseudo-random portion of the
|
||||||
|
per-message capture file name.
|
||||||
|
|
||||||
|
<i>time-stamp</i>
|
||||||
|
A time stamp as defined in <a href="http://www.faqs.org/rfcs/rfc2822.html">RFC 2822</a>.
|
||||||
|
|
||||||
<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
|
||||||
|
|
||||||
|
@ -22,6 +22,10 @@ SMTP-SOURCE(1) SMTP-SOURCE(1)
|
|||||||
UNIX-domain and IPv4 or IPv6 servers. IPv4 and IPv6 are
|
UNIX-domain and IPv4 or IPv6 servers. IPv4 and IPv6 are
|
||||||
the default.
|
the default.
|
||||||
|
|
||||||
|
Note: this is an unsupported test program. No attempt is
|
||||||
|
made to maintain compatibility between successive ver-
|
||||||
|
sions.
|
||||||
|
|
||||||
Arguments:
|
Arguments:
|
||||||
|
|
||||||
<b>-4</b> Connect to the server with IPv4. This option has no
|
<b>-4</b> Connect to the server with IPv4. This option has no
|
||||||
|
@ -25,6 +25,11 @@ Connections can be accepted on IPv4 or IPv6 endpoints, or on
|
|||||||
UNIX-domain sockets.
|
UNIX-domain sockets.
|
||||||
IPv4 and IPv6 are the default.
|
IPv4 and IPv6 are the default.
|
||||||
This program is the complement of the \fBqmqp-source\fR(1) program.
|
This program is the complement of the \fBqmqp-source\fR(1) program.
|
||||||
|
|
||||||
|
Note: this is an unsupported test program. No attempt is made
|
||||||
|
to maintain compatibility between successive versions.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
.IP \fB-4\fR
|
.IP \fB-4\fR
|
||||||
Support IPv4 only. This option has no effect when
|
Support IPv4 only. This option has no effect when
|
||||||
Postfix is built without IPv6 support.
|
Postfix is built without IPv6 support.
|
||||||
|
@ -21,7 +21,10 @@ or in parallel. The program speaks the QMQP protocol.
|
|||||||
Connections can be made to UNIX-domain and IPv4 or IPv6 servers.
|
Connections can be made to UNIX-domain and IPv4 or IPv6 servers.
|
||||||
IPv4 and IPv6 are the default.
|
IPv4 and IPv6 are the default.
|
||||||
|
|
||||||
Options:
|
Note: this is an unsupported test program. No attempt is made
|
||||||
|
to maintain compatibility between successive versions.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
.IP \fB-4\fR
|
.IP \fB-4\fR
|
||||||
Connect to the server with IPv4. This option has no effect when
|
Connect to the server with IPv4. This option has no effect when
|
||||||
Postfix is built without IPv6 support.
|
Postfix is built without IPv6 support.
|
||||||
|
@ -21,11 +21,19 @@ It takes SMTP messages from the network and throws them away.
|
|||||||
The purpose is to measure client performance, not protocol
|
The purpose is to measure client performance, not protocol
|
||||||
compliance.
|
compliance.
|
||||||
|
|
||||||
|
\fBsmtp-sink\fR may also be configured to capture each mail
|
||||||
|
delivery transaction to file. Since disk latencies are large
|
||||||
|
compared to network delays, this mode of operation can
|
||||||
|
reduce the maximal performance by several orders of magnitude.
|
||||||
|
|
||||||
Connections can be accepted on IPv4 or IPv6 endpoints, or on
|
Connections can be accepted on IPv4 or IPv6 endpoints, or on
|
||||||
UNIX-domain sockets.
|
UNIX-domain sockets.
|
||||||
IPv4 and IPv6 are the default.
|
IPv4 and IPv6 are the default.
|
||||||
This program is the complement of the \fBsmtp-source\fR(1) program.
|
This program is the complement of the \fBsmtp-source\fR(1) program.
|
||||||
|
|
||||||
|
Note: this is an unsupported test program. No attempt is made
|
||||||
|
to maintain compatibility between successive versions.
|
||||||
|
|
||||||
Arguments:
|
Arguments:
|
||||||
.IP \fB-4\fR
|
.IP \fB-4\fR
|
||||||
Support IPv4 only. This option has no effect when
|
Support IPv4 only. This option has no effect when
|
||||||
@ -43,6 +51,27 @@ session ends, a QUIT command is executed, or when "." is
|
|||||||
received.
|
received.
|
||||||
.IP \fB-C\fR
|
.IP \fB-C\fR
|
||||||
Disable XCLIENT support.
|
Disable XCLIENT support.
|
||||||
|
.IP "\fB-d \fIdump-template\fR"
|
||||||
|
Dump each mail transaction to a single-message file whose
|
||||||
|
name is created by expanding the \fIdump-template\fR via
|
||||||
|
strftime(3) and appending a pseudo-random hexadecimal number
|
||||||
|
(example: "%Y%m%d%H/%M." expands into "2006081203/05.809a62e3").
|
||||||
|
If the template contains "/" characters, missing directories
|
||||||
|
are created automatically. The message dump format is
|
||||||
|
described below.
|
||||||
|
.sp
|
||||||
|
Note: this option keeps one capture file open for every
|
||||||
|
mail transaction in progress.
|
||||||
|
.IP "\fB-D \fIdump-template\fR"
|
||||||
|
Append mail transactions to a multi-message dump file whose
|
||||||
|
name is created by expanding the \fIdump-template\fR via
|
||||||
|
strftime(3).
|
||||||
|
If the template contains "/" characters, missing directories
|
||||||
|
are created automatically. The message dump format is
|
||||||
|
described below.
|
||||||
|
.sp
|
||||||
|
Note: this option keeps one capture file open for every
|
||||||
|
mail transaction in progress.
|
||||||
.IP \fB-e\fR
|
.IP \fB-e\fR
|
||||||
Do not announce ESMTP support.
|
Do not announce ESMTP support.
|
||||||
.IP \fB-E\fR
|
.IP \fB-E\fR
|
||||||
@ -62,6 +91,11 @@ Use \fIhostname\fR in the SMTP greeting, in the HELO response,
|
|||||||
and in the EHLO response. The default hostname is "smtp-sink".
|
and in the EHLO response. The default hostname is "smtp-sink".
|
||||||
.IP \fB-L\fR
|
.IP \fB-L\fR
|
||||||
Enable LMTP instead of SMTP.
|
Enable LMTP instead of SMTP.
|
||||||
|
.IP "\fB-m \fIcount\fR (default: 256)"
|
||||||
|
An upper bound on the maximal number of simultaneous
|
||||||
|
connections that \fBsmtp-sink\fR will handle. This prevents
|
||||||
|
the process from running out of file descriptors. Excess
|
||||||
|
connections will stay queued in the TCP/IP stack.
|
||||||
.IP "\fB-n \fIcount\fR"
|
.IP "\fB-n \fIcount\fR"
|
||||||
Terminate after \fIcount\fR sessions. This is for testing purposes.
|
Terminate after \fIcount\fR sessions. This is for testing purposes.
|
||||||
.IP \fB-p\fR
|
.IP \fB-p\fR
|
||||||
@ -92,6 +126,14 @@ Examples of commands are CONNECT, HELO, EHLO, LHLO, MAIL, RCPT, VRFY,
|
|||||||
DATA, ., RSET, NOOP, and QUIT. Separate command names by
|
DATA, ., RSET, NOOP, and QUIT. Separate command names by
|
||||||
white space or commas, and use quotes to protect white space
|
white space or commas, and use quotes to protect white space
|
||||||
from the shell. Command names are case-insensitive.
|
from the shell. Command names are case-insensitive.
|
||||||
|
.IP "\fB-S start-string\fR"
|
||||||
|
An optional string that is prepended to each message that is
|
||||||
|
written to a dump file (see the dump file format description
|
||||||
|
below). The following C escape sequences are supported: \ea
|
||||||
|
(bell), \eb (backslace), \ef (formfeed), \en (newline), \er
|
||||||
|
(carriage return), \et (horizontal tab), \ev (vertical tab),
|
||||||
|
\e\fIddd\fR (up to three octal digits) and \e\e (the backslash
|
||||||
|
character).
|
||||||
.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.
|
||||||
@ -108,6 +150,62 @@ Listen on the UNIX-domain socket at \fIpathname\fR.
|
|||||||
.IP \fIbacklog\fR
|
.IP \fIbacklog\fR
|
||||||
The maximum length the queue of pending connections,
|
The maximum length the queue of pending connections,
|
||||||
as defined by the \fBlisten\fR(2) system call.
|
as defined by the \fBlisten\fR(2) system call.
|
||||||
|
.SH "DUMP FILE FORMAT"
|
||||||
|
.na
|
||||||
|
.nf
|
||||||
|
.ad
|
||||||
|
.fi
|
||||||
|
Each dumped message contains a sequence of text lines,
|
||||||
|
terminated with the newline character. The sequence of
|
||||||
|
information is as follows:
|
||||||
|
.IP \(bu
|
||||||
|
The optional string specified with the \fB-S\fR option.
|
||||||
|
.IP \(bu
|
||||||
|
The \fBsmtp-sink\fR generated headers as documented below.
|
||||||
|
.IP \(bu
|
||||||
|
The message header and body as received from the SMTP client.
|
||||||
|
.IP \(bu
|
||||||
|
An empty line.
|
||||||
|
.PP
|
||||||
|
The format of the \fBsmtp-sink\fR generated headers is as
|
||||||
|
follows:
|
||||||
|
.IP "\fBX-Client-Addr: \fItext\fR"
|
||||||
|
The client IP address without enclosing []. An IPv6 address
|
||||||
|
is prefixed with "ipv6:". This record is always present.
|
||||||
|
.IP "\fBX-Client-Proto: \fItext\fR"
|
||||||
|
The client protocol: SMTP, ESMTP or LMTP. This record is
|
||||||
|
always present.
|
||||||
|
.IP "\fBX-Helo-Args: \fItext\fR"
|
||||||
|
The arguments of the last HELO or EHLO command before this
|
||||||
|
mail delivery transaction. This record is present only if
|
||||||
|
the client sent a recognizable HELO or EHLO command before
|
||||||
|
the DATA command.
|
||||||
|
.IP "\fBX-Mail-Args: \fItext\fR"
|
||||||
|
The arguments, if any, of the MAIL command that started
|
||||||
|
this mail delivery transaction. This record is present only
|
||||||
|
if the client sent a recognizable MAIL command.
|
||||||
|
.IP "\fBX-Rcpt-Args: \fItext\fR"
|
||||||
|
The arguments, if any, of each successive RCPT command
|
||||||
|
within this mail delivery transaction. There may be zero
|
||||||
|
or more of these records. This record is present only if
|
||||||
|
the client sent a recognizable RCPT command.
|
||||||
|
.IP "\fBReceived: \fItext\fR"
|
||||||
|
A message header for compatibility with mail processing
|
||||||
|
software. This three-line header marks the end of the headers
|
||||||
|
provided by \fBsmtp-sink\fR, and is formatted
|
||||||
|
as follows:
|
||||||
|
.RS
|
||||||
|
.IP "\fBfrom \fIhelo\fB ([\fIaddr\fB])\fR"
|
||||||
|
The HELO or EHLO command argument and client IP address.
|
||||||
|
If the client did not send HELO or EHLO, the client IP
|
||||||
|
address is used instead.
|
||||||
|
.IP "\fBby \fIhost\fB (smtp-sink) with \fIproto\fB id \fIrandom\fB;\fR"
|
||||||
|
The hostname specified with the \fB-h\fR option, the client
|
||||||
|
protocol (see \fBX-Client-Proto\fR above), and the pseudo-random
|
||||||
|
portion of the per-message capture file name.
|
||||||
|
.IP \fItime-stamp\fR
|
||||||
|
A time stamp as defined in RFC 2822.
|
||||||
|
.RE
|
||||||
.SH "SEE ALSO"
|
.SH "SEE ALSO"
|
||||||
.na
|
.na
|
||||||
.nf
|
.nf
|
||||||
|
@ -23,6 +23,9 @@ LMTP.
|
|||||||
Connections can be made to UNIX-domain and IPv4 or IPv6 servers.
|
Connections can be made to UNIX-domain and IPv4 or IPv6 servers.
|
||||||
IPv4 and IPv6 are the default.
|
IPv4 and IPv6 are the default.
|
||||||
|
|
||||||
|
Note: this is an unsupported test program. No attempt is made
|
||||||
|
to maintain compatibility between successive versions.
|
||||||
|
|
||||||
Arguments:
|
Arguments:
|
||||||
.IP \fB-4\fR
|
.IP \fB-4\fR
|
||||||
Connect to the server with IPv4. This option has no effect when
|
Connect to the server with IPv4. This option has no effect when
|
||||||
|
@ -134,7 +134,7 @@ Automatically wake up the named service after the specified
|
|||||||
number of seconds. The wake up is implemented by connecting
|
number of seconds. The wake up is implemented by connecting
|
||||||
to the service and sending a wake up request. A ? at the
|
to the service and sending a wake up request. A ? at the
|
||||||
end of the wake-up time field requests that no wake up
|
end of the wake-up time field requests that no wake up
|
||||||
events be sent before the service is used.
|
events be sent before the first time a service is used.
|
||||||
Specify 0 for no automatic wake up.
|
Specify 0 for no automatic wake up.
|
||||||
.sp
|
.sp
|
||||||
The \fBpickup\fR(8), \fBqmgr\fR(8) and \fBflush\fR(8)
|
The \fBpickup\fR(8), \fBqmgr\fR(8) and \fBflush\fR(8)
|
||||||
|
@ -3019,6 +3019,10 @@ default is to report only the most serious problems. The paranoid
|
|||||||
may wish to turn on the policy (UCE and mail relaying) and protocol
|
may wish to turn on the policy (UCE and mail relaying) and protocol
|
||||||
error (broken mail software) reports.
|
error (broken mail software) reports.
|
||||||
.PP
|
.PP
|
||||||
|
NOTE: postmaster notifications may contain confidential information
|
||||||
|
such as SASL passwords or message content. It is the system
|
||||||
|
administrator's responsibility to treat such information with care.
|
||||||
|
.PP
|
||||||
The error classes are:
|
The error classes are:
|
||||||
.IP "\fBbounce\fR (also implies \fB2bounce\fR)"
|
.IP "\fBbounce\fR (also implies \fB2bounce\fR)"
|
||||||
Send the postmaster copies of the headers of bounced mail, and
|
Send the postmaster copies of the headers of bounced mail, and
|
||||||
@ -7164,7 +7168,8 @@ message contains no To: or Cc: message header.
|
|||||||
.SH unknown_address_reject_code (default: 450)
|
.SH unknown_address_reject_code (default: 450)
|
||||||
The numerical Postfix SMTP server response code when a sender or
|
The numerical Postfix SMTP server response code when a sender or
|
||||||
recipient address is rejected by the reject_unknown_sender_domain
|
recipient address is rejected by the reject_unknown_sender_domain
|
||||||
or reject_unknown_recipient_domain restriction.
|
or reject_unknown_recipient_domain restriction. The response is
|
||||||
|
always 450 in case of a temporary DNS error.
|
||||||
.PP
|
.PP
|
||||||
Do not change this unless you have a complete understanding of RFC 821.
|
Do not change this unless you have a complete understanding of RFC 821.
|
||||||
.SH unknown_client_reject_code (default: 450)
|
.SH unknown_client_reject_code (default: 450)
|
||||||
|
@ -79,10 +79,11 @@ like: </p>
|
|||||||
</pre>
|
</pre>
|
||||||
</blockquote>
|
</blockquote>
|
||||||
|
|
||||||
<p> After postfix has been built with cdb support, you can use
|
<p> After Postfix has been built with cdb support, you can use
|
||||||
"cdb" tables wherever you can use read-only "hash", "btree" or
|
"cdb" tables wherever you can use read-only "hash", "btree" or
|
||||||
"dbm" tables. However, the "<b>postmap -i</b>" (incremental record
|
"dbm" tables. However, the "<b>postmap -i</b>" (incremental record
|
||||||
insertion) and "<b>postmap -d</b>" (incremental record deletion)
|
insertion) and "<b>postmap -d</b>" (incremental record deletion)
|
||||||
command-line options are not available. For the same reason the
|
command-line options are not available. For the same reason the
|
||||||
"cdb" map type cannot be used to store the persistent address
|
"cdb" map type cannot be used to store the persistent address
|
||||||
verification cache for the verify(8) service. </p>
|
verification cache for the verify(8) service, or to store
|
||||||
|
TLS session information for the tlsmgr(8) service. </p>
|
||||||
|
@ -113,9 +113,8 @@ Postfix versions. </p>
|
|||||||
<h2><a name="build_dovecot">Building Postfix with Dovecot SASL
|
<h2><a name="build_dovecot">Building Postfix with Dovecot SASL
|
||||||
support</a></h2>
|
support</a></h2>
|
||||||
|
|
||||||
<p> Dovecot SASL support is available in Postfix 2.3 and later. The
|
<p> Support for the Dovecot version 1 SASL protocol is available
|
||||||
Dovecot source code is available via http://www.dovecot.org/. At
|
in Postfix 2.3 and later. At the time
|
||||||
the time
|
|
||||||
of writing, only server-side SASL support is available, so you can't
|
of writing, only server-side SASL support is available, so you can't
|
||||||
use it to authenticate to your network provider's server. Dovecot
|
use it to authenticate to your network provider's server. Dovecot
|
||||||
uses its own daemon process for authentication. This keeps the
|
uses its own daemon process for authentication. This keeps the
|
||||||
@ -127,7 +126,7 @@ in the Postfix top-level directory: </p>
|
|||||||
|
|
||||||
<blockquote>
|
<blockquote>
|
||||||
<pre>
|
<pre>
|
||||||
% make makefiles CCARGS='-DUSE_SASL_AUTH -DDEF_SASL_SERVER_TYPE=\"dovecot\"'
|
% make makefiles CCARGS='-DUSE_SASL_AUTH -DDEF_SERVER_SASL_TYPE=\"dovecot\"'
|
||||||
</pre>
|
</pre>
|
||||||
</blockquote>
|
</blockquote>
|
||||||
|
|
||||||
@ -138,7 +137,7 @@ INSTALL document. </p>
|
|||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
|
|
||||||
<li> <p> The "-DDEF_SASL_SERVER_TYPE" stuff is not necessary; it just
|
<li> <p> The "-DDEF_SERVER_SASL_TYPE" stuff is not necessary; it just
|
||||||
makes Postfix configuration a little more convenient because you
|
makes Postfix configuration a little more convenient because you
|
||||||
don't have to specify the SASL plug-in type in the Postfix main.cf
|
don't have to specify the SASL plug-in type in the Postfix main.cf
|
||||||
file. </p>
|
file. </p>
|
||||||
|
@ -128,7 +128,7 @@
|
|||||||
# number of seconds. The wake up is implemented by connecting
|
# number of seconds. The wake up is implemented by connecting
|
||||||
# to the service and sending a wake up request. A ? at the
|
# to the service and sending a wake up request. A ? at the
|
||||||
# end of the wake-up time field requests that no wake up
|
# end of the wake-up time field requests that no wake up
|
||||||
# events be sent before the service is used.
|
# events be sent before the first time a service is used.
|
||||||
# Specify 0 for no automatic wake up.
|
# Specify 0 for no automatic wake up.
|
||||||
# .sp
|
# .sp
|
||||||
# The \fBpickup\fR(8), \fBqmgr\fR(8) and \fBflush\fR(8)
|
# The \fBpickup\fR(8), \fBqmgr\fR(8) and \fBflush\fR(8)
|
||||||
|
@ -2801,6 +2801,11 @@ may wish to turn on the policy (UCE and mail relaying) and protocol
|
|||||||
error (broken mail software) reports.
|
error (broken mail software) reports.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
<p> NOTE: postmaster notifications may contain confidential information
|
||||||
|
such as SASL passwords or message content. It is the system
|
||||||
|
administrator's responsibility to treat such information with care.
|
||||||
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
The error classes are:
|
The error classes are:
|
||||||
</p>
|
</p>
|
||||||
@ -5894,7 +5899,8 @@ The default time unit is s (seconds).
|
|||||||
<p>
|
<p>
|
||||||
The numerical Postfix SMTP server response code when a sender or
|
The numerical Postfix SMTP server response code when a sender or
|
||||||
recipient address is rejected by the reject_unknown_sender_domain
|
recipient address is rejected by the reject_unknown_sender_domain
|
||||||
or reject_unknown_recipient_domain restriction.
|
or reject_unknown_recipient_domain restriction. The response is
|
||||||
|
always 450 in case of a temporary DNS error.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
|
@ -213,10 +213,13 @@
|
|||||||
|
|
||||||
static void cleanup_milter_set_error(CLEANUP_STATE *state, int err)
|
static void cleanup_milter_set_error(CLEANUP_STATE *state, int err)
|
||||||
{
|
{
|
||||||
if (err == EFBIG)
|
if (err == EFBIG) {
|
||||||
|
msg_warn("%s: queue file size limit exceeded", state->queue_id);
|
||||||
state->errs |= CLEANUP_STAT_SIZE;
|
state->errs |= CLEANUP_STAT_SIZE;
|
||||||
else
|
} else {
|
||||||
|
msg_warn("%s: write queue file: %m", state->queue_id);
|
||||||
state->errs |= CLEANUP_STAT_WRITE;
|
state->errs |= CLEANUP_STAT_WRITE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* cleanup_milter_error - return dummy error description */
|
/* cleanup_milter_error - return dummy error description */
|
||||||
|
@ -121,7 +121,7 @@ const char *mail_date(time_t when)
|
|||||||
* Finally, add the time zone name.
|
* Finally, add the time zone name.
|
||||||
*/
|
*/
|
||||||
while (strftime(vstring_end(vp), vstring_avail(vp), " (%Z)", lt) == 0)
|
while (strftime(vstring_end(vp), vstring_avail(vp), " (%Z)", lt) == 0)
|
||||||
VSTRING_SPACE(vp, 100);
|
VSTRING_SPACE(vp, vstring_avail(vp) + 100);
|
||||||
VSTRING_SKIP(vp);
|
VSTRING_SKIP(vp);
|
||||||
|
|
||||||
return (vstring_str(vp));
|
return (vstring_str(vp));
|
||||||
|
@ -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 "20060806"
|
#define MAIL_RELEASE_DATE "20060823"
|
||||||
#define MAIL_VERSION_NUMBER "2.4"
|
#define MAIL_VERSION_NUMBER "2.4"
|
||||||
|
|
||||||
#ifdef SNAPSHOT
|
#ifdef SNAPSHOT
|
||||||
|
@ -2250,7 +2250,7 @@ static int rcpt_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *argv)
|
|||||||
}
|
}
|
||||||
vstring_strcpy(state->dsn_orcpt_buf, arg + 6);
|
vstring_strcpy(state->dsn_orcpt_buf, arg + 6);
|
||||||
if (dsn_orcpt_addr
|
if (dsn_orcpt_addr
|
||||||
|| (coded_addr = split_at(STR(state->dsn_orcpt_buf), ';')) == 0
|
|| (coded_addr = split_at(STR(state->dsn_orcpt_buf), ';')) == 0
|
||||||
|| xtext_unquote(state->dsn_buf, coded_addr) == 0
|
|| xtext_unquote(state->dsn_buf, coded_addr) == 0
|
||||||
|| *(dsn_orcpt_type = STR(state->dsn_orcpt_buf)) == 0) {
|
|| *(dsn_orcpt_type = STR(state->dsn_orcpt_buf)) == 0) {
|
||||||
state->error_mask |= MAIL_ERROR_PROTOCOL;
|
state->error_mask |= MAIL_ERROR_PROTOCOL;
|
||||||
@ -2643,9 +2643,11 @@ static int data_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *unused_argv)
|
|||||||
&& (state->proxy == 0 ? (++start, --len) == 0 : len == 1))
|
&& (state->proxy == 0 ? (++start, --len) == 0 : len == 1))
|
||||||
break;
|
break;
|
||||||
if (state->err == CLEANUP_STAT_OK) {
|
if (state->err == CLEANUP_STAT_OK) {
|
||||||
if (var_message_limit > 0 && var_message_limit - state->act_size < len + 2)
|
if (var_message_limit > 0 && var_message_limit - state->act_size < len + 2) {
|
||||||
state->err = CLEANUP_STAT_SIZE;
|
state->err = CLEANUP_STAT_SIZE;
|
||||||
else {
|
msg_warn("%s: queue file size limit exceeded",
|
||||||
|
state->queue_id ? state->queue_id : "NOQUEUE");
|
||||||
|
} else {
|
||||||
state->act_size += len + 2;
|
state->act_size += len + 2;
|
||||||
if (out_record(out_stream, curr_rec_type, start, len) < 0)
|
if (out_record(out_stream, curr_rec_type, start, len) < 0)
|
||||||
state->err = out_error;
|
state->err = out_error;
|
||||||
|
@ -19,6 +19,11 @@
|
|||||||
/* UNIX-domain sockets.
|
/* UNIX-domain sockets.
|
||||||
/* IPv4 and IPv6 are the default.
|
/* IPv4 and IPv6 are the default.
|
||||||
/* This program is the complement of the \fBqmqp-source\fR(1) program.
|
/* This program is the complement of the \fBqmqp-source\fR(1) program.
|
||||||
|
/*
|
||||||
|
/* Note: this is an unsupported test program. No attempt is made
|
||||||
|
/* to maintain compatibility between successive versions.
|
||||||
|
/*
|
||||||
|
/* Arguments:
|
||||||
/* .IP \fB-4\fR
|
/* .IP \fB-4\fR
|
||||||
/* Support IPv4 only. This option has no effect when
|
/* Support IPv4 only. This option has no effect when
|
||||||
/* Postfix is built without IPv6 support.
|
/* Postfix is built without IPv6 support.
|
||||||
|
@ -15,7 +15,10 @@
|
|||||||
/* Connections can be made to UNIX-domain and IPv4 or IPv6 servers.
|
/* Connections can be made to UNIX-domain and IPv4 or IPv6 servers.
|
||||||
/* IPv4 and IPv6 are the default.
|
/* IPv4 and IPv6 are the default.
|
||||||
/*
|
/*
|
||||||
/* Options:
|
/* Note: this is an unsupported test program. No attempt is made
|
||||||
|
/* to maintain compatibility between successive versions.
|
||||||
|
/*
|
||||||
|
/* Arguments:
|
||||||
/* .IP \fB-4\fR
|
/* .IP \fB-4\fR
|
||||||
/* Connect to the server with IPv4. This option has no effect when
|
/* Connect to the server with IPv4. This option has no effect when
|
||||||
/* Postfix is built without IPv6 support.
|
/* Postfix is built without IPv6 support.
|
||||||
|
@ -15,11 +15,19 @@
|
|||||||
/* The purpose is to measure client performance, not protocol
|
/* The purpose is to measure client performance, not protocol
|
||||||
/* compliance.
|
/* compliance.
|
||||||
/*
|
/*
|
||||||
|
/* \fBsmtp-sink\fR may also be configured to capture each mail
|
||||||
|
/* delivery transaction to file. Since disk latencies are large
|
||||||
|
/* compared to network delays, this mode of operation can
|
||||||
|
/* reduce the maximal performance by several orders of magnitude.
|
||||||
|
/*
|
||||||
/* Connections can be accepted on IPv4 or IPv6 endpoints, or on
|
/* Connections can be accepted on IPv4 or IPv6 endpoints, or on
|
||||||
/* UNIX-domain sockets.
|
/* UNIX-domain sockets.
|
||||||
/* IPv4 and IPv6 are the default.
|
/* IPv4 and IPv6 are the default.
|
||||||
/* This program is the complement of the \fBsmtp-source\fR(1) program.
|
/* This program is the complement of the \fBsmtp-source\fR(1) program.
|
||||||
/*
|
/*
|
||||||
|
/* Note: this is an unsupported test program. No attempt is made
|
||||||
|
/* to maintain compatibility between successive versions.
|
||||||
|
/*
|
||||||
/* Arguments:
|
/* Arguments:
|
||||||
/* .IP \fB-4\fR
|
/* .IP \fB-4\fR
|
||||||
/* Support IPv4 only. This option has no effect when
|
/* Support IPv4 only. This option has no effect when
|
||||||
@ -37,6 +45,27 @@
|
|||||||
/* received.
|
/* received.
|
||||||
/* .IP \fB-C\fR
|
/* .IP \fB-C\fR
|
||||||
/* Disable XCLIENT support.
|
/* Disable XCLIENT support.
|
||||||
|
/* .IP "\fB-d \fIdump-template\fR"
|
||||||
|
/* Dump each mail transaction to a single-message file whose
|
||||||
|
/* name is created by expanding the \fIdump-template\fR via
|
||||||
|
/* strftime(3) and appending a pseudo-random hexadecimal number
|
||||||
|
/* (example: "%Y%m%d%H/%M." expands into "2006081203/05.809a62e3").
|
||||||
|
/* If the template contains "/" characters, missing directories
|
||||||
|
/* are created automatically. The message dump format is
|
||||||
|
/* described below.
|
||||||
|
/* .sp
|
||||||
|
/* Note: this option keeps one capture file open for every
|
||||||
|
/* mail transaction in progress.
|
||||||
|
/* .IP "\fB-D \fIdump-template\fR"
|
||||||
|
/* Append mail transactions to a multi-message dump file whose
|
||||||
|
/* name is created by expanding the \fIdump-template\fR via
|
||||||
|
/* strftime(3).
|
||||||
|
/* If the template contains "/" characters, missing directories
|
||||||
|
/* are created automatically. The message dump format is
|
||||||
|
/* described below.
|
||||||
|
/* .sp
|
||||||
|
/* Note: this option keeps one capture file open for every
|
||||||
|
/* mail transaction in progress.
|
||||||
/* .IP \fB-e\fR
|
/* .IP \fB-e\fR
|
||||||
/* Do not announce ESMTP support.
|
/* Do not announce ESMTP support.
|
||||||
/* .IP \fB-E\fR
|
/* .IP \fB-E\fR
|
||||||
@ -56,6 +85,11 @@
|
|||||||
/* and in the EHLO response. The default hostname is "smtp-sink".
|
/* and in the EHLO response. The default hostname is "smtp-sink".
|
||||||
/* .IP \fB-L\fR
|
/* .IP \fB-L\fR
|
||||||
/* Enable LMTP instead of SMTP.
|
/* Enable LMTP instead of SMTP.
|
||||||
|
/* .IP "\fB-m \fIcount\fR (default: 256)"
|
||||||
|
/* An upper bound on the maximal number of simultaneous
|
||||||
|
/* connections that \fBsmtp-sink\fR will handle. This prevents
|
||||||
|
/* the process from running out of file descriptors. Excess
|
||||||
|
/* connections will stay queued in the TCP/IP stack.
|
||||||
/* .IP "\fB-n \fIcount\fR"
|
/* .IP "\fB-n \fIcount\fR"
|
||||||
/* Terminate after \fIcount\fR sessions. This is for testing purposes.
|
/* Terminate after \fIcount\fR sessions. This is for testing purposes.
|
||||||
/* .IP \fB-p\fR
|
/* .IP \fB-p\fR
|
||||||
@ -86,6 +120,14 @@
|
|||||||
/* DATA, ., RSET, NOOP, and QUIT. Separate command names by
|
/* DATA, ., RSET, NOOP, and QUIT. Separate command names by
|
||||||
/* white space or commas, and use quotes to protect white space
|
/* white space or commas, and use quotes to protect white space
|
||||||
/* from the shell. Command names are case-insensitive.
|
/* from the shell. Command names are case-insensitive.
|
||||||
|
/* .IP "\fB-S start-string\fR"
|
||||||
|
/* An optional string that is prepended to each message that is
|
||||||
|
/* written to a dump file (see the dump file format description
|
||||||
|
/* below). The following C escape sequences are supported: \ea
|
||||||
|
/* (bell), \eb (backslace), \ef (formfeed), \en (newline), \er
|
||||||
|
/* (carriage return), \et (horizontal tab), \ev (vertical tab),
|
||||||
|
/* \e\fIddd\fR (up to three octal digits) and \e\e (the backslash
|
||||||
|
/* character).
|
||||||
/* .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.
|
||||||
@ -102,6 +144,60 @@
|
|||||||
/* .IP \fIbacklog\fR
|
/* .IP \fIbacklog\fR
|
||||||
/* The maximum length the queue of pending connections,
|
/* The maximum length the queue of pending connections,
|
||||||
/* as defined by the \fBlisten\fR(2) system call.
|
/* as defined by the \fBlisten\fR(2) system call.
|
||||||
|
/* DUMP FILE FORMAT
|
||||||
|
/* .ad
|
||||||
|
/* .fi
|
||||||
|
/* Each dumped message contains a sequence of text lines,
|
||||||
|
/* terminated with the newline character. The sequence of
|
||||||
|
/* information is as follows:
|
||||||
|
/* .IP \(bu
|
||||||
|
/* The optional string specified with the \fB-S\fR option.
|
||||||
|
/* .IP \(bu
|
||||||
|
/* The \fBsmtp-sink\fR generated headers as documented below.
|
||||||
|
/* .IP \(bu
|
||||||
|
/* The message header and body as received from the SMTP client.
|
||||||
|
/* .IP \(bu
|
||||||
|
/* An empty line.
|
||||||
|
/* .PP
|
||||||
|
/* The format of the \fBsmtp-sink\fR generated headers is as
|
||||||
|
/* follows:
|
||||||
|
/* .IP "\fBX-Client-Addr: \fItext\fR"
|
||||||
|
/* The client IP address without enclosing []. An IPv6 address
|
||||||
|
/* is prefixed with "ipv6:". This record is always present.
|
||||||
|
/* .IP "\fBX-Client-Proto: \fItext\fR"
|
||||||
|
/* The client protocol: SMTP, ESMTP or LMTP. This record is
|
||||||
|
/* always present.
|
||||||
|
/* .IP "\fBX-Helo-Args: \fItext\fR"
|
||||||
|
/* The arguments of the last HELO or EHLO command before this
|
||||||
|
/* mail delivery transaction. This record is present only if
|
||||||
|
/* the client sent a recognizable HELO or EHLO command before
|
||||||
|
/* the DATA command.
|
||||||
|
/* .IP "\fBX-Mail-Args: \fItext\fR"
|
||||||
|
/* The arguments, if any, of the MAIL command that started
|
||||||
|
/* this mail delivery transaction. This record is present only
|
||||||
|
/* if the client sent a recognizable MAIL command.
|
||||||
|
/* .IP "\fBX-Rcpt-Args: \fItext\fR"
|
||||||
|
/* The arguments, if any, of each successive RCPT command
|
||||||
|
/* within this mail delivery transaction. There may be zero
|
||||||
|
/* or more of these records. This record is present only if
|
||||||
|
/* the client sent a recognizable RCPT command.
|
||||||
|
/* .IP "\fBReceived: \fItext\fR"
|
||||||
|
/* A message header for compatibility with mail processing
|
||||||
|
/* software. This three-line header marks the end of the headers
|
||||||
|
/* provided by \fBsmtp-sink\fR, and is formatted
|
||||||
|
/* as follows:
|
||||||
|
/* .RS
|
||||||
|
/* .IP "\fBfrom \fIhelo\fB ([\fIaddr\fB])\fR"
|
||||||
|
/* The HELO or EHLO command argument and client IP address.
|
||||||
|
/* If the client did not send HELO or EHLO, the client IP
|
||||||
|
/* address is used instead.
|
||||||
|
/* .IP "\fBby \fIhost\fB (smtp-sink) with \fIproto\fB id \fIrandom\fB;\fR"
|
||||||
|
/* The hostname specified with the \fB-h\fR option, the client
|
||||||
|
/* protocol (see \fBX-Client-Proto\fR above), and the pseudo-random
|
||||||
|
/* portion of the per-message capture file name.
|
||||||
|
/* .IP \fItime-stamp\fR
|
||||||
|
/* A time stamp as defined in RFC 2822.
|
||||||
|
/* .RE
|
||||||
/* SEE ALSO
|
/* SEE ALSO
|
||||||
/* smtp-source(1), SMTP/LMTP message generator
|
/* smtp-source(1), SMTP/LMTP message generator
|
||||||
/* LICENSE
|
/* LICENSE
|
||||||
@ -120,12 +216,15 @@
|
|||||||
#include <sys_defs.h>
|
#include <sys_defs.h>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <syslog.h>
|
#include <syslog.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
#ifdef STRCASECMP_IN_STRINGS_H
|
#ifdef STRCASECMP_IN_STRINGS_H
|
||||||
#include <strings.h>
|
#include <strings.h>
|
||||||
@ -146,10 +245,14 @@
|
|||||||
#include <stringops.h>
|
#include <stringops.h>
|
||||||
#include <sane_accept.h>
|
#include <sane_accept.h>
|
||||||
#include <inet_proto.h>
|
#include <inet_proto.h>
|
||||||
|
#include <myaddrinfo.h>
|
||||||
|
#include <make_dirs.h>
|
||||||
|
#include <myrand.h>
|
||||||
|
|
||||||
/* Global library. */
|
/* Global library. */
|
||||||
|
|
||||||
#include <smtp_stream.h>
|
#include <smtp_stream.h>
|
||||||
|
#include <mail_date.h>
|
||||||
|
|
||||||
/* Application-specific. */
|
/* Application-specific. */
|
||||||
|
|
||||||
@ -158,8 +261,17 @@ typedef struct SINK_STATE {
|
|||||||
VSTRING *buffer;
|
VSTRING *buffer;
|
||||||
int data_state;
|
int data_state;
|
||||||
int (*read_fn) (struct SINK_STATE *);
|
int (*read_fn) (struct SINK_STATE *);
|
||||||
|
int in_mail;
|
||||||
int rcpts;
|
int rcpts;
|
||||||
char *push_back_ptr;
|
char *push_back_ptr;
|
||||||
|
/* Capture file information for fake Received: header */
|
||||||
|
MAI_HOSTADDR_STR client_addr; /* IP address */
|
||||||
|
char *addr_prefix; /* ipv6: or empty */
|
||||||
|
char *helo_args; /* text after HELO or EHLO */
|
||||||
|
const char *client_proto; /* SMTP, ESMTP, LMTP */
|
||||||
|
time_t start_time; /* MAIL command time */
|
||||||
|
int id; /* pseudo-random */
|
||||||
|
VSTREAM *dump_file; /* dump file or null */
|
||||||
} SINK_STATE;
|
} SINK_STATE;
|
||||||
|
|
||||||
#define ST_ANY 0
|
#define ST_ANY 0
|
||||||
@ -173,6 +285,10 @@ typedef struct SINK_STATE {
|
|||||||
#define PUSH_BACK_GET(state) (*(state)->push_back_ptr++)
|
#define PUSH_BACK_GET(state) (*(state)->push_back_ptr++)
|
||||||
#define PUSH_BACK_SET(state, text) ((state)->push_back_ptr = (text))
|
#define PUSH_BACK_SET(state, text) ((state)->push_back_ptr = (text))
|
||||||
|
|
||||||
|
#ifndef DEF_MAX_CLIENT_COUNT
|
||||||
|
#define DEF_MAX_CLIENT_COUNT 256
|
||||||
|
#endif
|
||||||
|
|
||||||
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;
|
||||||
@ -194,10 +310,19 @@ static int disable_saslauth;
|
|||||||
static int disable_xclient;
|
static int disable_xclient;
|
||||||
static int disable_xforward;
|
static int disable_xforward;
|
||||||
static int disable_enh_status;
|
static int disable_enh_status;
|
||||||
|
static int max_client_count = DEF_MAX_CLIENT_COUNT;
|
||||||
|
static int client_count;
|
||||||
|
static int sock;
|
||||||
|
|
||||||
|
static char *single_template; /* individual template */
|
||||||
|
static char *shared_template; /* shared template */
|
||||||
|
static VSTRING *start_string; /* dump content prefix */
|
||||||
|
|
||||||
#define SOFT_ERROR_RESP "450 4.3.0 Error: command failed"
|
#define SOFT_ERROR_RESP "450 4.3.0 Error: command failed"
|
||||||
#define HARD_ERROR_RESP "500 5.3.0 Error: command failed"
|
#define HARD_ERROR_RESP "500 5.3.0 Error: command failed"
|
||||||
|
|
||||||
|
#define STR(x) vstring_str(x)
|
||||||
|
|
||||||
/* do_stats - show counters */
|
/* do_stats - show counters */
|
||||||
|
|
||||||
static void do_stats(void)
|
static void do_stats(void)
|
||||||
@ -223,10 +348,211 @@ static void soft_err_resp(SINK_STATE *state)
|
|||||||
smtp_flush(state->stream);
|
smtp_flush(state->stream);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* exp_path_template - expand template pathname, static result */
|
||||||
|
|
||||||
|
static VSTRING *exp_path_template(const char *template, time_t start_time)
|
||||||
|
{
|
||||||
|
static VSTRING *path_buf = 0;
|
||||||
|
struct tm *lt;
|
||||||
|
|
||||||
|
if (path_buf == 0)
|
||||||
|
path_buf = vstring_alloc(100);
|
||||||
|
else
|
||||||
|
VSTRING_RESET(path_buf);
|
||||||
|
lt = localtime(&start_time);
|
||||||
|
while (strftime(STR(path_buf), vstring_avail(path_buf), template, lt) == 0)
|
||||||
|
VSTRING_SPACE(path_buf, vstring_avail(path_buf) + 100);
|
||||||
|
VSTRING_SKIP(path_buf);
|
||||||
|
return (path_buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* make_parent_dir - create parent directory or bust */
|
||||||
|
|
||||||
|
static void make_parent_dir(const char *path, mode_t mode)
|
||||||
|
{
|
||||||
|
const char *parent;
|
||||||
|
|
||||||
|
parent = sane_dirname((VSTRING *) 0, path);
|
||||||
|
if (make_dirs(parent, mode) < 0)
|
||||||
|
msg_fatal("mkdir %s: %m", parent);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* mail_file_open - open mail capture file */
|
||||||
|
|
||||||
|
static void mail_file_open(SINK_STATE *state)
|
||||||
|
{
|
||||||
|
const char *myname = "mail_file_open";
|
||||||
|
VSTRING *path_buf;
|
||||||
|
ssize_t len;
|
||||||
|
int tries = 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Save the start time for later.
|
||||||
|
*/
|
||||||
|
time(&(state->start_time));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Expand the per-message dumpfile pathname template.
|
||||||
|
*/
|
||||||
|
path_buf = exp_path_template(single_template, state->start_time);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Append a random hexadecimal string to the pathname and create a new
|
||||||
|
* file. Retry with a different path if the file already exists. Create
|
||||||
|
* intermediate directories on the fly when the template specifies
|
||||||
|
* multiple pathname segments.
|
||||||
|
*/
|
||||||
|
#define ID_FORMAT "%08x"
|
||||||
|
|
||||||
|
for (len = VSTRING_LEN(path_buf); /* void */ ; vstring_truncate(path_buf, len)) {
|
||||||
|
if (++tries > 100)
|
||||||
|
msg_fatal("%s: something is looping", myname);
|
||||||
|
state->id = myrand();
|
||||||
|
vstring_sprintf_append(path_buf, ID_FORMAT, state->id);
|
||||||
|
if ((state->dump_file = vstream_fopen(STR(path_buf),
|
||||||
|
O_RDWR | O_CREAT | O_EXCL,
|
||||||
|
0644)) != 0) {
|
||||||
|
break;
|
||||||
|
} else if (errno == EEXIST) {
|
||||||
|
continue;
|
||||||
|
} else if (errno == ENOENT) {
|
||||||
|
make_parent_dir(STR(path_buf), 0755);
|
||||||
|
continue;
|
||||||
|
} else {
|
||||||
|
msg_fatal("open %s: %m", STR(path_buf));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Don't leave temporary files behind.
|
||||||
|
*/
|
||||||
|
if (shared_template != 0 && unlink(STR(path_buf)) < 0)
|
||||||
|
msg_fatal("unlink %s: %m", STR(path_buf));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Do initial header records.
|
||||||
|
*/
|
||||||
|
if (start_string)
|
||||||
|
vstream_fprintf(state->dump_file, "%s", STR(start_string));
|
||||||
|
vstream_fprintf(state->dump_file, "X-Client-Addr: %s%s\n",
|
||||||
|
state->addr_prefix, state->client_addr.buf);
|
||||||
|
vstream_fprintf(state->dump_file, "X-Client-Proto: %s\n", state->client_proto);
|
||||||
|
if (state->helo_args)
|
||||||
|
vstream_fprintf(state->dump_file, "X-Helo-Args: %s\n", state->helo_args);
|
||||||
|
/* Note: there may be more than one recipient. */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* mail_file_finish_header - do final smtp-sink generated header records */
|
||||||
|
|
||||||
|
static void mail_file_finish_header(SINK_STATE *state)
|
||||||
|
{
|
||||||
|
if (state->helo_args)
|
||||||
|
vstream_fprintf(state->dump_file, "Received: from %s ([%s%s])\n",
|
||||||
|
state->helo_args, state->addr_prefix,
|
||||||
|
state->client_addr.buf);
|
||||||
|
else
|
||||||
|
vstream_fprintf(state->dump_file, "Received: from [%s%s] ([%s%s])\n",
|
||||||
|
state->addr_prefix, state->client_addr.buf,
|
||||||
|
state->addr_prefix, state->client_addr.buf);
|
||||||
|
vstream_fprintf(state->dump_file, "\tby %s (smtp-sink)"
|
||||||
|
" with %s id " ID_FORMAT ";\n",
|
||||||
|
var_myhostname, state->client_proto, state->id);
|
||||||
|
vstream_fprintf(state->dump_file, "\t%s\n", mail_date(state->start_time));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* mail_file_cleanup - common cleanup for capture file */
|
||||||
|
|
||||||
|
static void mail_file_cleanup(SINK_STATE *state)
|
||||||
|
{
|
||||||
|
(void) vstream_fclose(state->dump_file);
|
||||||
|
state->dump_file = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* mail_file_finish - handle message completion for capture file */
|
||||||
|
|
||||||
|
static void mail_file_finish(SINK_STATE *state)
|
||||||
|
{
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Optionally append the captured message to a shared dumpfile.
|
||||||
|
*/
|
||||||
|
if (shared_template) {
|
||||||
|
const char *out_path;
|
||||||
|
VSTREAM *out_fp;
|
||||||
|
ssize_t count;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Expand the shared dumpfile pathname template.
|
||||||
|
*/
|
||||||
|
out_path = STR(exp_path_template(shared_template, state->start_time));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Open the shared dump file.
|
||||||
|
*/
|
||||||
|
#define OUT_OPEN_FLAGS (O_WRONLY | O_CREAT | O_APPEND)
|
||||||
|
#define OUT_OPEN_MODE 0644
|
||||||
|
|
||||||
|
if ((out_fp = vstream_fopen(out_path, OUT_OPEN_FLAGS, OUT_OPEN_MODE))
|
||||||
|
== 0 && errno == ENOENT) {
|
||||||
|
make_parent_dir(out_path, 0755);
|
||||||
|
out_fp = vstream_fopen(out_path, OUT_OPEN_FLAGS, OUT_OPEN_MODE);
|
||||||
|
}
|
||||||
|
if (out_fp == 0)
|
||||||
|
msg_fatal("open %s: %m", out_path);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Append message content from single-message dump file.
|
||||||
|
*/
|
||||||
|
if (vstream_fseek(state->dump_file, 0L, SEEK_SET) < 0)
|
||||||
|
msg_fatal("seek file %s: %m", VSTREAM_PATH(state->dump_file));
|
||||||
|
VSTRING_RESET(state->buffer);
|
||||||
|
for (;;) {
|
||||||
|
count = vstream_fread(state->dump_file, STR(state->buffer),
|
||||||
|
vstring_avail(state->buffer));
|
||||||
|
if (count <= 0)
|
||||||
|
break;
|
||||||
|
if (vstream_fwrite(out_fp, STR(state->buffer), count) != count)
|
||||||
|
msg_fatal("append file %s: %m", out_path);
|
||||||
|
}
|
||||||
|
if (vstream_ferror(state->dump_file))
|
||||||
|
msg_fatal("read file %s: %m", VSTREAM_PATH(state->dump_file));
|
||||||
|
if (vstream_fclose(out_fp))
|
||||||
|
msg_fatal("append file %s: %m", out_path);
|
||||||
|
}
|
||||||
|
mail_file_cleanup(state);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* mail_file_reset - abort mail to capture file */
|
||||||
|
|
||||||
|
static void mail_file_reset(SINK_STATE *state)
|
||||||
|
{
|
||||||
|
if (shared_template == 0
|
||||||
|
&& unlink(VSTREAM_PATH(state->dump_file)) < 0
|
||||||
|
&& errno != ENOENT)
|
||||||
|
msg_fatal("unlink %s: %m", VSTREAM_PATH(state->dump_file));
|
||||||
|
mail_file_cleanup(state);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* mail_cmd_reset - reset mail transaction information */
|
||||||
|
|
||||||
|
static void mail_cmd_reset(SINK_STATE *state)
|
||||||
|
{
|
||||||
|
state->in_mail = 0;
|
||||||
|
/* Not: state->rcpts = 0. This breaks the DOT reply with LMTP. */
|
||||||
|
if (state->dump_file)
|
||||||
|
mail_file_reset(state);
|
||||||
|
}
|
||||||
|
|
||||||
/* 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, const char *args)
|
||||||
{
|
{
|
||||||
|
#define SKIP(cp, cond) for (/* void */; *cp && (cond); cp++)
|
||||||
|
|
||||||
|
/* EHLO aborts a mail transaction in progress. */
|
||||||
|
mail_cmd_reset(state);
|
||||||
|
if (enable_lmtp == 0)
|
||||||
|
state->client_proto = "ESMTP";
|
||||||
smtp_printf(state->stream, "250-%s", var_myhostname);
|
smtp_printf(state->stream, "250-%s", var_myhostname);
|
||||||
if (!disable_pipelining)
|
if (!disable_pipelining)
|
||||||
smtp_printf(state->stream, "250-PIPELINING");
|
smtp_printf(state->stream, "250-PIPELINING");
|
||||||
@ -242,50 +568,107 @@ static void ehlo_response(SINK_STATE *state)
|
|||||||
smtp_printf(state->stream, "250-ENHANCEDSTATUSCODES");
|
smtp_printf(state->stream, "250-ENHANCEDSTATUSCODES");
|
||||||
smtp_printf(state->stream, "250 ");
|
smtp_printf(state->stream, "250 ");
|
||||||
smtp_flush(state->stream);
|
smtp_flush(state->stream);
|
||||||
|
if (single_template) {
|
||||||
|
if (state->helo_args)
|
||||||
|
myfree(state->helo_args);
|
||||||
|
SKIP(args, ISSPACE(*args));
|
||||||
|
state->helo_args = mystrdup(args);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* helo_response - respond to HELO command */
|
/* helo_response - respond to HELO command */
|
||||||
|
|
||||||
static void helo_response(SINK_STATE *state)
|
static void helo_response(SINK_STATE *state, const char *args)
|
||||||
{
|
{
|
||||||
|
/* HELO aborts a mail transaction in progress. */
|
||||||
|
mail_cmd_reset(state);
|
||||||
|
state->client_proto = "SMTP";
|
||||||
smtp_printf(state->stream, "250 %s", var_myhostname);
|
smtp_printf(state->stream, "250 %s", var_myhostname);
|
||||||
smtp_flush(state->stream);
|
smtp_flush(state->stream);
|
||||||
|
if (single_template) {
|
||||||
|
if (state->helo_args)
|
||||||
|
myfree(state->helo_args);
|
||||||
|
SKIP(args, ISSPACE(*args));
|
||||||
|
state->helo_args = mystrdup(args);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ok_response - send 250 OK */
|
/* ok_response - send 250 OK */
|
||||||
|
|
||||||
static void ok_response(SINK_STATE *state)
|
static void ok_response(SINK_STATE *state, const char *unused_args)
|
||||||
{
|
{
|
||||||
smtp_printf(state->stream, "250 2.0.0 Ok");
|
smtp_printf(state->stream, "250 2.0.0 Ok");
|
||||||
smtp_flush(state->stream);
|
smtp_flush(state->stream);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* mail_response - reset recipient count, send 250 OK */
|
/* rset_response - reset, send 250 OK */
|
||||||
|
|
||||||
static void mail_response(SINK_STATE *state)
|
static void rset_response(SINK_STATE *state, const char *unused_args)
|
||||||
{
|
{
|
||||||
state->rcpts = 0;
|
mail_cmd_reset(state);
|
||||||
smtp_printf(state->stream, "250 2.1.0 Ok");
|
smtp_printf(state->stream, "250 2.1.0 Ok");
|
||||||
smtp_flush(state->stream);
|
smtp_flush(state->stream);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* mail_response - reset recipient count, send 250 OK */
|
||||||
|
|
||||||
|
static void mail_response(SINK_STATE *state, const char *args)
|
||||||
|
{
|
||||||
|
if (state->in_mail) {
|
||||||
|
smtp_printf(state->stream, "503 5.5.1 Error: nested MAIL command");
|
||||||
|
smtp_flush(state->stream);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
state->in_mail++;
|
||||||
|
state->rcpts = 0;
|
||||||
|
smtp_printf(state->stream, "250 2.1.0 Ok");
|
||||||
|
smtp_flush(state->stream);
|
||||||
|
if (single_template) {
|
||||||
|
mail_file_open(state);
|
||||||
|
SKIP(args, *args != ':');
|
||||||
|
SKIP(args, *args == ':');
|
||||||
|
SKIP(args, ISSPACE(*args));
|
||||||
|
vstream_fprintf(state->dump_file, "X-Mail-Args: %s\n", args);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* rcpt_response - bump recipient count, send 250 OK */
|
/* rcpt_response - bump recipient count, send 250 OK */
|
||||||
|
|
||||||
static void rcpt_response(SINK_STATE *state)
|
static void rcpt_response(SINK_STATE *state, const char *args)
|
||||||
{
|
{
|
||||||
|
if (state->in_mail == 0) {
|
||||||
|
smtp_printf(state->stream, "503 5.5.1 Error: need MAIL command");
|
||||||
|
smtp_flush(state->stream);
|
||||||
|
return;
|
||||||
|
}
|
||||||
state->rcpts++;
|
state->rcpts++;
|
||||||
smtp_printf(state->stream, "250 2.1.5 Ok");
|
smtp_printf(state->stream, "250 2.1.5 Ok");
|
||||||
smtp_flush(state->stream);
|
smtp_flush(state->stream);
|
||||||
|
/* Note: there may be more than one recipient per mail transaction. */
|
||||||
|
if (state->dump_file) {
|
||||||
|
SKIP(args, *args != ':');
|
||||||
|
SKIP(args, *args == ':');
|
||||||
|
SKIP(args, ISSPACE(*args));
|
||||||
|
vstream_fprintf(state->dump_file, "X-Rcpt-Args: %s\n", args);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* data_response - respond to DATA command */
|
/* data_response - respond to DATA command */
|
||||||
|
|
||||||
static void data_response(SINK_STATE *state)
|
static void data_response(SINK_STATE *state, const char *unused_args)
|
||||||
{
|
{
|
||||||
|
if (state->in_mail == 0 || state->rcpts == 0) {
|
||||||
|
smtp_printf(state->stream, "503 5.5.1 Error: need RCPT command");
|
||||||
|
smtp_flush(state->stream);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
/* Not: ST_ANY. */
|
||||||
state->data_state = ST_CR_LF;
|
state->data_state = ST_CR_LF;
|
||||||
smtp_printf(state->stream, "354 End data with <CR><LF>.<CR><LF>");
|
smtp_printf(state->stream, "354 End data with <CR><LF>.<CR><LF>");
|
||||||
smtp_flush(state->stream);
|
smtp_flush(state->stream);
|
||||||
state->read_fn = data_read;
|
state->read_fn = data_read;
|
||||||
|
if (state->dump_file)
|
||||||
|
mail_file_finish_header(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* data_event - delayed response to DATA command */
|
/* data_event - delayed response to DATA command */
|
||||||
@ -294,7 +677,7 @@ static void data_event(int unused_event, char *context)
|
|||||||
{
|
{
|
||||||
SINK_STATE *state = (SINK_STATE *) context;
|
SINK_STATE *state = (SINK_STATE *) context;
|
||||||
|
|
||||||
data_response(state);
|
data_response(state, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* dot_resp_hard - hard error response to . command */
|
/* dot_resp_hard - hard error response to . command */
|
||||||
@ -325,7 +708,7 @@ static void dot_resp_soft(SINK_STATE *state)
|
|||||||
|
|
||||||
/* dot_response - response to . command */
|
/* dot_response - response to . command */
|
||||||
|
|
||||||
static void dot_response(SINK_STATE *state)
|
static void dot_response(SINK_STATE *state, const char *unused_args)
|
||||||
{
|
{
|
||||||
if (enable_lmtp) {
|
if (enable_lmtp) {
|
||||||
while (state->rcpts-- > 0) /* XXX this could block */
|
while (state->rcpts-- > 0) /* XXX this could block */
|
||||||
@ -338,7 +721,7 @@ static void dot_response(SINK_STATE *state)
|
|||||||
|
|
||||||
/* quit_response - respond to QUIT command */
|
/* quit_response - respond to QUIT command */
|
||||||
|
|
||||||
static void quit_response(SINK_STATE *state)
|
static void quit_response(SINK_STATE *state, const char *unused_args)
|
||||||
{
|
{
|
||||||
smtp_printf(state->stream, "221 Bye");
|
smtp_printf(state->stream, "221 Bye");
|
||||||
smtp_flush(state->stream);
|
smtp_flush(state->stream);
|
||||||
@ -348,7 +731,7 @@ static void quit_response(SINK_STATE *state)
|
|||||||
|
|
||||||
/* conn_response - respond to connect command */
|
/* conn_response - respond to connect command */
|
||||||
|
|
||||||
static void conn_response(SINK_STATE *state)
|
static void conn_response(SINK_STATE *state, const char *unused_args)
|
||||||
{
|
{
|
||||||
if (pretend_pix)
|
if (pretend_pix)
|
||||||
smtp_printf(state->stream, "220 ********");
|
smtp_printf(state->stream, "220 ********");
|
||||||
@ -400,10 +783,19 @@ static int data_read(SINK_STATE *state)
|
|||||||
state->data_state = data_trans[0].next_state;
|
state->data_state = data_trans[0].next_state;
|
||||||
else
|
else
|
||||||
state->data_state = ST_ANY;
|
state->data_state = ST_ANY;
|
||||||
|
if (state->dump_file) {
|
||||||
|
if (ch != '\r' && state->data_state != ST_CR_LF_DOT)
|
||||||
|
VSTREAM_PUTC(ch, state->dump_file);
|
||||||
|
if (vstream_ferror(state->dump_file))
|
||||||
|
msg_fatal("append file %s: %m", VSTREAM_PATH(state->dump_file));
|
||||||
|
}
|
||||||
if (state->data_state == ST_CR_LF_DOT_CR_LF) {
|
if (state->data_state == ST_CR_LF_DOT_CR_LF) {
|
||||||
PUSH_BACK_SET(state, ".\r\n");
|
PUSH_BACK_SET(state, ".\r\n");
|
||||||
state->read_fn = command_read;
|
state->read_fn = command_read;
|
||||||
state->data_state = ST_ANY;
|
state->data_state = ST_ANY;
|
||||||
|
if (state->dump_file)
|
||||||
|
mail_file_finish(state);
|
||||||
|
mail_cmd_reset(state);
|
||||||
if (count) {
|
if (count) {
|
||||||
mesg_count++;
|
mesg_count++;
|
||||||
do_stats();
|
do_stats();
|
||||||
@ -427,7 +819,7 @@ static int data_read(SINK_STATE *state)
|
|||||||
*/
|
*/
|
||||||
typedef struct SINK_COMMAND {
|
typedef struct SINK_COMMAND {
|
||||||
const char *name;
|
const char *name;
|
||||||
void (*response) (SINK_STATE *);
|
void (*response) (SINK_STATE *, const char *);
|
||||||
void (*hard_response) (SINK_STATE *);
|
void (*hard_response) (SINK_STATE *);
|
||||||
void (*soft_response) (SINK_STATE *);
|
void (*soft_response) (SINK_STATE *);
|
||||||
int flags;
|
int flags;
|
||||||
@ -451,7 +843,7 @@ static SINK_COMMAND command_table[] = {
|
|||||||
"rcpt", rcpt_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,
|
"data", data_response, hard_err_resp, soft_err_resp, FLAG_ENABLE,
|
||||||
".", dot_response, dot_resp_hard, dot_resp_soft, FLAG_ENABLE,
|
".", dot_response, dot_resp_hard, dot_resp_soft, FLAG_ENABLE,
|
||||||
"rset", ok_response, hard_err_resp, soft_err_resp, FLAG_ENABLE,
|
"rset", rset_response, hard_err_resp, soft_err_resp, FLAG_ENABLE,
|
||||||
"noop", 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,
|
"vrfy", ok_response, hard_err_resp, soft_err_resp, FLAG_ENABLE,
|
||||||
"quit", quit_response, hard_err_resp, soft_err_resp, FLAG_ENABLE,
|
"quit", quit_response, hard_err_resp, soft_err_resp, FLAG_ENABLE,
|
||||||
@ -502,11 +894,12 @@ static void set_cmds_flags(const char *cmds, int flags)
|
|||||||
|
|
||||||
/* command_resp - respond to command */
|
/* command_resp - respond to command */
|
||||||
|
|
||||||
static int command_resp(SINK_STATE *state, SINK_COMMAND *cmdp, const char *command, char *args)
|
static int command_resp(SINK_STATE *state, SINK_COMMAND *cmdp,
|
||||||
|
const char *command, const char *args)
|
||||||
{
|
{
|
||||||
/* 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(args, '?'));
|
syslog(LOG_INFO, "%s %.100s", command, args);
|
||||||
if (cmdp->flags & FLAG_DISCONNECT)
|
if (cmdp->flags & FLAG_DISCONNECT)
|
||||||
return (-1);
|
return (-1);
|
||||||
if (cmdp->flags & FLAG_HARD_ERR) {
|
if (cmdp->flags & FLAG_HARD_ERR) {
|
||||||
@ -520,7 +913,7 @@ static int command_resp(SINK_STATE *state, SINK_COMMAND *cmdp, const char *comma
|
|||||||
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 {
|
||||||
cmdp->response(state);
|
cmdp->response(state, args);
|
||||||
if (cmdp->response == quit_response)
|
if (cmdp->response == quit_response)
|
||||||
return (-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
@ -604,7 +997,7 @@ static int command_read(SINK_STATE *state)
|
|||||||
*/
|
*/
|
||||||
vstring_truncate(state->buffer, VSTRING_LEN(state->buffer) - 2);
|
vstring_truncate(state->buffer, VSTRING_LEN(state->buffer) - 2);
|
||||||
VSTRING_TERMINATE(state->buffer);
|
VSTRING_TERMINATE(state->buffer);
|
||||||
state->data_state = ST_ANY;
|
state->data_state = ST_CR_LF;
|
||||||
VSTRING_RESET(state->buffer);
|
VSTRING_RESET(state->buffer);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -626,7 +1019,7 @@ static int command_read(SINK_STATE *state)
|
|||||||
smtp_flush(state->stream);
|
smtp_flush(state->stream);
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
return (command_resp(state, cmdp, command, ptr));
|
return (command_resp(state, cmdp, command, printable(ptr, '?')));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* read_timeout - handle timer event */
|
/* read_timeout - handle timer event */
|
||||||
@ -698,6 +1091,8 @@ static void read_event(int unused_event, char *context)
|
|||||||
|
|
||||||
static void disconnect(SINK_STATE *state)
|
static void disconnect(SINK_STATE *state)
|
||||||
{
|
{
|
||||||
|
static void connect_event(int, char *);
|
||||||
|
|
||||||
event_disable_readwrite(vstream_fileno(state->stream));
|
event_disable_readwrite(vstream_fileno(state->stream));
|
||||||
event_cancel_timer(read_timeout, (char *) state);
|
event_cancel_timer(read_timeout, (char *) state);
|
||||||
if (count) {
|
if (count) {
|
||||||
@ -706,24 +1101,36 @@ static void disconnect(SINK_STATE *state)
|
|||||||
}
|
}
|
||||||
vstream_fclose(state->stream);
|
vstream_fclose(state->stream);
|
||||||
vstring_free(state->buffer);
|
vstring_free(state->buffer);
|
||||||
|
/* Clean up file capture attributes. */
|
||||||
|
if (state->helo_args)
|
||||||
|
myfree(state->helo_args);
|
||||||
|
/* Delete incomplete mail transaction. */
|
||||||
|
mail_cmd_reset(state);
|
||||||
myfree((char *) state);
|
myfree((char *) state);
|
||||||
if (max_quit_count > 0 && quit_count >= max_quit_count)
|
if (max_quit_count > 0 && quit_count >= max_quit_count)
|
||||||
exit(0);
|
exit(0);
|
||||||
|
if (client_count-- == max_client_count)
|
||||||
|
event_enable_read(sock, connect_event, (char *) 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* connect_event - handle connection events */
|
/* connect_event - handle connection events */
|
||||||
|
|
||||||
static void connect_event(int unused_event, char *context)
|
static void connect_event(int unused_event, char *unused_context)
|
||||||
{
|
{
|
||||||
int sock = CAST_CHAR_PTR_TO_INT(context);
|
|
||||||
struct sockaddr sa;
|
struct sockaddr sa;
|
||||||
SOCKADDR_SIZE len = sizeof(sa);
|
SOCKADDR_SIZE len = sizeof(sa);
|
||||||
SINK_STATE *state;
|
SINK_STATE *state;
|
||||||
int fd;
|
int fd;
|
||||||
|
|
||||||
if ((fd = sane_accept(sock, &sa, &len)) >= 0) {
|
if ((fd = sane_accept(sock, &sa, &len)) >= 0) {
|
||||||
|
/* Safety: limit the number of open sockets and capture files. */
|
||||||
|
if (++client_count == max_client_count)
|
||||||
|
event_disable_readwrite(sock);
|
||||||
|
state = (SINK_STATE *) mymalloc(sizeof(*state));
|
||||||
|
SOCKADDR_TO_HOSTADDR(&sa, len, &state->client_addr,
|
||||||
|
(MAI_SERVPORT_STR *) 0, sa.sa_family);
|
||||||
if (msg_verbose)
|
if (msg_verbose)
|
||||||
msg_info("connect (%s)",
|
msg_info("connect (%s %s)",
|
||||||
#ifdef AF_LOCAL
|
#ifdef AF_LOCAL
|
||||||
sa.sa_family == AF_LOCAL ? "AF_LOCAL" :
|
sa.sa_family == AF_LOCAL ? "AF_LOCAL" :
|
||||||
#else
|
#else
|
||||||
@ -733,15 +1140,24 @@ static void connect_event(int unused_event, char *context)
|
|||||||
#ifdef AF_INET6
|
#ifdef AF_INET6
|
||||||
sa.sa_family == AF_INET6 ? "AF_INET6" :
|
sa.sa_family == AF_INET6 ? "AF_INET6" :
|
||||||
#endif
|
#endif
|
||||||
"unknown protocol family");
|
"unknown protocol family",
|
||||||
|
state->client_addr.buf);
|
||||||
non_blocking(fd, NON_BLOCKING);
|
non_blocking(fd, NON_BLOCKING);
|
||||||
state = (SINK_STATE *) mymalloc(sizeof(*state));
|
|
||||||
state->stream = vstream_fdopen(fd, O_RDWR);
|
state->stream = vstream_fdopen(fd, O_RDWR);
|
||||||
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, "");
|
PUSH_BACK_SET(state, "");
|
||||||
smtp_timeout_setup(state->stream, var_tmout);
|
smtp_timeout_setup(state->stream, var_tmout);
|
||||||
|
state->in_mail = 0;
|
||||||
|
state->rcpts = 0;
|
||||||
|
/* Initialize file capture attributes. */
|
||||||
|
state->addr_prefix = (sa.sa_family == AF_INET6 ? "ipv6:" : "");
|
||||||
|
state->helo_args = 0;
|
||||||
|
state->client_proto = enable_lmtp ? "LMTP" : "SMTP";
|
||||||
|
state->start_time = 0;
|
||||||
|
state->id = 0;
|
||||||
|
state->dump_file = 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We use the smtp_stream module to produce output. That module
|
* We use the smtp_stream module to produce output. That module
|
||||||
@ -780,12 +1196,11 @@ static void connect_event(int unused_event, char *context)
|
|||||||
|
|
||||||
static void usage(char *myname)
|
static void usage(char *myname)
|
||||||
{
|
{
|
||||||
msg_fatal("usage: %s [-468acCeEFLpPv] [-f commands] [-h hostname] [-n count] [-q commands] [-r commands] [-s commands] [-w delay] [host]:port backlog", myname);
|
msg_fatal("usage: %s [-468acCeEFLpPv] [-f commands] [-h hostname] [-m max_concurrency] [-n quit_count] [-q commands] [-r commands] [-s commands] [-w delay] [-d dump-template] [-D dump-template] [-S start-string] [host]:port backlog", myname);
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
int sock;
|
|
||||||
int backlog;
|
int backlog;
|
||||||
int ch;
|
int ch;
|
||||||
const char *protocols = INET_PROTO_NAME_ALL;
|
const char *protocols = INET_PROTO_NAME_ALL;
|
||||||
@ -804,7 +1219,7 @@ int main(int argc, char **argv)
|
|||||||
/*
|
/*
|
||||||
* Parse JCL.
|
* Parse JCL.
|
||||||
*/
|
*/
|
||||||
while ((ch = GETOPT(argc, argv, "468acCeEf:Fh:Ln:pPq:r:s:t:vw:")) > 0) {
|
while ((ch = GETOPT(argc, argv, "468acCeEf:Fh:Ln:m:pPq:r:s:S:t:vw:d:D:")) > 0) {
|
||||||
switch (ch) {
|
switch (ch) {
|
||||||
case '4':
|
case '4':
|
||||||
protocols = INET_PROTO_NAME_IPV4;
|
protocols = INET_PROTO_NAME_IPV4;
|
||||||
@ -825,6 +1240,12 @@ int main(int argc, char **argv)
|
|||||||
disable_xclient = 1;
|
disable_xclient = 1;
|
||||||
reset_cmd_flags("xclient", FLAG_ENABLE);
|
reset_cmd_flags("xclient", FLAG_ENABLE);
|
||||||
break;
|
break;
|
||||||
|
case 'd':
|
||||||
|
single_template = optarg;
|
||||||
|
break;
|
||||||
|
case 'D':
|
||||||
|
shared_template = optarg;
|
||||||
|
break;
|
||||||
case 'e':
|
case 'e':
|
||||||
disable_esmtp = 1;
|
disable_esmtp = 1;
|
||||||
break;
|
break;
|
||||||
@ -845,9 +1266,13 @@ int main(int argc, char **argv)
|
|||||||
case 'L':
|
case 'L':
|
||||||
enable_lmtp = 1;
|
enable_lmtp = 1;
|
||||||
break;
|
break;
|
||||||
|
case 'm':
|
||||||
|
if ((max_client_count = atoi(optarg)) <= 0)
|
||||||
|
msg_fatal("bad concurrency limit: %s", optarg);
|
||||||
|
break;
|
||||||
case 'n':
|
case 'n':
|
||||||
if ((max_quit_count = atoi(optarg)) <= 0)
|
if ((max_quit_count = atoi(optarg)) <= 0)
|
||||||
msg_fatal("bad count: %s", optarg);
|
msg_fatal("bad quit count: %s", optarg);
|
||||||
break;
|
break;
|
||||||
case 'p':
|
case 'p':
|
||||||
disable_pipelining = 1;
|
disable_pipelining = 1;
|
||||||
@ -867,6 +1292,10 @@ int main(int argc, char **argv)
|
|||||||
openlog(basename(argv[0]), LOG_PID, LOG_MAIL);
|
openlog(basename(argv[0]), LOG_PID, LOG_MAIL);
|
||||||
set_cmds_flags(optarg, FLAG_SYSLOG);
|
set_cmds_flags(optarg, FLAG_SYSLOG);
|
||||||
break;
|
break;
|
||||||
|
case 'S':
|
||||||
|
start_string = vstring_alloc(10);
|
||||||
|
unescape(start_string, optarg);
|
||||||
|
break;
|
||||||
case 't':
|
case 't':
|
||||||
if ((var_tmout = atoi(optarg)) <= 0)
|
if ((var_tmout = atoi(optarg)) <= 0)
|
||||||
msg_fatal("bad timeout: %s", optarg);
|
msg_fatal("bad timeout: %s", optarg);
|
||||||
@ -886,6 +1315,8 @@ int main(int argc, char **argv)
|
|||||||
usage(argv[0]);
|
usage(argv[0]);
|
||||||
if ((backlog = atoi(argv[optind + 1])) <= 0)
|
if ((backlog = atoi(argv[optind + 1])) <= 0)
|
||||||
usage(argv[0]);
|
usage(argv[0]);
|
||||||
|
if (single_template && shared_template)
|
||||||
|
msg_fatal("use only one of -d or -D, but not both");
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Initialize.
|
* Initialize.
|
||||||
@ -904,10 +1335,15 @@ int main(int argc, char **argv)
|
|||||||
sock = inet_listen(argv[optind], backlog, BLOCKING);
|
sock = inet_listen(argv[optind], backlog, BLOCKING);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (single_template)
|
||||||
|
mysrand((int) time((time_t *) 0));
|
||||||
|
else if (shared_template)
|
||||||
|
single_template = shared_template;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Start the event handler.
|
* Start the event handler.
|
||||||
*/
|
*/
|
||||||
event_enable_read(sock, connect_event, CAST_INT_TO_CHAR_PTR(sock));
|
event_enable_read(sock, connect_event, (char *) 0);
|
||||||
for (;;)
|
for (;;)
|
||||||
event_loop(-1);
|
event_loop(-1);
|
||||||
}
|
}
|
||||||
|
@ -17,6 +17,9 @@
|
|||||||
/* Connections can be made to UNIX-domain and IPv4 or IPv6 servers.
|
/* Connections can be made to UNIX-domain and IPv4 or IPv6 servers.
|
||||||
/* IPv4 and IPv6 are the default.
|
/* IPv4 and IPv6 are the default.
|
||||||
/*
|
/*
|
||||||
|
/* Note: this is an unsupported test program. No attempt is made
|
||||||
|
/* to maintain compatibility between successive versions.
|
||||||
|
/*
|
||||||
/* Arguments:
|
/* Arguments:
|
||||||
/* .IP \fB-4\fR
|
/* .IP \fB-4\fR
|
||||||
/* Connect to the server with IPv4. This option has no effect when
|
/* Connect to the server with IPv4. This option has no effect when
|
||||||
@ -510,7 +513,7 @@ static void send_helo(SESSION *session)
|
|||||||
* Send the standard greeting with our hostname
|
* Send the standard greeting with our hostname
|
||||||
*/
|
*/
|
||||||
if ((except = vstream_setjmp(session->stream)) != 0)
|
if ((except = vstream_setjmp(session->stream)) != 0)
|
||||||
msg_fatal("%s while sending HELO", exception_text(except));
|
msg_fatal("%s while sending %s", exception_text(except), protocol);
|
||||||
|
|
||||||
command(session->stream, "%s %s", protocol, var_myhostname);
|
command(session->stream, "%s %s", protocol, var_myhostname);
|
||||||
|
|
||||||
@ -528,15 +531,16 @@ static void helo_done(int unused_event, char *context)
|
|||||||
SESSION *session = (SESSION *) context;
|
SESSION *session = (SESSION *) context;
|
||||||
RESPONSE *resp;
|
RESPONSE *resp;
|
||||||
int except;
|
int except;
|
||||||
|
const char *protocol = (talk_lmtp ? "LHLO" : "HELO");
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Get response to HELO command.
|
* Get response to HELO command.
|
||||||
*/
|
*/
|
||||||
if ((except = vstream_setjmp(session->stream)) != 0)
|
if ((except = vstream_setjmp(session->stream)) != 0)
|
||||||
msg_fatal("%s while sending HELO", exception_text(except));
|
msg_fatal("%s while sending %s", exception_text(except), protocol);
|
||||||
|
|
||||||
if ((resp = response(session->stream, buffer))->code / 100 != 2)
|
if ((resp = response(session->stream, buffer))->code / 100 != 2)
|
||||||
msg_fatal("HELO rejected: %d %s", resp->code, resp->str);
|
msg_fatal("%s rejected: %d %s", protocol, resp->code, resp->str);
|
||||||
|
|
||||||
send_mail(session);
|
send_mail(session);
|
||||||
}
|
}
|
||||||
|
@ -15,6 +15,10 @@
|
|||||||
/* DIAGNOSTICS
|
/* DIAGNOSTICS
|
||||||
/* peekfd() returns -1 in case of trouble. The global \fIerrno\fR
|
/* peekfd() returns -1 in case of trouble. The global \fIerrno\fR
|
||||||
/* variable reflects the nature of the problem.
|
/* variable reflects the nature of the problem.
|
||||||
|
/* BUGS
|
||||||
|
/* On some systems, non-blocking read() may fail even after a
|
||||||
|
/* positive return from peekfd(). The smtp-sink program works
|
||||||
|
/* around this by using the readable() function instead.
|
||||||
/* LICENSE
|
/* LICENSE
|
||||||
/* .ad
|
/* .ad
|
||||||
/* .fi
|
/* .fi
|
||||||
|
@ -1049,8 +1049,9 @@ int vstream_fclose(VSTREAM *stream)
|
|||||||
*/
|
*/
|
||||||
if (stream->pid != 0)
|
if (stream->pid != 0)
|
||||||
msg_panic("vstream_fclose: stream has process");
|
msg_panic("vstream_fclose: stream has process");
|
||||||
if ((stream->buf.flags & VSTREAM_FLAG_WRITE_DOUBLE) != 0)
|
if ((stream->buf.flags & VSTREAM_FLAG_WRITE_DOUBLE) != 0 && stream->fd >= 0)
|
||||||
vstream_fflush(stream);
|
vstream_fflush(stream);
|
||||||
|
/* Do not remove: vstream_fdclose() depends on this error test. */
|
||||||
err = vstream_ferror(stream);
|
err = vstream_ferror(stream);
|
||||||
if (stream->buf.flags & VSTREAM_FLAG_DOUBLE) {
|
if (stream->buf.flags & VSTREAM_FLAG_DOUBLE) {
|
||||||
if (stream->read_fd >= 0)
|
if (stream->read_fd >= 0)
|
||||||
@ -1079,8 +1080,22 @@ int vstream_fclose(VSTREAM *stream)
|
|||||||
|
|
||||||
int vstream_fdclose(VSTREAM *stream)
|
int vstream_fdclose(VSTREAM *stream)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Flush unwritten output, just like vstream_fclose(). Errors are
|
||||||
|
* reported by vstream_fclose().
|
||||||
|
*/
|
||||||
|
if ((stream->buf.flags & VSTREAM_FLAG_WRITE_DOUBLE) != 0)
|
||||||
|
(void) vstream_fflush(stream);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* NOTE: Negative file descriptors are not part of the external
|
||||||
|
* interface. They are for internal use only, in order to support
|
||||||
|
* vstream_fdclose() without a lot of code duplication. Applications that
|
||||||
|
* rely on negative VSTREAM file descriptors will break without warning.
|
||||||
|
*/
|
||||||
if (stream->buf.flags & VSTREAM_FLAG_DOUBLE) {
|
if (stream->buf.flags & VSTREAM_FLAG_DOUBLE) {
|
||||||
stream->read_fd = stream->write_fd = -1;
|
stream->fd = stream->read_fd = stream->write_fd = -1;
|
||||||
} else {
|
} else {
|
||||||
stream->fd = -1;
|
stream->fd = -1;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user