2
0
mirror of https://github.com/vdukhovni/postfix synced 2025-08-31 06:05:37 +00:00

postfix-2.3-RC5

This commit is contained in:
Wietse Venema
2006-07-04 00:00:00 -05:00
committed by Viktor Dukhovni
parent c79abe8c8c
commit 2b4310b330
12 changed files with 96 additions and 65 deletions

View File

@@ -12445,6 +12445,11 @@ Apologies for any names omitted.
Compatibility: with OpenBSD 2.7 and later, the alias file Compatibility: with OpenBSD 2.7 and later, the alias file
is now in /etc/mail/aliases. is now in /etc/mail/aliases.
20060704
Bugfix: the Milter client skipped zero-length body lines.
File: milter/milter8.c.
Wish list: Wish list:
In the SMTPD policy client (encode or strip) non-printable In the SMTPD policy client (encode or strip) non-printable

View File

@@ -125,7 +125,11 @@ RRuunnnniinngg MMiilltteerr aapppplliiccaattiioonnss
To run a Milter application, see the documentation of the filter for options. A To run a Milter application, see the documentation of the filter for options. A
typical command looks like this: typical command looks like this:
$ //ssoommee//wwhheerree//ddkk--ffiilltteerr --pp iinneett::ppoorrttnnuummbbeerr@@llooccaallhhoosstt ......ootthheerr ooppttiioonnss...... # //ssoommee//wwhheerree//ddkk--ffiilltteerr --uu uusseerriidd --pp iinneett::ppoorrttnnuummbbeerr@@llooccaallhhoosstt ......ootthheerr
ooppttiioonnss......
Please specify a userid value that isn't used for other applications (not
"postfix", not "www", etc.).
CCoonnffiigguurriinngg PPoossttffiixx CCoonnffiigguurriinngg PPoossttffiixx

View File

@@ -257,10 +257,13 @@ for options. A typical command looks like this:</p>
<blockquote> <blockquote>
<pre> <pre>
$ <b>/some/where/dk-filter -p inet:<i>portnumber</i>@localhost ...<i>other options</i>...</b> # <b>/some/where/dk-filter -u <i>userid</i> -p inet:<i>portnumber</i>@localhost ...<i>other options</i>...</b>
</pre> </pre>
</blockquote> </blockquote>
<p> Please specify a <i>userid</i> value that isn't used for other
applications (not "postfix", not "www", etc.). </p>
<h2><a name="config">Configuring Postfix</a></h2> <h2><a name="config">Configuring Postfix</a></h2>
<p> Like Sendmail, Postfix has a lot of configuration options that <p> Like Sendmail, Postfix has a lot of configuration options that

View File

