Bugfix: Content-Transfer-Encoding: attribute values are
case insensitive. File: src/cleanup/cleanup_message.c.
+
+20070514
+
+ Bugfix: mailbox_transport(_maps) and fallback_transport(_maps)
+ were broken when used with the error(8) or discard(8)
+ transports. Cause: insufficient documentation. Files:
+ error/error.c, discard/discard.c.
+
+20070520
+
+ Bugfix (problem introduced Postfix 2.3): when DSN support
+ was introduced it broke "agressive" recipient duplicate
+ elimination with "enable_original_recipient = no". File:
+ cleanup/cleanup_out_recipient.c.
+
+20070529
+
+ Bugfix (introduced Postfix 2.3): the sendmail/postdrop
+ commands would hang when trying to submit a message larger
+ than the per-message size limit. File: postdrop/postdrop.c.
+
+20070530
+
+ Sabotage the saboteur who insists on breaking Postfix by
+ adding gethostbyname() calls that cause maildir delivery
+ to fail when the machine name is not found in /etc/hosts,
+ or that cause Postfix processes to hang when the network
+ is down.
* Distinguish between different original recipient addresses that map
* onto the same mailbox. The recipient will use our original recipient
* message header to figure things out.
+ *
+ * Postfix 2.2 compatibility: when ignoring differences in Postfix original
+ * recipient information, also ignore differences in DSN attributes. We
+ * do, however, keep the DSN attributes of the recipient that survives
+ * duplicate elimination.
*/
#define STREQ(x, y) (strcmp((x), (y)) == 0)
if ((state->flags & CLEANUP_FLAG_MAP_OK) == 0
|| cleanup_virt_alias_maps == 0) {
- if (been_here(state->dups, "%s\n%d\n%s\n%s",
- dsn_orcpt, dsn_notify, orcpt, recip) == 0) {
+ if ((var_enable_orcpt ?
+ been_here(state->dups, "%s\n%d\n%s\n%s",
+ dsn_orcpt, dsn_notify, orcpt, recip) :
+ been_here_fixed(state->dups, recip)) == 0) {
if (dsn_notify)
cleanup_out_format(state, REC_TYPE_ATTR, "%s=%d",
MAIL_ATTR_DSN_NOTIFY, dsn_notify);
* notifications. The queue manager will flush the trace (and bounce)
* logfile, possibly after it has generated its own success or failure
* notification records.
+ *
+ * Postfix 2.2 compatibility: when ignoring differences in Postfix original
+ * recipient information, also ignore differences in DSN attributes. We
+ * do, however, keep the DSN attributes of the recipient that survives
+ * duplicate elimination.
*/
else {
RECIPIENT rcpt;
dsn_notify & ~DSN_NOTIFY_SUCCESS);
}
for (cpp = argv->argv; *cpp; cpp++) {
- if (been_here(state->dups, "%s\n%d\n%s\n%s",
- dsn_orcpt, dsn_notify, orcpt, *cpp) == 0) {
+ if ((var_enable_orcpt ?
+ been_here(state->dups, "%s\n%d\n%s\n%s",
+ dsn_orcpt, dsn_notify, orcpt, *cpp) :
+ been_here_fixed(state->dups, *cpp)) == 0) {
if (dsn_notify)
cleanup_out_format(state, REC_TYPE_ATTR, "%s=%d",
MAIL_ATTR_DSN_NOTIFY, dsn_notify);
(void) DSN_SIMPLE(&dsn, DSN_STATUS(dp.dsn), dp.text);
for (nrcpt = 0; nrcpt < request->rcpt_list.len; nrcpt++) {
rcpt = request->rcpt_list.info + nrcpt;
- if (rcpt->offset >= 0) {
- status = sent(BOUNCE_FLAGS(request), request->queue_id,
- &request->msg_stats, rcpt, "none", &dsn);
- if (status == 0 && (request->flags & DEL_REQ_FLAG_SUCCESS))
- deliver_completed(src, rcpt->offset);
- result |= status;
- }
+ status = sent(BOUNCE_FLAGS(request), request->queue_id,
+ &request->msg_stats, rcpt, "none", &dsn);
+ if (status == 0 && (request->flags & DEL_REQ_FLAG_SUCCESS))
+ deliver_completed(src, rcpt->offset);
+ result |= status;
}
/*
(void) DSN_SIMPLE(&dsn, DSN_STATUS(dp.dsn), dp.text);
for (nrcpt = 0; nrcpt < request->rcpt_list.len; nrcpt++) {
rcpt = request->rcpt_list.info + nrcpt;
- if (rcpt->offset >= 0) {
- status = bounce_append(BOUNCE_FLAGS(request), request->queue_id,
- &request->msg_stats, rcpt, "none", &dsn);
- if (status == 0)
- deliver_completed(src, rcpt->offset);
- result |= status;
- }
+ status = bounce_append(BOUNCE_FLAGS(request), request->queue_id,
+ &request->msg_stats, rcpt, "none", &dsn);
+ if (status == 0)
+ deliver_completed(src, rcpt->offset);
+ result |= status;
}
/*
* Patches change both the patchlevel and the release date. Snapshots have no
* patchlevel; they change the release date only.
*/
-#define MAIL_RELEASE_DATE "20070511"
-#define MAIL_VERSION_NUMBER "2.3.10-RC1"
+#define MAIL_RELEASE_DATE "20070530"
+#define MAIL_VERSION_NUMBER "2.3.10"
#ifdef SNAPSHOT
# define MAIL_VERSION_DATE "-" MAIL_RELEASE_DATE
if (*var_mbox_transp_maps && transp_maps == 0)
transp_maps = maps_create(VAR_MBOX_TRANSP_MAPS, var_mbox_transp_maps,
DICT_FLAG_LOCK | DICT_FLAG_NO_REGSUB);
+ /* The -1 is a hint for the down-stream deliver_completed() function. */
if (*var_mbox_transp_maps
&& (map_transport = maps_find(transp_maps, state.msg_attr.user,
DICT_FLAG_NONE)) != 0) {
if (*var_fbck_transp_maps && transp_maps == 0)
transp_maps = maps_create(VAR_FBCK_TRANSP_MAPS, var_fbck_transp_maps,
DICT_FLAG_LOCK | DICT_FLAG_NO_REGSUB);
+ /* The -1 is a hint for the down-stream deliver_completed() function. */
if (*var_fbck_transp_maps
&& (map_transport = maps_find(transp_maps, state.msg_attr.user,
DICT_FLAG_NONE)) != 0) {
+ state.msg_attr.rcpt.offset = -1L;
return (deliver_pass(MAIL_CLASS_PRIVATE, map_transport,
state.request, &state.msg_attr.rcpt));
}
if (REC_PUT_BUF(dst->stream, rec_type, buf) < 0) {
/* rec_get() errors must not clobber errno. */
saved_errno = errno;
- while (rec_get_raw(VSTREAM_IN, buf, var_line_limit,
- REC_FLAG_NONE) > 0)
- /* void */ ;
+ while ((rec_type = rec_get_raw(VSTREAM_IN, buf, var_line_limit,
+ REC_FLAG_NONE)) != REC_TYPE_END
+ && rec_type != REC_TYPE_EOF)
+ if (rec_type == REC_TYPE_ERROR)
+ msg_fatal("uid=%ld: malformed input", (long) uid);
errno = saved_errno;
break;
}
* part of the socket interface library. We avoid the more politically-
* correct uname() routine because that has no portable way of dealing
* with long (FQDN) hostnames.
+ *
+ * DO NOT CALL GETHOSTBYNAME FROM THIS FUNCTION. IT BREAKS MAILDIR DELIVERY
+ * AND OTHER THINGS WHEN THE MACHINE NAME IS NOT FOUND IN /ETC/HOSTS OR
+ * CAUSES PROCESSES TO HANG WHEN THE NETWORK IS DISCONNECTED.
+ *
+ * POSTFIX NO LONGER NEEDS A FULLY QUALIFIED HOSTNAME. INSTEAD POSTFIX WILL
+ * USE A DEFAULT DOMAIN NAME "LOCALDOMAIN".
*/
if (my_host_name == 0) {
+ /* DO NOT CALL GETHOSTBYNAME FROM THIS FUNCTION */
if (gethostname(namebuf, sizeof(namebuf)) < 0)
msg_fatal("gethostname: %m");
namebuf[MAXHOSTNAMELEN] = 0;
+ /* DO NOT CALL GETHOSTBYNAME FROM THIS FUNCTION */
if (valid_hostname(namebuf, DO_GRIPE) == 0)
msg_fatal("unable to use my own hostname");
+ /* DO NOT CALL GETHOSTBYNAME FROM THIS FUNCTION */
my_host_name = mystrdup(namebuf);
}
return (my_host_name);