20030920
- Bugfix: LDAP client update by by Victor Duchovni, Morgan
- Stanley. Files: README_FILES/LDAP_README, util/dict_ldap.c.
+ Bugfix: the 20030917 LDAP connection sharing code introduced
+ a compilation problem with non-OpenLDAP implementations.
+ Fix by Liviu Daia. File: util/dict_ldap.c
+
+ Compatibility: the LDAP server_host parameter now supports
+ all the usual Postfix list element delimiters. Some LDAP
+ libraries support just SPACE, others SPACE and ",". Postfix
+ now normalizes the host list into a space separated format.
+ This is less surprising to Postfix users used to the full
+ range of delimeters in other contexts. Implemented by Liviu
+ Daia. File: util/dict_ldap.c
Bugfix: after returning too old mail, the bounce daemon
- now deletes recipients from the original queue file, to
- avoid repeated bounce notifications when the queue manager
- is restarted. Files: bounce/*.[hc], global/bounce_log.[hc],
- global/{bounce,defer}.[hc] and everything that invokes
- these routines including queue manager and delivery agents.
+ now locks the original queue file and deletes deferred
+ recipients, to avoid repeated bounce notifications when
+ the queue manager is restarted. Files: bounce/*.[hc],
+ global/bounce_log.[hc], global/{bounce,defer}.[hc] and
+ everything that invokes these routines including queue
+ manager and delivery agents.
Open problems:
Location of the Postfix queue, and of the local IPC
communication endpoints.
+ <b>application_event_drain_time</b>
+ How long the program waits for the trigger to be
+ accepted.
+
<b>SEE ALSO</b>
<a href="qmgr.8.html">qmgr(8)</a> queue manager trigger protocol
<a href="pickup.8.html">pickup(8)</a> local pickup daemon
<b>LICENSE</b>
- The Secure Mailer license must be distributed with this
+ The Secure Mailer license must be distributed with this
software.
<b>AUTHOR(S)</b>
-<html> <head> </head> <body> <pre>
+<html> <body> <pre>
VIRTUAL(8) VIRTUAL(8)
<b>NAME</b>
.IP \fBqueue_directory\fR
Location of the Postfix queue, and of the local IPC communication
endpoints.
+.IP \fBapplication_event_drain_time\fR
+How long the program waits for the trigger to be accepted.
.SH SEE ALSO
.na
.nf
#include <line_wrap.h>
#include <stringops.h>
#include <xtext.h>
+#include <myflock.h>
/* Global library. */
* backoff.
*/
if ((bounce_info->orig_fp = mail_queue_open(queue_name, queue_id,
- O_RDONLY, 0)) == 0
+ O_RDWR, 0)) == 0
&& errno != ENOENT)
msg_fatal("open %s %s: %m", service, queue_id);
* Skip over the original message envelope records. If the envelope is
* corrupted just send whatever we can (remember this is a best effort,
* it does not have to be perfect).
+ *
+ * Lock the file for shared use, so that queue manager leaves it alone after
+ * restarting.
*/
+#define DELIVER_LOCK_MODE (MYFLOCK_OP_SHARED | MYFLOCK_OP_NOWAIT)
+
if (bounce_info->orig_fp != 0) {
+ if (myflock(vstream_fileno(bounce_info->orig_fp), INTERNAL_LOCK,
+ DELIVER_LOCK_MODE) < 0)
+ msg_fatal("cannot get shared lock on %s: %m",
+ VSTREAM_PATH(bounce_info->orig_fp));
while ((rec_type = rec_get(bounce_info->orig_fp,
bounce_info->buf, 0)) > 0) {
if (rec_type == REC_TYPE_TIME && bounce_info->arrival_time == 0) {
* job. But if the system IS running out of resources, raise a fatal
* run-time error and force a backoff.
*/
- if ((log_handle = bounce_log_open(service, queue_id, O_RDWR, 0)) == 0
+ if ((log_handle = bounce_log_open(service, queue_id, O_RDONLY, 0)) == 0
&& errno != ENOENT)
msg_fatal("open %s %s: %m", service, queue_id);
bounce_info = bounce_mail_alloc(service, queue_name, queue_id,
*/
if (bounce_info->log_handle == 0
|| bounce_log_rewind(bounce_info->log_handle)) {
- post_mail_fputs(bounce, "\t--- Delivery error report unavailable ---");
+ post_mail_fputs(bounce, "\t--- Delivery report unavailable ---");
} else {
while (bounce_log_read(bounce_info->log_handle) != 0)
if (bounce_recipient_log(bounce, bounce_info) != 0)
/* SYNOPSIS
/* #include <abounce.h>
/*
-/* void abounce_flush(flags, queue, id, encoding, sender, callback, context)
+/* void abounce_flush(flags, queue, id, encoding, sender,
+/* callback, context)
/* int flags;
/* const char *queue;
/* const char *id;
/* void (*callback)(int status, char *context);
/* char *context;
/*
-/* void abounce_flush_verp(flags, queue, id, encoding, sender, verp, callback, context)
+/* void abounce_flush_verp(flags, queue, id, encoding,
+/* sender, verp, callback, context)
/* int flags;
/* const char *queue;
/* const char *id;
/* void (*callback)(int status, char *context);
/* char *context;
/*
-/* void adefer_flush(flags, queue, id, encoding, sender, callback, context)
+/* void adefer_flush(flags, queue, id, encoding, sender,
+/* callback, context)
/* int flags;
/* const char *queue;
/* const char *id;
/* void (*callback)(int status, char *context);
/* char *context;
/*
-/* void adefer_flush_verp(flags, queue, id, encoding, sender, verp, callback, context)
+/* void adefer_flush_verp(flags, queue, id, encoding,
+/* sender, verp, callback, context)
/* int flags;
/* const char *queue;
/* const char *id;
/* void (*callback)(int status, char *context);
/* char *context;
/*
-/* void adefer_warn(flags, queue, id, encoding, sender, callback, context)
+/* void adefer_warn(flags, queue, id, encoding, sender,
+/* callback, context)
/* int flags;
/* const char *queue;
/* const char *id;
/* adefer_flush() bounces the specified message to
/* the specified sender, including the defer log that was
/* built with defer_append().
+/* adefer_flush() requests that the deferred recipients are deleted
+/* from the original queue file.
/*
/* adefer_flush_verp() is like adefer_flush() but sends
/* one VERP style notification per undeliverable recipient.
const char *verp, ABOUNCE_FN callback,
char *context)
{
+ flags |= BOUNCE_FLAG_DELRCPT;
abounce_request_verp(MAIL_CLASS_PRIVATE, var_defer_service,
BOUNCE_CMD_VERP, flags, queue, id, encoding,
sender, verp, callback, context);
const char *encoding, const char *sender,
ABOUNCE_FN callback, char *context)
{
+ flags |= BOUNCE_FLAG_DELRCPT;
abounce_request(MAIL_CLASS_PRIVATE, var_defer_service, BOUNCE_CMD_FLUSH,
flags, queue, id, encoding, sender, callback, context);
}
/*
/* defer_flush() bounces the specified message to the specified
/* sender, including the defer log that was built with defer_append().
+/* defer_flush() requests that the deferred recipients are deleted
+/* from the original queue file.
/* The result is zero in case of success, non-zero otherwise.
/*
/* defer_warn() sends a warning message that the mail in question has
* 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 "20030920"
+#define MAIL_RELEASE_DATE "20030921"
#define VAR_MAIL_VERSION "mail_version"
#define DEF_MAIL_VERSION "2.0.16-" MAIL_RELEASE_DATE
ATTR_TYPE_STR, MAIL_ATTR_QUEUEID, queue_id,
ATTR_TYPE_STR, MAIL_ATTR_ORCPT, orig_rcpt,
ATTR_TYPE_STR, MAIL_ATTR_RECIP, recipient,
+ ATTR_TYPE_LONG, MAIL_ATTR_OFFSET, (long) 0,
ATTR_TYPE_STR, MAIL_ATTR_STATUS, dsn_code,
ATTR_TYPE_STR, MAIL_ATTR_ACTION, dsn_action,
ATTR_TYPE_STR, MAIL_ATTR_WHY, vstring_str(why),
/* .IP \fBqueue_directory\fR
/* Location of the Postfix queue, and of the local IPC communication
/* endpoints.
+/* .IP \fBapplication_event_drain_time\fR
+/* How long the program waits for the trigger to be accepted.
/* SEE ALSO
/* qmgr(8) queue manager trigger protocol
/* pickup(8) local pickup daemon
}
}
if (dns_status != DNS_OK) {
- msg_warn("Unable to look up %s host for %s", dns_strtype(type),
- domain && domain[1] ? domain : name);
+ msg_warn("Unable to look up %s host for %s: %s", dns_strtype(type),
+ domain && domain[1] ? domain : name, dns_strerror(h_errno));
return (SMTPD_CHECK_DUNNO);
}
*/
for (server = server_list; server != 0; server = server->next) {
if ((hp = gethostbyname((char *) server->data)) == 0) {
- msg_warn("Unable to look up %s host %s for %s %s",
+ msg_warn("Unable to look up %s host %s for %s %s: %s",
dns_strtype(type), (char *) server->data,
- reply_class, reply_name);
+ reply_class, reply_name, dns_strerror(h_errno));
continue;
}
if (hp->h_addrtype != AF_INET || hp->h_length != sizeof(addr)) {
for (msg_stat = 0, rcpt = rqst->rcpt_list.info; rcpt < rcpt_end; rcpt++) {
state.msg_attr.orig_rcpt = rcpt->orig_addr;
state.msg_attr.recipient = rcpt->address;
+ state.msg_attr.rcpt_offset = rcpt->offset;
rcpt_stat = deliver_recipient(state, usr_attr);
if (rcpt_stat == 0)
deliver_completed(state.msg_attr.fp, rcpt->offset);