@@ -16,7 +16,7 @@ MASTER(5) MASTER(5)
Postfix services are implemented by daemon processes. Postfix services are implemented by daemon processes.
These run in the background under control of the <a href="master.8.html"><b>master</b>(8)</a> These run in the background under control of the <a href="master.8.html"><b>master</b>(8)</a>
process. The master.cf configuration file defines how a process. The <a href="master.5.html">master.cf</a> configuration file defines how a
client program connects to a service, and what daemon pro- client program connects to a service, and what daemon pro-
gram runs when a service is requested. Most daemon pro- gram runs when a service is requested. Most daemon pro-
cesses are short-lived and terminate after serving <b><a href="postconf.5.html#max_use">max_use</a></b> cesses are short-lived and terminate after serving <b><a href="postconf.5.html#max_use">max_use</a></b>
@@ -28,17 +28,17 @@ MASTER(5) MASTER(5)
<a href="local.8.html"><b>local</b>(8)</a>, <a href="pipe.8.html"><b>pipe</b>(8)</a> or <a href="spawn.8.html"><b>spawn</b>(8)</a> services, or run the server <a href="local.8.html"><b>local</b>(8)</a>, <a href="pipe.8.html"><b>pipe</b>(8)</a> or <a href="spawn.8.html"><b>spawn</b>(8)</a> services, or run the server
under control by <b>inetd</b>(8) or equivalent. under control by <b>inetd</b>(8) or equivalent.
After changing master.cf you must execute "<b>postfix reload</b>" After changing <a href="master.5.html">master.cf</a> you must execute "<b>postfix reload</b>"
to reload the configuration. to reload the configuration.
<b>SYNTAX</b> <b>SYNTAX</b>
The general format of the master.cf file is as follows: The general format of the <a href="master.5.html">master.cf</a> file is as follows:
<b>o</b> Each logical line defines a single Postfix service. <b>o</b> Each logical line defines a single Postfix service.
Each service is identified by its name and type as Each service is identified by its name and type as
described below. When multiple lines specify the described below. When multiple lines specify the
same service name and type, only the last one is same service name and type, only the last one is
remembered. Otherwise, the order of master.cf ser- remembered. Otherwise, the order of <a href="master.5.html">master.cf</a> ser-
vice definitions does not matter. vice definitions does not matter.
<b>o</b> Empty lines and whitespace-only lines are ignored, <b>o</b> Empty lines and whitespace-only lines are ignored,
@@ -51,7 +51,7 @@ MASTER(5) MASTER(5)
Each logical line consists of eight fields separated by Each logical line consists of eight fields separated by
whitespace. These are described below in the order as whitespace. These are described below in the order as
they appear in the master.cf file. they appear in the <a href="master.5.html">master.cf</a> file.
Where applicable a field of "-" requests that the built-in Where applicable a field of "-" requests that the built-in
default value be used. For boolean fields specify "y" or default value be used. For boolean fields specify "y" or
@@ -86,9 +86,9 @@ MASTER(5) MASTER(5)
Note: with Postfix version 2.2 and later Note: with Postfix version 2.2 and later
specify "<b><a href="postconf.5.html#inet_interfaces">inet_interfaces</a> = loopback-only</b>" in specify "<b><a href="postconf.5.html#inet_interfaces">inet_interfaces</a> = loopback-only</b>" in
main.cf, instead of hard-coding loopback IP <a href="postconf.5.html">main.cf</a>, instead of hard-coding loopback IP
address information in master.cf or in address information in <a href="master.5.html">master.cf</a> or in
main.cf. <a href="postconf.5.html">main.cf</a>.
<b>unix</b> The service listens on a UNIX-domain socket <b>unix</b> The service listens on a UNIX-domain socket
and is accessible for local clients only. and is accessible for local clients only.
@@ -96,7 +96,7 @@ MASTER(5) MASTER(5)
The service name is a pathname relative to The service name is a pathname relative to
the Postfix queue directory (pathname con- the Postfix queue directory (pathname con-
trolled with the <b><a href="postconf.5.html#queue_directory">queue_directory</a></b> configura- trolled with the <b><a href="postconf.5.html#queue_directory">queue_directory</a></b> configura-
tion parameter in main.cf). tion parameter in <a href="postconf.5.html">main.cf</a>).
On Solaris systems the <b>unix</b> type is imple- On Solaris systems the <b>unix</b> type is imple-
mented with streams sockets. mented with streams sockets.
@@ -107,7 +107,7 @@ MASTER(5) MASTER(5)
The service name is a pathname relative to The service name is a pathname relative to
the Postfix queue directory (pathname con- the Postfix queue directory (pathname con-
trolled with the <b><a href="postconf.5.html#queue_directory">queue_directory</a></b> configura- trolled with the <b><a href="postconf.5.html#queue_directory">queue_directory</a></b> configura-
tion parameter in main.cf). tion parameter in <a href="postconf.5.html">main.cf</a>).
<b>Private (default: y)</b> <b>Private (default: y)</b>
Whether or not access is restricted to the mail Whether or not access is restricted to the mail
@@ -118,7 +118,7 @@ MASTER(5) MASTER(5)
Whether the service runs with root privileges or as Whether the service runs with root privileges or as
the owner of the Postfix system (the owner name is the owner of the Postfix system (the owner name is
controlled by the <b><a href="postconf.5.html#mail_owner">mail_owner</a></b> configuration variable controlled by the <b><a href="postconf.5.html#mail_owner">mail_owner</a></b> configuration variable
in the main.cf file). in the <a href="postconf.5.html">main.cf</a> file).
The <a href="local.8.html"><b>local</b>(8)</a>, <a href="pipe.8.html"><b>pipe</b>(8)</a>, <a href="spawn.8.html"><b>spawn</b>(8)</a>, and <a href="virtual.8.html"><b>virtual</b>(8)</a> The <a href="local.8.html"><b>local</b>(8)</a>, <a href="pipe.8.html"><b>pipe</b>(8)</a>, <a href="spawn.8.html"><b>spawn</b>(8)</a>, and <a href="virtual.8.html"><b>virtual</b>(8)</a>
daemons require privileges. daemons require privileges.
@@ -127,7 +127,7 @@ MASTER(5) MASTER(5)
Whether or not the service runs chrooted to the Whether or not the service runs chrooted to the
mail queue directory (pathname is controlled by the mail queue directory (pathname is controlled by the
<b><a href="postconf.5.html#queue_directory">queue_directory</a></b> configuration variable in the <b><a href="postconf.5.html#queue_directory">queue_directory</a></b> configuration variable in the
main.cf file). <a href="postconf.5.html">main.cf</a> file).
Chroot should not be used with the <a href="local.8.html"><b>local</b>(8)</a>, Chroot should not be used with the <a href="local.8.html"><b>local</b>(8)</a>,
<a href="pipe.8.html"><b>pipe</b>(8)</a>, <a href="spawn.8.html"><b>spawn</b>(8)</a>, and <a href="virtual.8.html"><b>virtual</b>(8)</a> daemons. <a href="pipe.8.html"><b>pipe</b>(8)</a>, <a href="spawn.8.html"><b>spawn</b>(8)</a>, and <a href="virtual.8.html"><b>virtual</b>(8)</a> daemons.
@@ -136,9 +136,9 @@ MASTER(5) MASTER(5)
service in the first place. service in the first place.
The files in the examples/chroot-setup subdirectory The files in the examples/chroot-setup subdirectory
of the Postfix source archive describe how to set of the Postfix source archive can be used to set up
up a Postfix chroot environment for your type of a Postfix chroot environment on a variety of sys-
machine, and <a href="BASIC_CONFIGURATION_README.html">BASIC_CONFIGURATION_README</a> discusses tems. See also <a href="BASIC_CONFIGURATION_README.html">BASIC_CONFIGURATION_README</a> for
issues related to running daemons chrooted. issues related to running daemons chrooted.
<b>Wake up time (default: 0)</b> <b>Wake up time (default: 0)</b>
@@ -146,9 +146,9 @@ MASTER(5) MASTER(5)
specified number of seconds. The wake up is imple- specified number of seconds. The wake up is imple-
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 wake up events be sent time field requests that no wake up events be sent
only to services that are actually being used. before the service is used. Specify 0 for no auto-
Specify 0 for no automatic wake up. matic 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.
@@ -182,21 +182,21 @@ MASTER(5) MASTER(5)
<b>-D</b> Run the daemon under control by the command <b>-D</b> Run the daemon under control by the command
specified with the <b><a href="postconf.5.html#debugger_command">debugger_command</a></b> variable specified with the <b><a href="postconf.5.html#debugger_command">debugger_command</a></b> variable
in the main.cf configuration file. See in the <a href="postconf.5.html">main.cf</a> configuration file. See
<a href="DEBUG_README.html">DEBUG_README</a> for hints and tips. <a href="DEBUG_README.html">DEBUG_README</a> for hints and tips.
<b>-o</b> <i>name</i>=<i>value</i> <b>-o</b> <i>name</i>=<i>value</i>
Override the named main.cf configuration Override the named <a href="postconf.5.html">main.cf</a> configuration
parameter. The parameter value can refer to parameter. The parameter value can refer to
other parameters as <i>$name</i> etc., just like in other parameters as <i>$name</i> etc., just like in
main.cf. See <a href="postconf.5.html"><b>postconf</b>(5)</a> for syntax. <a href="postconf.5.html">main.cf</a>. See <a href="postconf.5.html"><b>postconf</b>(5)</a> for syntax.
NOTE 1: do not specify whitespace around the NOTE 1: do not specify whitespace around the
"=". In parameter values, either avoid "=". In parameter values, either avoid
whitespace altogether, use commas instead of whitespace altogether, use commas instead of
spaces, or consider overrides like "-o spaces, or consider overrides like "-o
name=$override_parameter" with $over- name=$override_parameter" with $over-
ride_parameter set in main.cf. ride_parameter set in <a href="postconf.5.html">main.cf</a>.
NOTE 2: Over-zealous use of parameter over- NOTE 2: Over-zealous use of parameter over-
rides makes the Postfix configuration hard rides makes the Postfix configuration hard

