--THOST
--TPLPGSQL
--TPGSQL_NAME
--TDICT_PGSQL
-TABOUNCE
-TALIAS_TOKEN
-TARGV
-TDICT_PCRE_PRESCAN_CONTEXT
-TDICT_PCRE_REGEXP
-TDICT_PCRE_RULE
+-TDICT_PGSQL
-TDICT_PROXY
-TDICT_REGEXP
-TDICT_REGEXP_EXPAND_CONTEXT
-THEADER_OPTS
-THEADER_TOKEN
-THOST
+-THOST
-THTABLE
-THTABLE_INFO
-TINET_ADDR_LIST
-TMAC_PARSE
-TMAIL_PRINT
-TMAIL_SCAN
+-TMAIL_STREAM
-TMAPS
-TMASTER_PROC
-TMASTER_SERV
-TNAMADR_LIST
-TNAME_MASK
-TPEER_NAME
+-TPGSQL_NAME
-TPICKUP_INFO
-TPIPE_ATTR
-TPIPE_PARAMS
-TPLMYSQL
+-TPLPGSQL
-TPOST_MAIL_STATE
-TQMGR_ENTRY
-TQMGR_JOB
now has an explicit flush operation, and the smtp-source/sink
programs are updated to take advantage of this.
- Cleanup: the file system clock drift detection code now runs
- only once per process instance, to minimize the performance
- impact. File: global/mail_stream.c.
+ Cleanup: the file system clock drift detection code now
+ runs only once per process instance, to minimize the
+ performance impact. File: global/mail_stream.c.
Robustness: avoid TIME_WAIT state with smtp/qmqp-source
client sockets. This puts less strain on local system
resources.
+10030415
+
+ Cleanup: the file system clock drift detection code now
+ runs only for incoming mail. File: global/mail_stream.c.
+
Open problems:
Low: smtp-source may block when sending large test messages.
To use pgsql with Postfix on Debian GNU/Linux, you must install
the postfix-pgsql package.
-In order to build Postfix with pgsql map support, you will need to
-add -DHAS_PGSQL and -I for the directory containing the PostgreSQL
-header files and the libpq library to AUXLIBS, for example:
+In order to build Postfix with pgsql map support, you specify
+-DHAS_PGSQL, the directory with the PostgreSQL header files, and
+the location of the libpq library file.
+
+For example:
make tidy
make -f Makefile.init makefiles \
# end pgsql config file
-Eliminating single points of failure
-====================================
+Using mirrored databases
+========================
+
+Sites that have a need for multiple mail exchangers may enjoy the
+convenience of using a networked mailer database, but do not want
+to introduce a single point of failure to their system.
+
+For this reason we've included the ability to have Postfix reference
+multiple hosts for access to a single pgsql map. This will work
+if sites set up mirrored pgsql databases on two or more hosts.
-Since sites that have a need for multiple mail exchangers may enjoy
-the convenience of using a networked mailer database, but do not
-want to introduce a single point of failure to their system, we've
-included the ability to have postfix reference multiple hosts for
-access to a single pgsql map. This will work if sites set up
-mirrored pgsql databases on two or more hosts. Whenever queries
-fail with an error at one host, the rest of the hosts will be tried
-in order. Each host that is in an error state will undergo a
-reconnection attempt every so often, and if no pgsql server hosts
-are reachable, then mail will be deferred until at least one of
-those hosts is reachable.
+Whenever queries fail with an error at one host, the rest of the
+hosts will be tried in order. Each host that is in an error state
+will undergo a reconnection attempt every so often, and if no pgsql
+server hosts are reachable, then mail will be deferred until at
+least one of those hosts is reachable.
mmencode is part of the metamail software.
MIME::Base64 is available from www.cpan.org.
+Trouble shooting the SASL internals
+===================================
+
+[based on text by Liviu Daia]
+
+In the Cyrus SASL sources you'll find a subdirectory named "sample".
+Run make there, then run the resulting sample server and client in
+separate terminals. Strace / ktrace / truss the server to see what
+makes it unhappy, fix the problem, then write the authors thanking
+them for providing such useful logging. Repeat the previous step
+until you can successfully authenticate with the sample client.
+Only then get back to Postfix.
+
Enabling SASL authentication in the Postfix SMTP client
=======================================================
defines the database. See the sample-pgsql-aliases.cf file for
examples, and the PGSQL_README file for general information.
-Workarounds for file systems whose clock runs ahead of the local
-clock (this can happen with remote file systems). Postfix now logs
-a warning and proceeds with reduced performance, instead of ignoring
-new mail completely.
+Workaround for file system clock drift that caused Postfix to ignore
+new mail (this could happen with file systems mounted from a server).
+Postfix now logs a warning and proceeds with only slightly reduced
+performance, instead of ignoring new mail.
Incompatible changes with Postfix snapshot 2.0.6-20030305
=========================================================
/* mail_stream_cleanup - clean up after success or failure */
-void mail_stream_cleanup(MAIL_STREAM * info)
+void mail_stream_cleanup(MAIL_STREAM *info)
{
FREE_AND_WIPE(info->close, info->stream);
+ FREE_AND_WIPE(myfree, info->queue);
FREE_AND_WIPE(myfree, info->id);
FREE_AND_WIPE(myfree, info->class);
FREE_AND_WIPE(myfree, info->service);
/* mail_stream_finish_file - finish file mail stream */
-static int mail_stream_finish_file(MAIL_STREAM * info, VSTRING *unused_why)
+static int mail_stream_finish_file(MAIL_STREAM *info, VSTRING *unused_why)
{
int status = 0;
static char wakeup[] = {TRIGGER_REQ_WAKEUP};
struct stat st;
time_t now;
struct utimbuf tbuf;
- char *queue_file_path = 0;
- static int fs_clock_ok = 0;
- static int fs_clock_warned = 0;
+ char *path_to_reset = 0;
+ static int incoming_fs_clock_ok = 0;
+ static int incoming_clock_warned = 0;
+ int check_incoming_fs_clock;
/*
* Make sure the message makes it to file. Set the execute bit when no
* must end with an explicit END record. Postfix queue files without END
* record are discarded.
*
- * Attempt to detect file system clocks that are ahead of local time. the
- * effect can be difficult to understand (mail is enqueued but Postfix
- * ignores it). This clock drift detection may not work with file systems
- * that work on a local copy of the file and that update the server only
- * after the file is closed.
+ * Attempt to detect file system clocks that are ahead of local time, but
+ * don't check the file system clock all the time. The effect of file
+ * system clock drift can be difficult to understand (Postfix ignores new
+ * mail until the next queue run).
+ *
+ * This clock drift detection code may not work with file systems that work
+ * on a local copy of the file and that update the server only after the
+ * file is closed.
*/
+ check_incoming_fs_clock =
+ (!incoming_fs_clock_ok && !strcmp(info->queue, MAIL_QUEUE_INCOMING));
+
if (vstream_fflush(info->stream)
|| fchmod(vstream_fileno(info->stream), 0700 | info->mode)
#ifdef HAS_FSYNC
|| fsync(vstream_fileno(info->stream))
#endif
- || (fs_clock_ok == 0 && fstat(vstream_fileno(info->stream), &st) < 0)
+ || (check_incoming_fs_clock
+ && fstat(vstream_fileno(info->stream), &st) < 0)
)
status = (errno == EFBIG ? CLEANUP_STAT_SIZE : CLEANUP_STAT_WRITE);
st.st_mtime += 10;
#endif
- /*
- * Don't check the file system clock all the time.
- */
- if (fs_clock_ok == 0 && st.st_mtime <= time(&now))
- fs_clock_ok = 1;
-
/*
* Work around file system clocks that are ahead of local time.
*/
- if (status == CLEANUP_STAT_OK && fs_clock_ok == 0) {
- if (fs_clock_warned == 0) {
- msg_warn("%s: file system clock is %d seconds ahead of local clock",
- info->id, (int) (st.st_mtime - now));
- msg_warn("%s: resetting file time stamps - this hurts performance",
- info->id);
- fs_clock_warned = 1;
+ if (status == CLEANUP_STAT_OK && check_incoming_fs_clock) {
+ if (st.st_mtime <= time(&now)) {
+ incoming_fs_clock_ok = 1;
+ } else {
+ path_to_reset = mystrdup(VSTREAM_PATH(info->stream));
+ if (incoming_clock_warned == 0) {
+ msg_warn("file system clock is %d seconds ahead of local clock",
+ (int) (st.st_mtime - now));
+ msg_warn("resetting file time stamps - this hurts performance");
+ incoming_clock_warned = 1;
+ }
}
- queue_file_path = mystrdup(VSTREAM_PATH(info->stream));
}
/*
/*
* Work around file system clocks that are ahead of local time.
*/
- if (queue_file_path != 0) {
+ if (path_to_reset != 0) {
tbuf.actime = tbuf.modtime = now;
- if (utime(queue_file_path, &tbuf) < 0 && errno != ENOENT)
+ if (utime(path_to_reset, &tbuf) < 0 && errno != ENOENT)
msg_fatal("%s: update file time stamps: %m", info->id);
- myfree(queue_file_path);
+ myfree(path_to_reset);
}
/*
/* mail_stream_finish_ipc - finish IPC mail stream */
-static int mail_stream_finish_ipc(MAIL_STREAM * info, VSTRING *why)
+static int mail_stream_finish_ipc(MAIL_STREAM *info, VSTRING *why)
{
int status = CLEANUP_STAT_WRITE;
/* mail_stream_finish - finish action */
-int mail_stream_finish(MAIL_STREAM * info, VSTRING *why)
+int mail_stream_finish(MAIL_STREAM *info, VSTRING *why)
{
return (info->finish(info, why));
}
info->stream = stream;
info->finish = mail_stream_finish_file;
info->close = vstream_fclose;
+ info->queue = mystrdup(queue);
info->id = mystrdup(basename(VSTREAM_PATH(stream)));
info->class = mystrdup(class);
info->service = mystrdup(service);
info->stream = stream;
info->finish = mail_stream_finish_ipc;
info->close = vstream_fclose;
+ info->queue = 0;
info->id = mystrdup(vstring_str(id_buf));
info->class = 0;
info->service = 0;
info->stream = stream;
info->finish = mail_stream_finish_ipc;
info->close = vstream_pclose;
+ info->queue = 0;
info->id = mystrdup(vstring_str(id_buf));
info->class = 0;
info->service = 0;
struct MAIL_STREAM {
VSTREAM *stream; /* file or pipe or socket */
+ char *queue; /* (initial) queue name */
char *id; /* queue id */
MAIL_STREAM_FINISH_FN finish; /* finish code */
MAIL_STREAM_CLOSE_FN close; /* close stream */
* 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 "20030414"
+#define MAIL_RELEASE_DATE "20030415"
#define VAR_MAIL_VERSION "mail_version"
#define DEF_MAIL_VERSION "2.0.8-" MAIL_RELEASE_DATE
static void dot_response(SINK_STATE *state)
{
if (enable_lmtp) {
- while (state->rcpts-- > 0) /* XXX this could block */
- ok_response(state);
+ while (state->rcpts-- > 0) /* XXX this could block */
+ ok_response(state); /* XXX this flushes too often */
} else {
ok_response(state);
}
/* SYNOPSIS
/* #include <dict_pgsql.h>
/*
-/* DICT *dict_pgsql_open(name, dummy, unused_dict_flags)
+/* DICT *dict_pgsql_open(name, unused_open_flags, unused_dict_flags)
/* const char *name;
-/* int dummy;
+/* int unused_open_flags;
/* int unused_dict_flags;
/* DESCRIPTION
/* dict_pgsql_open() creates a dictionary of type 'pgsql'. This
/* or a null pointer in case of problems.
/*
/* The pgsql dictionary can manage multiple connections to
-/* different sql servers on different hosts. It assumes that
-/* the underlying data on each host is identical (mirrored) and
+/* different sql servers for the same database. It assumes that
+/* the underlying data on each server is identical (mirrored) and
/* maintains one connection at any given time. If any connection
/* fails, any other available ones will be opened and used.
/* The intent of this feature is to eliminate a single point of