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

postfix-2.0.9-20030519

This commit is contained in:
Wietse Venema
2003-05-19 00:00:00 -05:00
committed by Viktor Dukhovni
parent cf574a300d
commit eb8dcde50b
30 changed files with 217 additions and 70 deletions

View File

@@ -8047,6 +8047,43 @@ Apologies for any names omitted.
Patrik Rak's clever queue manager scheduler (nqmgr). Files:
conf/sample-scheduler.cf, README_FILES/SCHEDULER_README.
20030429
Bugfix: while verifying an address, the LMTP client entered
a forbidden "next" sender state after the last recipient.
Fix by Vladimir Davydoff. File: lmtp/lmtp_proto.c.
Bugfix: proxymap server did not parse "," as space.
Leandro Santi. File: proxymap/proxymap.c.
20030502
Bugfix: defer delivery after .forward etc. file read error.
File: local/token.c.
20030503
Bugfix: the Postfix LMTP client used the wrong service
name, causing trouble with SASL 2.1.13. Daniel Schales,
Louisiana Tech. File: lmtp/lmtp_sasl_glue.c.
20030518
Workaround: IRIX select() reports that a non-blocking file
descriptor is writable while write() transfers zero bytes.
File: util/vstream.c.
20030519
Feature: new require_{date,from,message_id,received}_header
restriction to reject SMTP mail when some message header
is missing. Only the From: and Date: headers are actually
required by Internet mail standards; the Received: and
Message-ID: headers are optional, but these are often
missing from SPAM email. Files: global/cleanup_user.h,
global/cleanup_strerror.c, smtpd/smtpd_check.c,
cleanup/cleanup_message.c.
Open problems:
Low: smtp-source may block when sending large test messages.

View File

@@ -28,43 +28,43 @@ Initially the list of address classes is hard coded, but this is
meant to become extensible:
-------------------------------------------------------------------
Class Description
Class Description
-------------------------------------------------------------------
local For UNIX accounts and for traditional /etc/aliases
Domain names are listed in $mydestination (or match the IP
address listed with $inet_interfaces)
Known recipients are listed in $local_recipient_maps (this
information is currently used by the Postfix SMTP server
only; if $local_recipient_maps is empty, the Postfix
SMTP server accepts all recipients)
Default delivery agent: local
local For UNIX accounts and for traditional /etc/aliases
Domain names are listed in $mydestination (or match the IP
address listed with $inet_interfaces)
Known recipients are listed in $local_recipient_maps (this
information is currently used by the Postfix SMTP server
only; if $local_recipient_maps is empty, the Postfix
SMTP server accepts all recipients)
Default delivery agent: local
virtual For hosted domains that are aliased to mailboxes in other
alias domains
Known recipients are listed in $virtual_alias_maps (default
is $virtual_maps for Postfix 1.1 compatibility)
Domain names are listed in $virtual_alias_domains (default
is $virtual_alias_maps for Postfix 1.1 compatibility)
alias domains
Known recipients are listed in $virtual_alias_maps (default
is $virtual_maps for Postfix 1.1 compatibility)
Domain names are listed in $virtual_alias_domains (default
is $virtual_alias_maps for Postfix 1.1 compatibility)
virtual For hosted domains with their own mailboxes
mailbox Known recipients are listed in $virtual_mailbox_maps (if
this parameter is empty, the Postfix SMTP server accepts
all recipients for domains listed in $virtual_mailbox_domains)
Domain names are listed in $virtual_mailbox_domains (default
is $virtual_mailbox_maps for Postfix 1.1 compatibility)
Default delivery agent: virtual
virtual For hosted domains with their own mailboxes
mailbox Known recipients are listed in $virtual_mailbox_maps (if
this parameter is empty, the Postfix SMTP server accepts
all recipients for domains listed in $virtual_mailbox_domains)
Domain names are listed in $virtual_mailbox_domains (default
is $virtual_mailbox_maps for Postfix 1.1 compatibility)
Default delivery agent: virtual
relay For remote destinations that list your system as MX host
Domain names are listed in $relay_domains
Known recipients are listed in $relay_recipient_maps (if
this parameter is empty, the Postfix SMTP server accepts
all recipients for domains listed in $relay_domains)
Default delivery agent: relay (clone of default smtp agent)
relay For remote destinations that list your system as MX host
Domain names are listed in $relay_domains
Known recipients are listed in $relay_recipient_maps (if
this parameter is empty, the Postfix SMTP server accepts
all recipients for domains listed in $relay_domains)
Default delivery agent: relay (clone of default smtp agent)
other Restricted to mail from authorized clients
Default delivery agent: smtp
No domain table
No recipient table
other Restricted to mail from authorized clients
Default delivery agent: smtp
No domain table
No recipient table
-------------------------------------------------------------------
Incompatibilities with Postfix 1.1
@@ -92,8 +92,7 @@ Incompatibilities with Postfix 1.1
- The local_recipient_maps feature is now turned on by default, so
that the Postfix SMTP server rejects mail for unknown local
recipients. This is enabled by default. See the LOCAL_RECIPIENT_README
file hints and tips.
recipients. See the LOCAL_RECIPIENT_README file hints and tips.
- Introduction of relay delivery transport in master.cf. This helps
to avoid mail delivery scheduling problems on inbound mail relays,