View File

@@ -126,16 +126,16 @@ most of the purpose of having that service in the first
place. place.
.sp .sp
The files in the examples/chroot-setup subdirectory of the The files in the examples/chroot-setup subdirectory of the
Postfix source archive describe how to set up a Postfix Postfix source archive can be used to set up a Postfix
chroot environment for your type of machine, and chroot environment on a variety of systems. See also
BASIC_CONFIGURATION_README discusses issues related to BASIC_CONFIGURATION_README for issues related to running
running daemons chrooted. daemons chrooted.
.IP "\fBWake up time (default: 0)\fR" .IP "\fBWake up time (default: 0)\fR"
Automatically wake up the named service after the specified 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 wake up events end of the wake-up time field requests that no wake up
be sent only to services that are actually being used. events be sent before the 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)

View File

@@ -257,10 +257,13 @@ for options. A typical command looks like this:</p>
<blockquote> <blockquote>
<pre> <pre>
$ <b>/some/where/dk-filter -p inet:<i>portnumber</i>@localhost ...<i>other options</i>...</b> # <b>/some/where/dk-filter -u <i>userid</i> -p inet:<i>portnumber</i>@localhost ...<i>other options</i>...</b>
</pre> </pre>
</blockquote> </blockquote>
<p> Please specify a <i>userid</i> value that isn't used for other
applications (not "postfix", not "www", etc.). </p>
<h2><a name="config">Configuring Postfix</a></h2> <h2><a name="config">Configuring Postfix</a></h2>
<p> Like Sendmail, Postfix has a lot of configuration options that <p> Like Sendmail, Postfix has a lot of configuration options that

View File

@@ -120,16 +120,16 @@
# place. # place.
# .sp # .sp
# The files in the examples/chroot-setup subdirectory of the # The files in the examples/chroot-setup subdirectory of the
# Postfix source archive describe how to set up a Postfix # Postfix source archive can be used to set up a Postfix
# chroot environment for your type of machine, and # chroot environment on a variety of systems. See also
# BASIC_CONFIGURATION_README discusses issues related to # BASIC_CONFIGURATION_README for issues related to running
# running daemons chrooted. # daemons chrooted.
# .IP "\fBWake up time (default: 0)\fR" # .IP "\fBWake up time (default: 0)\fR"
# Automatically wake up the named service after the specified # 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 wake up events # end of the wake-up time field requests that no wake up
# be sent only to services that are actually being used. # events be sent before the 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)

View File

@@ -37,35 +37,32 @@
/* local call-back functions for macro expansion and for queue /* local call-back functions for macro expansion and for queue
/* file modification. /* file modification.
/* /*
/* cleanup_milter_inspect() subjects a message to inspection /* cleanup_milter_inspect() sends the current message headers
/* by mail filters. Each filter can accept or reject the message /* and body to the mail filters that were received with
/* and can request changes to the recipient list, to message /* cleanup_milter_receive(), or that are specified with the
/* headers, and to replace the message body. /* cleanup_milters configuration parameter.
/* /*
/* cleanup_milter_emul_mail() emulates connect, helo and mail /* cleanup_milter_emul_mail() emulates connect, helo and mail
/* events for mail that does not arrive via the smtpd(8) server. /* events for mail that does not arrive via the smtpd(8) server.
/* This pretends that mail arrives from localhost/127.0.0.1 /* The emulation pretends that mail arrives from localhost/127.0.0.1
/* via ESMTP. This code reports a server configuration error /* via ESMTP. Milters can reject emulated connect, helo, mail
/* condition when the milter rejects the emulated commands. /* or data events, but not emulated rcpt events as described
/* next.
/* /*
/* cleanup_milter_emul_rcpt() emulates an rcpt() event for /* cleanup_milter_emul_rcpt() emulates an rcpt event for mail
/* non-SMTP mail. See cleanup_milter_emul_mail() for the /* that does not arrive via the smtpd(8) server. This reports
/* handling of reject replies. /* a server configuration error condition when the milter
/* rejects an emulated rcpt event.
/* /*
/* cleanup_milter_emul_data() emulates a data event for non-SMTP /* cleanup_milter_emul_data() emulates a data event for mail
/* mail. See cleanup_milter_emul_mail() for the handling of /* that does not arrive via the smtpd(8) server. It's OK for
/* reject replies. /* milters to reject emulated data events.
/* SEE ALSO /* SEE ALSO
/* milter(3) generic mail filter interface /* milter(3) generic mail filter interface
/* BUGS
/* Postfix prepends its own Received: header when it receives
/* mail from outside, or when it forwards mail internally.
/* This header is seen by mail filters, and is present when
/* mail filters edit the queue file.
/* DIAGNOSTICS /* DIAGNOSTICS
/* Fatal errors: memory allocation problem. /* Fatal errors: memory allocation problem.
/* Panic: interface violation. /* Panic: interface violation.
/* state->errs is updated in case of I/O errors. /* Warnings: I/O errors (state->errs is updated accordingly).
/* LICENSE /* LICENSE
/* .ad /* .ad
/* .fi /* .fi
@@ -226,14 +223,24 @@ static void cleanup_milter_set_error(CLEANUP_STATE *state, int err)
static const char *cleanup_milter_error(CLEANUP_STATE *state, int err) static const char *cleanup_milter_error(CLEANUP_STATE *state, int err)
{ {
const char *myname = "cleanup_milter_error";
/* /*
* This error text will be ignored by cleanup_milter_apply(). It exists * For consistency with error reporting within the milter infrastructure,
* only to maintain a consistent error reporting interface to the milter * content manipulation routines return a null pointer on success, and an
* infrastructure. * SMTP-like response on error.
*
* However, when cleanup_milter_apply() receives this error response from
* the milter infrastructure, it ignores the text since the appropriate
* cleanup error flags were already set by cleanup_milter_set_error().
*
* Specify a null error number when the "errno to error flag" mapping was
* already done elsewhere, possibly outside this module.
*/ */
if (err) if (err)
cleanup_milter_set_error(state, err); cleanup_milter_set_error(state, err);
else if (CLEANUP_OUT_OK(state))
msg_panic("%s: missing errno to error flag mapping", myname);
return ("451 4.3.0 Server internal error"); return ("451 4.3.0 Server internal error");
} }
@@ -404,7 +411,7 @@ static off_t cleanup_find_header(CLEANUP_STATE *state, ssize_t index,
if ((rec_type = rec_get_raw(state->dst, buf, 0, REC_FLAG_NONE)) < 0) { \ if ((rec_type = rec_get_raw(state->dst, buf, 0, REC_FLAG_NONE)) < 0) { \
msg_warn("%s: read file %s: %m", myname, cleanup_path); \ msg_warn("%s: read file %s: %m", myname, cleanup_path); \
cleanup_milter_set_error(state, errno); \ cleanup_milter_set_error(state, errno); \
quit; \ do { quit; } while (0); \
} \ } \
if (msg_verbose > 1) \ if (msg_verbose > 1) \
msg_info("%s: read: %ld: %.*s", myname, (long) curr_offset, \ msg_info("%s: read: %ld: %.*s", myname, (long) curr_offset, \
@@ -1055,7 +1062,8 @@ static const char *cleanup_del_rcpt(void *context, char *rcpt)
* but to match against the expanded and rewritten recipient address. * but to match against the expanded and rewritten recipient address.
* *
* XXX Remove the (dsn_orcpt, dsn_notify, orcpt, recip) tuple from the * XXX Remove the (dsn_orcpt, dsn_notify, orcpt, recip) tuple from the
* duplicate recipient filter. * duplicate recipient filter. This requires that we maintain reference
* counts.
*/ */
if (vstream_fseek(state->dst, 0L, SEEK_SET) < 0) { if (vstream_fseek(state->dst, 0L, SEEK_SET) < 0) {
msg_warn("%s: seek file %s: %m", myname, cleanup_path); msg_warn("%s: seek file %s: %m", myname, cleanup_path);

View File

@@ -20,8 +20,8 @@
* 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 "20060703" #define MAIL_RELEASE_DATE "20060704"
#define MAIL_VERSION_NUMBER "2.3-RC4" #define MAIL_VERSION_NUMBER "2.3-RC5"
#define VAR_MAIL_VERSION "mail_version" #define VAR_MAIL_VERSION "mail_version"
#define DEF_MAIL_VERSION MAIL_VERSION_NUMBER #define DEF_MAIL_VERSION MAIL_VERSION_NUMBER

View File

@@ -67,7 +67,7 @@ milter: milter.c $(LIB) $(LIBS)
mv junk $@.o mv junk $@.o
test-milter: test-milter.c test-milter: test-milter.c
cc -o $@ $? -lmilter -lpthread cc -g -o $@ $? -lmilter -lpthread
depend: $(MAKES) depend: $(MAKES)
(sed '1,/^# do not edit/!d' Makefile.in; \ (sed '1,/^# do not edit/!d' Makefile.in; \

View File

@@ -1997,6 +1997,12 @@ static void milter8_body(void *ptr, int rec_type,
*/ */
if (msg_verbose > 1) if (msg_verbose > 1)
msg_info("%s: body milter %s: %.100s", myname, milter->m.name, buf); msg_info("%s: body milter %s: %.100s", myname, milter->m.name, buf);
/* To append \r\n, simply redirect input to another buffer. */
if (rec_type == REC_TYPE_NORM && todo == 0) {
bp = "\r\n";
todo = 2;
rec_type = REC_TYPE_EOF;
}
while (todo > 0) { while (todo > 0) {
/* Append one REC_TYPE_NORM or REC_TYPE_CONT to body chunk buffer. */ /* Append one REC_TYPE_NORM or REC_TYPE_CONT to body chunk buffer. */
space = MILTER_CHUNK_SIZE - LEN(milter->body); space = MILTER_CHUNK_SIZE - LEN(milter->body);

View File

@@ -106,6 +106,8 @@ static char *chg_val;
static int test_reply(SMFICTX *ctx, int code) static int test_reply(SMFICTX *ctx, int code)
{ {
(void) fflush(stdout); /* In case output redirected. */
if (code == SMFIR_REPLYCODE) { if (code == SMFIR_REPLYCODE) {
if (smfi_setreply(ctx, reply_code, reply_dsn, reply_message) != MI_SUCCESS) if (smfi_setreply(ctx, reply_code, reply_dsn, reply_message) != MI_SUCCESS)
fprintf(stderr, "smfi_setreply failed\n"); fprintf(stderr, "smfi_setreply failed\n");
@@ -205,7 +207,7 @@ static sfsistat test_body(SMFICTX *ctx, unsigned char *data, size_t data_len)
if (verbose == 0) if (verbose == 0)
printf("test_body %ld bytes\n", (long) data_len); printf("test_body %ld bytes\n", (long) data_len);
else else
printf("%*s", data_len, data); printf("%.*s", data_len, data);
return (test_reply(ctx, test_body_reply)); return (test_reply(ctx, test_body_reply));
} }