View File

@@ -236,8 +236,9 @@ program.
Note: the localhost port 10025 SMTP server filter should announce
itself as "220 localhost...". Postfix aborts delivery when it
connects to an SMTP server that uses the same hostname, because
that normally means you have a mail delivery loop problem.
connects to an SMTP server that uses the same hostname as Postfix
("host <servername> greeted me with my own hostname"), because that
normally means you have a mail delivery loop problem.
The example here assumes that the /some/where/filter command is a
PERL script. PERL has modules that make talking SMTP easy. The
@@ -280,9 +281,9 @@ mail.
The "-o local_recipient_maps=" and "-o relay_recipient_maps=" avoid
unnecessary table lookups.
The "-o myhostname=localhost.domain.tld" avoids a possible problem
if your content filter is based on a proxy that simply relays SMTP
commands.
The "-o myhostname=localhost.domain.tld" avoids false alarms ("host
<servername> greeted me with my own hostname") if your content
filter is based on a proxy that simply relays SMTP commands.
The "-o smtpd_xxx_restrictions" and "-o mynetworks=127.0.0.0/8"
turn off UCE controls that would only waste time here.

View File

@@ -13,10 +13,11 @@ The old Postfix scheduler had several limitations due to unfortunate
choices in its design.
1 - Round-robin selection by destination for mail that is delivered
via the same message delivery transport. That strategy broke
down when one single destination (say, inbound mail) had to
compete with multiple other destinations (say, outbound mail).
The poor suffering destination would be selected only
via the same message delivery transport. The round-robin strategy
was chosen with the intention to prevent a single (destination)
site from using up too many mail delivery resources. However,
that strategy penalized inbound mail on bi-directional gateways.
The poor suffering inbound destination would be selected only
1/number-of-destinations of the time, even when it had more
mail than other destinations, and thus mail could be delayed.
@@ -62,7 +63,7 @@ However, even from programmer's point of view, there is nothing
more to add to the message scheduling idea itself. There are few
things which make it look more complicated than it is, but the
algorithm is the same as the user percieves it. The summary of the
changes from the user's view:
differences of the programmer's view from the user's view are:
1) Simplification of terms for users: The user knows about messages
and recipients. The program itself works with jobs (one message is

View File

@@ -68,7 +68,7 @@ virtual_mailbox_domains
Specifies the list of domains that should be delivered to the
$virtual_transport delivery agent (default: virtual). As of
version 1.2, Postfix is smart enough that you don't have to
version 2.0, Postfix is smart enough that you don't have to
list every virtual domain in a Postfix transport map.
virtual_mailbox_maps

View File

@@ -1,8 +1,14 @@
#
# Postfix master process configuration file. Each line describes how
# a mailer component program should be run. The fields that make up
# each line are described below. A "-" field value requests that a
# default value be used for that field.
# Postfix master process configuration file. Each logical line
# describes how a Postfix daemon program should be run.
#
# A logical line starts with non-whitespace, non-comment text.
# Empty lines and whitespace-only lines are ignored, as are comment
# lines whose first non-whitespace character is a `#'.
# A line that starts with whitespace continues a logical line.
#
# The fields that make up each line are described below. A "-" field
# value requests that a default value be used for that field.
#
# Service: any name that is valid for the specified transport type
# (the next field). With INET transports, a service is specified as
@@ -59,12 +65,6 @@
# SPECIFY ONLY PROGRAMS THAT ARE WRITTEN TO RUN AS POSTFIX DAEMONS.
# ALL DAEMONS SPECIFIED HERE MUST SPEAK A POSTFIX-INTERNAL PROTOCOL.
#
# DO NOT CHANGE THE ZERO PROCESS LIMIT FOR CLEANUP/BOUNCE/DEFER OR
# POSTFIX WILL BECOME STUCK UP UNDER HEAVY LOAD
#
# DO NOT CHANGE THE ONE PROCESS LIMIT FOR PICKUP/QMGR OR POSTFIX WILL
# DELIVER MAIL MULTIPLE TIMES.
#
# DO NOT SHARE THE POSTFIX QUEUE BETWEEN MULTIPLE POSTFIX INSTANCES.
#
# ==========================================================================

View File

@@ -135,7 +135,7 @@
#
# EXAMPLE SMTPD ACCESS MAP
# # Protect your outgoing majordomo exploders
# /^(?!owner-)(.*)-outgoing@/ 550 Use ${1}@${2} instead
# /^(?!owner-)(.*)-outgoing@(.*)/ 550 Use ${1}@${2} instead
#
# # Bounce friend@whatever, except when whatever is our domain (you would
# # be better just bouncing all friend@ mail - this is just an example).

View File

@@ -66,4 +66,4 @@ strict_8bitmime = no
#
# This blocks mail from poorly written mail software.
#
strict_mime_domain_encoding = no
strict_mime_encoding_domain = no

View File

@@ -45,7 +45,7 @@
# Protect your outgoing majordomo exploders
#
/^(?!owner-)(.*)-outgoing@/ 550 Use ${1}@${2} instead
/^(?!owner-)(.*)-outgoing@(.*)/ 550 Use ${1}@${2} instead
# Bounce friend@whatever, except when whatever is our domain (you would

View File

@@ -30,4 +30,6 @@
/^postmaster@/ OK
# Protect your outgoing majordomo exploders
/^(.*)-outgoing@(.*)$/!/^owner-.*/ 550 Use ${1}@${2} instead
if !/^owner-.*/
/^(.*)-outgoing@(.*)$/ 550 Use ${1}@${2} instead
endif

View File

@@ -136,7 +136,7 @@ PCRE_TABLE(5) PCRE_TABLE(5)
<b>EXAMPLE</b> <b>SMTPD</b> <b>ACCESS</b> <b>MAP</b>
# Protect your outgoing majordomo exploders
/^(?!owner-)(.*)-outgoing@/ 550 Use ${1}@${2} instead
/^(?!owner-)(.*)-outgoing@(.*)/ 550 Use ${1}@${2} instead
# Bounce friend@whatever, except when whatever is our domain (you would
# be better just bouncing all friend@ mail - this is just an example).

View File

@@ -119,7 +119,7 @@ or $(n) if they aren't followed by whitespace.
.na
.nf
# Protect your outgoing majordomo exploders
/^(?!owner-)(.*)-outgoing@/ 550 Use ${1}@${2} instead
/^(?!owner-)(.*)-outgoing@(.*)/ 550 Use ${1}@${2} instead
# Bounce friend@whatever, except when whatever is our domain (you would
# be better just bouncing all friend@ mail - this is just an example).

View File

@@ -121,7 +121,7 @@ this also breaks majordomo approval requests when the included
request contains valid 8-bit MIME mail, and it breaks bounces from
mailers that do not properly encapsulate 8-bit content (for example,
bounces from qmail or from old versions of Postfix).
.IP \fBstrict_mime_domain_encoding\fR
.IP \fBstrict_mime_encoding_domain\fR
Reject mail with invalid \fBContent-Transfer-Encoding:\fR
information for message/* or multipart/*. This blocks mail
from poorly written software.

View File

@@ -111,7 +111,7 @@
# or $(n) if they aren't followed by whitespace.
# EXAMPLE SMTPD ACCESS MAP
# # Protect your outgoing majordomo exploders
# /^(?!owner-)(.*)-outgoing@/ 550 Use ${1}@${2} instead
# /^(?!owner-)(.*)-outgoing@(.*)/ 550 Use ${1}@${2} instead
#
# # Bounce friend@whatever, except when whatever is our domain (you would
# # be better just bouncing all friend@ mail - this is just an example).

View File

@@ -277,9 +277,6 @@ static void cleanup_service(VSTREAM *src, char *unused_service, char **argv)
* our status report.
*/
if (CLEANUP_OUT_OK(state) == 0 && type > 0) {
if ((state->errs & CLEANUP_STAT_CONT) == 0
&& (state->flags & CLEANUP_FLAG_DISCARD) == 0)
msg_warn("%s: skipping further client input", state->queue_id);
while (type != REC_TYPE_END
&& (type = rec_get(src, buf, 0)) > 0)
/* void */ ;

View File

@@ -132,6 +132,8 @@ static void cleanup_envelope_process(CLEANUP_STATE *state, int type,
return;
}
if (type == REC_TYPE_FLGS) {
if (msg_verbose)
msg_info("envelope %c %.*s", type, len, buf);
extra_flags = atol(buf);
if (extra_flags & ~CLEANUP_FLAG_MASK_EXTRA)
msg_warn("%s: bad extra flags: 0x%x", state->queue_id, extra_flags);

View File

@@ -493,6 +493,29 @@ static void cleanup_header_callback(void *context, int header_class,
}
}
/* cleanup_missing - handle missing message header */
static void cleanup_missing(CLEANUP_STATE *state, const char *resent,
const char *header)
{
const char *attr;
if ((attr = nvtable_find(state->attr, MAIL_ATTR_ORIGIN)) == 0)
attr = "unknown";
vstring_sprintf(state->temp1, "%s: reject: missing %s%s header from %s;",
state->queue_id, resent, header, attr);
if (state->sender)
vstring_sprintf_append(state->temp1, " from=<%s>", state->sender);
if (state->recip)
vstring_sprintf_append(state->temp1, " to=<%s>", state->recip);
if ((attr = nvtable_find(state->attr, MAIL_ATTR_PROTO_NAME)) != 0)
vstring_sprintf_append(state->temp1, " proto=%s", attr);
if ((attr = nvtable_find(state->attr, MAIL_ATTR_HELO_NAME)) != 0)
vstring_sprintf_append(state->temp1, " helo=<%s>", attr);
msg_info("%s", vstring_str(state->temp1));
state->errs |= CLEANUP_STAT_MISS_HDR;
}
/* cleanup_header_done_callback - insert missing message headers */
static void cleanup_header_done_callback(void *context)
@@ -502,6 +525,15 @@ static void cleanup_header_done_callback(void *context)
struct tm *tp;
TOK822 *token;
/*
* Postfix prepends a Received: message header, so we should see two when
* one is required.
*/
if ((state->flags & CLEANUP_FLAG_NEED_RCVD) && state->hop_count < 2) {
cleanup_missing(state, "", "Received");
return;
}
/*
* Add a missing (Resent-)Message-Id: header. The message ID gives the
* time in GMT units, plus the local queue ID.
@@ -513,6 +545,10 @@ static void cleanup_header_done_callback(void *context)
*/
if ((state->headers_seen & (1 << (state->resent[0] ?
HDR_RESENT_MESSAGE_ID : HDR_MESSAGE_ID))) == 0) {
if (state->flags & CLEANUP_FLAG_NEED_MSGID) {
cleanup_missing(state, state->resent, "Message-Id");
return;
}
tp = gmtime(&state->time);
strftime(time_stamp, sizeof(time_stamp), "%Y%m%d%H%M%S", tp);
cleanup_out_format(state, REC_TYPE_NORM, "%sMessage-Id: <%s.%s@%s>",
@@ -528,6 +564,10 @@ static void cleanup_header_done_callback(void *context)
*/
if ((state->headers_seen & (1 << (state->resent[0] ?
HDR_RESENT_DATE : HDR_DATE))) == 0) {
if (state->flags & CLEANUP_FLAG_NEED_DATE) {
cleanup_missing(state, state->resent, "Date");
return;
}
cleanup_out_format(state, REC_TYPE_NORM, "%sDate: %s",
state->resent, mail_date(state->time));
}
@@ -537,6 +577,10 @@ static void cleanup_header_done_callback(void *context)
*/
if ((state->headers_seen & (1 << (state->resent[0] ?
HDR_RESENT_FROM : HDR_FROM))) == 0) {
if (state->flags & CLEANUP_FLAG_NEED_FROM) {
cleanup_missing(state, state->resent, "From");
return;
}
quote_822_local(state->temp1, *state->sender ?
state->sender : MAIL_ADDR_MAIL_DAEMON);
vstring_sprintf(state->temp2, "%sFrom: %s",

View File

@@ -51,6 +51,7 @@ static struct cleanup_stat_map cleanup_stat_map[] = {
CLEANUP_STAT_BAD, "Internal protocol error",
CLEANUP_STAT_RCPT, "No recipients specified",
CLEANUP_STAT_HOPS, "Too many hops",
CLEANUP_STAT_MISS_HDR, "Missing message header",
CLEANUP_STAT_SIZE, "Message file too big",
CLEANUP_STAT_CONT, "Message content rejected",
CLEANUP_STAT_WRITE, "Error writing message file",

View File

@@ -20,13 +20,19 @@
#define CLEANUP_FLAG_HOLD (1<<2) /* Place message on hold */
#define CLEANUP_FLAG_DISCARD (1<<3) /* Discard message silently */
#define CLEANUP_FLAG_BCC_OK (1<<4) /* Ok to add auto-BCC addresses */
#define CLEANUP_FLAG_NEED_DATE (1<<5) /* Require (Resent:-)Date: */
#define CLEANUP_FLAG_NEED_FROM (1<<6) /* Require (Resent:-)From: */
#define CLEANUP_FLAG_NEED_MSGID (1<<7) /* Require (Resent:-)Message-Id: */
#define CLEANUP_FLAG_NEED_RCVD (1<<8) /* Require two Received: headers */
/*
* These are set on the fly while processing SMTP envelopes or message
* content.
*/
#define CLEANUP_FLAG_MASK_EXTRA \
(CLEANUP_FLAG_HOLD | CLEANUP_FLAG_DISCARD)
(CLEANUP_FLAG_HOLD | CLEANUP_FLAG_DISCARD | CLEANUP_FLAG_NEED_DATE | \
CLEANUP_FLAG_NEED_FROM | CLEANUP_FLAG_NEED_MSGID | \
CLEANUP_FLAG_NEED_RCVD)
/*
* Diagnostics.
@@ -39,6 +45,7 @@
#define CLEANUP_STAT_SIZE (1<<2) /* Message file too big */
#define CLEANUP_STAT_CONT (1<<3) /* Message content rejected */
#define CLEANUP_STAT_HOPS (1<<4) /* Too many hops */
#define CLEANUP_STAT_MISS_HDR (1<<5) /* Some missing header */
#define CLEANUP_STAT_RCPT (1<<6) /* No recipients found */
/*

View File

@@ -1337,6 +1337,11 @@ ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\\\]^_`\
abcdefghijklmnopqrstuvwxyz{|}~"
extern char *var_smtpd_exp_filter;
#define REQUIRE_DATE_HDR "require_date_header"
#define REQUIRE_FROM_HDR "require_from_header"
#define REQUIRE_MSGID_HDR "require_message_id_header"
#define REQUIRE_RCVD_HDR "require_received_header"
/*
* Heuristic to reject unknown local recipients at the SMTP port.
*/

View File

@@ -20,7 +20,7 @@
* Patches change the patchlevel and the release date. Snapshots change the
* release date only, unless they include the same bugfix as a patch release.
*/
#define MAIL_RELEASE_DATE "20030424"
#define MAIL_RELEASE_DATE "20030519"
#define VAR_MAIL_VERSION "mail_version"
#define DEF_MAIL_VERSION "2.0.9-" MAIL_RELEASE_DATE

View File

@@ -396,7 +396,7 @@ static int lmtp_loop(LMTP_STATE *state, int send_state, int recv_state)
vstring_str(state->scratch));
if ((next_rcpt = send_rcpt + 1) == request->rcpt_list.len)
next_state = DEL_REQ_TRACE_ONLY(request->flags) ?
LMTP_STATE_ABORT : LMTP_STATE_DATA;
LMTP_STATE_RSET : LMTP_STATE_DATA;
break;
/*

View File

@@ -369,7 +369,7 @@ void lmtp_sasl_start(LMTP_STATE *state)
#define NULL_SERVER_ADDR ((char *) 0)
#define NULL_CLIENT_ADDR ((char *) 0)
if (SASL_CLIENT_NEW("smtp", state->session->host,
if (SASL_CLIENT_NEW("lmtp", state->session->host,
NULL_CLIENT_ADDR, NULL_SERVER_ADDR,
state->sasl_callbacks, NULL_SECFLAGS,
(sasl_conn_t **) &state->sasl_conn) != SASL_OK)

View File

@@ -98,6 +98,7 @@
#include <tok822.h>
#include <mail_params.h>
#include <bounce.h>
#include <defer.h>
/* Application-specific. */
@@ -207,6 +208,10 @@ int deliver_token_stream(LOCAL_STATE state, USER_ATTR usr_attr,
break;
}
}
if (vstream_ferror(fp))
status = defer_append(BOUNCE_FLAGS(state.request),
BOUNCE_ATTR(state.msg_attr),
"error reading .forward file: %m");
vstring_free(buf);
return (status);
}

View File

@@ -350,7 +350,7 @@ DICT *dict_proxy_open(const char *map, int open_flags, int dict_flags)
static void post_jail_init(char *unused_name, char **unused_argv)
{
const char *sep = " \t\r\n";
const char *sep = ", \t\r\n";
char *saved_filter;
char *bp;
char *type_name;

View File

@@ -482,6 +482,9 @@ static void qmqpd_send_status(QMQPD_STATE *state)
} else if ((state->err & CLEANUP_STAT_RCPT) != 0) {
qmqpd_reply(state, DO_LOG, QMQPD_STAT_HARD,
"Error: no recipients specified");
} else if ((state->err & CLEANUP_STAT_MISS_HDR) != 0) {
qmqpd_reply(state, DO_LOG, QMQPD_STAT_HARD,
"Error: missing message header");
} else {
qmqpd_reply(state, DO_LOG, QMQPD_STAT_RETRY,
"Error: internal error %d", state->err);

View File

@@ -1141,6 +1141,9 @@ static int data_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *unused_argv)
} else if ((state->err & CLEANUP_STAT_WRITE) != 0) {
state->error_mask |= MAIL_ERROR_RESOURCE;
smtpd_chat_reply(state, "451 Error: queue file write error");
} else if ((state->err & CLEANUP_STAT_MISS_HDR) != 0) {
state->error_mask |= MAIL_ERROR_POLICY;
smtpd_chat_reply(state, "550 Error: missing message header");
} else {
state->error_mask |= MAIL_ERROR_SOFTWARE;
smtpd_chat_reply(state, "451 Error: internal error %d", state->err);

View File

@@ -57,6 +57,13 @@
/* Reject, defer or permit the request unconditionally. This is to be used
/* at the end of a restriction list in order to make the default
/* action explicit.
/* .IP require_date_header
/* .IP require_from_header
/* .IP require_message_id_header
/* .IP require_received_header
/* Reject the message when it does not contain a Date: etc.
/* message header. Only the Date: header is required by mail
/* standards. The other headers are usually added by MTAs.
/* .IP reject_unknown_client
/* Reject the request when the client hostname could not be found.
/* The \fIunknown_client_reject_code\fR configuration parameter
@@ -2750,6 +2757,26 @@ static int generic_checks(SMTPD_STATE *state, ARGV *restrictions,
DEFER_IF_REJECT2(state, MAIL_ERROR_POLICY,
"450 <%s>: %s rejected: defer_if_reject requested",
reply_name, reply_class);
} else if (strcasecmp(name, REQUIRE_DATE_HDR) == 0) {
#ifndef TEST
rec_fprintf(state->dest->stream, REC_TYPE_FLGS, "%d",
CLEANUP_FLAG_NEED_DATE);
#endif
} else if (strcasecmp(name, REQUIRE_FROM_HDR) == 0) {
#ifndef TEST
rec_fprintf(state->dest->stream, REC_TYPE_FLGS, "%d",
CLEANUP_FLAG_NEED_FROM);
#endif
} else if (strcasecmp(name, REQUIRE_MSGID_HDR) == 0) {
#ifndef TEST
rec_fprintf(state->dest->stream, REC_TYPE_FLGS, "%d",
CLEANUP_FLAG_NEED_MSGID);
#endif
} else if (strcasecmp(name, REQUIRE_RCVD_HDR) == 0) {
#ifndef TEST
rec_fprintf(state->dest->stream, REC_TYPE_FLGS, "%d",
CLEANUP_FLAG_NEED_RCVD);
#endif
}
/*

View File

@@ -470,6 +470,7 @@ extern int initgroups(const char *, int);
#define DBM_NO_TRAILING_NULL /* XXX check */
#define USE_STATVFS
#define STATVFS_IN_SYS_STATVFS_H
#define BROKEN_NON_BLOCKING_WRITE_SELECT
#endif
#if defined(IRIX5)

View File

@@ -535,11 +535,23 @@ static int vstream_fflush_some(VSTREAM *stream, int to_flush)
* When flushing a buffer, allow for partial writes. These can happen
* while talking to a network. Update the cached file seek position, if
* any.
*
* XXX Workaround for IRIX brain damage: select() indicates that a pipe is
* writable, but write() transfers zero bytes on non-blocking pipes. This
* means that there is no reasonable way to enforce write timeouts.
*/
for (data = (char *) bp->data, len = to_flush; len > 0; len -= n, data += n) {
if (stream->timeout)
stream->iotime = time((time_t *) 0);
if ((n = stream->write_fn(stream->fd, data, len, stream->timeout, stream->context)) <= 0) {
#ifdef BROKEN_NON_BLOCKING_WRITE_SELECT
if (n == 0) {
msg_warn("%s: write() transfers 0 bytes on a writable descriptor!",
myname);
sleep(1);
continue;
}
#endif
bp->flags |= VSTREAM_FLAG_ERR;
if (errno == ETIMEDOUT)
bp->flags |= VSTREAM_FLAG_TIMEOUT;