diff --git a/postfix/HISTORY b/postfix/HISTORY index edaedd257..ab1b56f4a 100644 --- a/postfix/HISTORY +++ b/postfix/HISTORY @@ -8911,6 +8911,15 @@ Apologies for any names omitted. Fix is to turn off loop detection when a non-default TCP port is specified. File: smtp/smtp_addr.c. + Bugfix: restore errno after write failure in SIGCHLD handler. + Leandro Santi. File: master/master_sig.c. + + Bugfix: the auto_clnt module disconnected too early, causing + unnecessary work by the anvil server. + + Cleanup: eliminated binary hashes from anvil server. Anvil + client information is now stored on top of its VSTREAM. + Open problems: Low: in the SMTP client, pass the session, request and diff --git a/postfix/html/postsuper.1.html b/postfix/html/postsuper.1.html index 2a8ff15ac..1364a46d4 100644 --- a/postfix/html/postsuper.1.html +++ b/postfix/html/postsuper.1.html @@ -1,12 +1,12 @@ -
+POSTSUPER(1) POSTSUPER(1) NAME postsuper - Postfix superintendent SYNOPSIS - postsuper [-psv] [-c config_dir] [-d queue_id] [-h - queue_id] [-H queue_id] [-r queue_id] [directory ...] + postsuper [-psv] [-c config_dir] [-d queue_id] [-h + queue_id] [-H queue_id] [-r queue_id] [directory ...] DESCRIPTION The postsuper command does maintenance jobs on the Postfix @@ -22,16 +22,16 @@ POSTSUPER(1) POSTSUPER(1) Options: - -c config_dir + -c config_dir The main.cf configuration file is in the named directory instead of the default configuration directory. See also the MAIL_CONFIG environment setting below. - -d queue_id + -d queue_id Delete one message with the named queue ID from the named mail queue(s) (default: hold, incoming, - active and deferred). If a queue_id of - is speci- + active and deferred). If a queue_id of - is speci- fied, the program reads queue IDs from standard input. For example, to delete all mail from or to user@example.com: @@ -40,15 +40,15 @@ POSTSUPER(1) POSTSUPER(1) / user@example\.com$/ { print $1 } \ ' | tr -d '*!' | postsuper -d - - Specify -d ALL to remove all messages; for example, - specify -d ALL deferred to delete mail in the + Specify -d ALL to remove all messages; for example, + specify -d ALL deferred to delete mail in the deferred queue. As a safety measure, the word ALL must be specified in upper case. - Postfix queue IDs are reused. There is a very - small possibility that postsuper deletes the wrong - message file when it is executed while the Postfix - mail system is running. + Postfix queue IDs are reused. There is a very + small possibility that postsuper deletes the wrong + message file when it is executed while the Postfix + mail system is running. The scenario is as follows: @@ -69,89 +69,90 @@ POSTSUPER(1) POSTSUPER(1) of the old message that it should have deleted. - -h queue_id + -h queue_id Put mail "on hold" so that no attempt is made to deliver it. Move one message with the named queue ID from the named mail queue(s) (default: incoming, active and deferred) to the hold queue. If a - queue_id of - is specified, the program reads queue + queue_id of - is specified, the program reads queue IDs from standard input. - Specify -h ALL to hold all messages; for example, - specify -h ALL deferred to hold mail in the + Specify -h ALL to hold all messages; for example, + specify -h ALL deferred to hold mail in the deferred queue. As a safety measure, the word ALL must be specified in upper case. - Note: mail that is put "on hold" will not expire + Note: while mail is "on hold" it will not expire when its time in the queue exceeds the maxi- - mal_queue_lifetime setting. + mal_queue_lifetime setting. It becomes subject to + expiration after it is released from "hold". - -H queue_id + -H queue_id Release mail that was put "on hold". Move one mes- - sage with the named queue ID from the named mail + sage with the named queue ID from the named mail queue(s) (default: hold) to the deferred queue. If - a queue_id of - is specified, the program reads + a queue_id of - is specified, the program reads queue IDs from standard input. - Specify -H ALL to release all mail that is "on - hold". As a safety measure, the word ALL must be + Specify -H ALL to release all mail that is "on + hold". As a safety measure, the word ALL must be specified in upper case. - -p Purge old temporary files that are left over after + -p Purge old temporary files that are left over after system or software crashes. - -r queue_id - Requeue the message with the named queue ID from - the named mail queue(s) (default: hold, incoming, - active and deferred). To requeue multiple mes- - sages, specify multiple -r command-line options. - Alternatively, if a queue_id of - is specified, the + -r queue_id + Requeue the message with the named queue ID from + the named mail queue(s) (default: hold, incoming, + active and deferred). To requeue multiple mes- + sages, specify multiple -r command-line options. + Alternatively, if a queue_id of - is specified, the program reads queue IDs from standard input. - Specify -r ALL to requeue all messages. As a safety - measure, the word ALL must be specified in upper + Specify -r ALL to requeue all messages. As a safety + measure, the word ALL must be specified in upper case. - A requeued message is moved to the maildrop queue, - from where it is copied by the pickup daemon to a - new file whose name is guaranteed to match the new + A requeued message is moved to the maildrop queue, + from where it is copied by the pickup daemon to a + new file whose name is guaranteed to match the new queue file inode number. The new queue file is sub- - jected again to mail address rewriting and substi- + jected again to mail address rewriting and substi- tution. This is useful when rewriting rules or vir- tual mappings have changed. - Postfix queue IDs are reused. There is a very + Postfix queue IDs are reused. There is a very small possibility that postsuper requeues the wrong - message file when it is executed while the Postfix + message file when it is executed while the Postfix mail system is running, but no harm should be done. -s Structure check and structure repair. It is highly - recommended to perform this operation once before + recommended to perform this operation once before Postfix startup. - o Rename files whose name does not match the + o Rename files whose name does not match the message file inode number. This operation is - necessary after restoring a mail queue from + necessary after restoring a mail queue from a different machine, or from backup media. o Move queue files that are in the wrong place in the file system hierarchy and remove sub- directories that are no longer needed. File - position rearrangements are necessary after - a change in the hash_queue_names and/or - hash_queue_depth configuration parameters. + position rearrangements are necessary after + a change in the hash_queue_names and/or + hash_queue_depth configuration parameters. -v Enable verbose logging for debugging purposes. Mul- - tiple -v options make the software increasingly + tiple -v options make the software increasingly verbose. DIAGNOSTICS - Problems are reported to the standard error stream and to + Problems are reported to the standard error stream and to syslogd. - postsuper reports the number of messages deleted with -d, + postsuper reports the number of messages deleted with -d, the number of messages requeued with -r, and the number of - messages whose queue file name was fixed with -s. The + messages whose queue file name was fixed with -s. The report is written to the standard error stream and to sys- logd. @@ -160,31 +161,31 @@ POSTSUPER(1) POSTSUPER(1) Directory with the main.cf file. BUGS - Mail that is not sanitized by Postfix (i.e. mail in the + Mail that is not sanitized by Postfix (i.e. mail in the maildrop queue) cannot be placed "on hold". -CONFIGURATION PARAMETERS - See the Postfix main.cf file for syntax details and for +CONFIGURATION PARAMETERS + See the Postfix main.cf file for syntax details and for default values. - hash_queue_depth + hash_queue_depth Number of subdirectory levels for hashed queues. - hash_queue_names - The names of queues that are organized into multi- + hash_queue_names + The names of queues that are organized into multi- ple levels of subdirectories. - queue_directory - Top-level directory of the Postfix queue. This is + queue_directory + Top-level directory of the Postfix queue. This is also the root directory of Postfix daemons that run chrooted. -SEE ALSO +SEE ALSO sendmail(1) sendmail-compatible user interface postqueue(1) unprivileged queue operations LICENSE - The Secure Mailer license must be distributed with this + The Secure Mailer license must be distributed with this software. AUTHOR(S) diff --git a/postfix/html/smtp.8.html b/postfix/html/smtp.8.html index 442e63eec..dcc88a50c 100644 --- a/postfix/html/smtp.8.html +++ b/postfix/html/smtp.8.html @@ -244,8 +244,8 @@ SMTP(8) SMTP(8) smtp_mx_address_limit An upper bound on the total number of MX (mail - exchanger) IP addresses that that can result from - mail exchanger lookups. + exchanger) IP addresses that can result from mail + exchanger lookups. Specify zero to disable the limit. diff --git a/postfix/man/man1/postsuper.1 b/postfix/man/man1/postsuper.1 index 5cbbbc027..e716f733c 100644 --- a/postfix/man/man1/postsuper.1 +++ b/postfix/man/man1/postsuper.1 @@ -87,9 +87,10 @@ Specify \fB-h ALL\fR to hold all messages; for example, specify As a safety measure, the word \fBALL\fR must be specified in upper case. .sp -Note: mail that is put "on hold" will not expire when its +Note: while mail is "on hold" it will not expire when its time in the queue exceeds the \fBmaximal_queue_lifetime\fR -setting. +setting. It becomes subject to expiration after it is +released from "hold". .IP "\fB-H \fIqueue_id\fR" Release mail that was put "on hold". Move one message with the named queue ID from the named diff --git a/postfix/man/man8/smtp.8 b/postfix/man/man8/smtp.8 index 80df1a34a..ba57449aa 100644 --- a/postfix/man/man8/smtp.8 +++ b/postfix/man/man8/smtp.8 @@ -205,7 +205,7 @@ The default limit is taken from the \fBdefault_destination_recipient_limit\fR parameter. .IP \fBsmtp_mx_address_limit\fR An upper bound on the total number of MX (mail exchanger) IP -addresses that that can result from mail exchanger lookups. +addresses that can result from mail exchanger lookups. .sp Specify zero to disable the limit. .sp diff --git a/postfix/src/anvil/Makefile.in b/postfix/src/anvil/Makefile.in index 189f14ec0..b88d2b255 100644 --- a/postfix/src/anvil/Makefile.in +++ b/postfix/src/anvil/Makefile.in @@ -57,7 +57,6 @@ anvil.o: ../../include/sys_defs.h anvil.o: ../../include/msg.h anvil.o: ../../include/mymalloc.h anvil.o: ../../include/htable.h -anvil.o: ../../include/binhash.h anvil.o: ../../include/stringops.h anvil.o: ../../include/vstring.h anvil.o: ../../include/vbuf.h diff --git a/postfix/src/anvil/anvil.c b/postfix/src/anvil/anvil.c index 80cd3a0e2..46c7977dc 100644 --- a/postfix/src/anvil/anvil.c +++ b/postfix/src/anvil/anvil.c @@ -122,7 +122,6 @@ #include#include #include -#include #include #include @@ -146,7 +145,6 @@ int var_anvil_stat_time; * State. */ static HTABLE *anvil_remote_map; /* indexed by service+ remote client */ -static BINHASH *anvil_local_map; /* indexed by local client handle */ /* * Absent a real-time query interface, these are logged at process exit time @@ -291,8 +289,8 @@ static void anvil_remote_expire(int unused_event, char *context) ANVIL_REMOTE_FREE(anvil_remote); if (msg_verbose) - msg_info("%s: anvil_remote_map used=%d", - myname, anvil_remote_map->used); + msg_info("%s: anvil_remote_map used=%d", + myname, anvil_remote_map->used); } /* anvil_remote_lookup - dump address status */ @@ -375,14 +373,12 @@ static void anvil_remote_connect(VSTREAM *client_stream, const char *ident) * Record this connection under the local client information, so that we * can clean up all its connection state when the local client goes away. */ - if ((anvil_local = - (ANVIL_LOCAL *) binhash_find(anvil_local_map, - (char *) &client_stream, - sizeof(client_stream))) == 0) { + if ((anvil_local = (ANVIL_LOCAL *) vstream_context(client_stream)) == 0) { anvil_local = (ANVIL_LOCAL *) mymalloc(sizeof(*anvil_local)); ANVIL_LOCAL_INIT(anvil_local); - binhash_enter(anvil_local_map, (char *) &client_stream, - sizeof(client_stream), (char *) anvil_local); + vstream_control(client_stream, + VSTREAM_CTL_CONTEXT, (void *) anvil_local, + VSTREAM_CTL_END); } ANVIL_LOCAL_ADD_ONE(anvil_local, anvil_remote); if (msg_verbose) @@ -446,10 +442,7 @@ static void anvil_remote_disconnect(VSTREAM *client_stream, const char *ident) /* * Update the local client information. */ - if ((anvil_local = - (ANVIL_LOCAL *) binhash_find(anvil_local_map, - (char *) &client_stream, - sizeof(client_stream))) != 0) + if ((anvil_local = (ANVIL_LOCAL *) vstream_context(client_stream)) != 0) ANVIL_LOCAL_DROP_ONE(anvil_local, anvil_remote); if (msg_verbose) msg_info("%s: anvil_local 0x%lx", @@ -481,24 +474,15 @@ static void anvil_service_done(VSTREAM *client_stream, char *unused_service, * that we still have for this local client. Do not destroy remote client * status information before it expires. */ - if ((anvil_local = - (ANVIL_LOCAL *) binhash_find(anvil_local_map, - (char *) &client_stream, - sizeof(client_stream))) != 0) { + if ((anvil_local = (ANVIL_LOCAL *) vstream_context(client_stream)) != 0) { if (msg_verbose) msg_info("%s: anvil_local 0x%lx", myname, (unsigned long) anvil_local); ANVIL_LOCAL_DROP_ALL(client_stream, anvil_local); - binhash_delete(anvil_local_map, - (char *) &client_stream, - sizeof(client_stream), myfree); + myfree((char *) anvil_local); } else if (msg_verbose) msg_info("client socket not found for fd=%d", vstream_fileno(client_stream)); - - if (msg_verbose) - msg_info("%s: anvil_local_map used=%d", - myname, anvil_local_map->used); } /* anvil_service - perform service for client */ @@ -520,6 +504,8 @@ static void anvil_service(VSTREAM *client_stream, char *unused_service, char **a * connection-management stuff is handled by the common code in * multi_server.c. */ + if (msg_verbose) + msg_info("--- start request ---"); if (attr_scan_plain(client_stream, ATTR_FLAG_MISSING | ATTR_FLAG_STRICT, ATTR_TYPE_STR, ANVIL_ATTR_REQ, request, @@ -542,6 +528,8 @@ static void anvil_service(VSTREAM *client_stream, char *unused_service, char **a /* Note: invokes anvil_service_done() */ multi_server_disconnect(client_stream); } + if (msg_verbose) + msg_info("--- end request ---"); vstring_free(ident); vstring_free(request); } @@ -561,7 +549,6 @@ static void post_jail_init(char *unused_name, char **unused_argv) * Initial client state tables. */ anvil_remote_map = htable_create(1000); - anvil_local_map = binhash_create(100); /* * Do not limit the number of client requests. diff --git a/postfix/src/global/mail_stream.c b/postfix/src/global/mail_stream.c index 19c822911..62a06b4cb 100644 --- a/postfix/src/global/mail_stream.c +++ b/postfix/src/global/mail_stream.c @@ -114,7 +114,13 @@ static VSTRING *id_buf; void mail_stream_cleanup(MAIL_STREAM *info) { - FREE_AND_WIPE(info->close, info->stream); + int status; + + if (info->stream) { + if ((status = info->close(info->stream)) != 0) + msg_warn("bad mail stream close status %d", status); + info->stream = 0; + } FREE_AND_WIPE(myfree, info->queue); FREE_AND_WIPE(myfree, info->id); FREE_AND_WIPE(myfree, info->class); @@ -318,6 +324,7 @@ MAIL_STREAM *mail_stream_command(const char *command) VSTREAM *stream; MAIL_STREAM *info; ARGV *export_env; + int status; if (id_buf == 0) id_buf = vstring_alloc(10); @@ -347,7 +354,8 @@ MAIL_STREAM *mail_stream_command(const char *command) if (attr_scan(stream, ATTR_FLAG_MISSING, ATTR_TYPE_STR, MAIL_ATTR_QUEUEID, id_buf, 0) != 1) { - vstream_pclose(stream); + if ((status = vstream_pclose(stream)) != 0) + msg_warn("command \"%s\" exited with status %d", command, status); return (0); } else { info = (MAIL_STREAM *) mymalloc(sizeof(*info)); diff --git a/postfix/src/global/mail_version.h b/postfix/src/global/mail_version.h index b56b2e540..635522778 100644 --- a/postfix/src/global/mail_version.h +++ b/postfix/src/global/mail_version.h @@ -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 "20031223" +#define MAIL_RELEASE_DATE "20031224" #define VAR_MAIL_VERSION "mail_version" #define DEF_MAIL_VERSION "2.0.16-" MAIL_RELEASE_DATE diff --git a/postfix/src/master/master_sig.c b/postfix/src/master/master_sig.c index 4475e43b1..bef31e0f6 100644 --- a/postfix/src/master/master_sig.c +++ b/postfix/src/master/master_sig.c @@ -121,8 +121,19 @@ static void master_sigchld(int sig, int code, struct sigcontext * scp) static void master_sigchld(int unused_sig) { + int saved_errno = errno; + + /* + * WARNING WARNING WARNING. + * + * This code runs at unpredictable moments, as a signal handler. Don't put + * any code here other than for setting a global flag, or code that is + * intended to be run within a signal handler. Restore errno in case we + * are interrupting the epilog of a failed system call. + */ if (write(SIG_PIPE_WRITE_FD, "", 1) != 1) msg_warn("write to SIG_PIPE_WRITE_FD failed: %m"); + errno = saved_errno; } /* master_sig_event - called upon return from select() */ diff --git a/postfix/src/postsuper/postsuper.c b/postfix/src/postsuper/postsuper.c index 6e986ce49..3b01c960e 100644 --- a/postfix/src/postsuper/postsuper.c +++ b/postfix/src/postsuper/postsuper.c @@ -81,9 +81,10 @@ /* As a safety measure, the word \fBALL\fR must be specified in upper /* case. /* .sp -/* Note: mail that is put "on hold" will not expire when its +/* Note: while mail is "on hold" it will not expire when its /* time in the queue exceeds the \fBmaximal_queue_lifetime\fR -/* setting. +/* setting. It becomes subject to expiration after it is +/* released from "hold". /* .IP "\fB-H \fIqueue_id\fR" /* Release mail that was put "on hold". /* Move one message with the named queue ID from the named diff --git a/postfix/src/smtp/smtp.c b/postfix/src/smtp/smtp.c index d52471c6a..0190e3472 100644 --- a/postfix/src/smtp/smtp.c +++ b/postfix/src/smtp/smtp.c @@ -189,7 +189,7 @@ /* \fBdefault_destination_recipient_limit\fR parameter. /* .IP \fBsmtp_mx_address_limit\fR /* An upper bound on the total number of MX (mail exchanger) IP -/* addresses that that can result from mail exchanger lookups. +/* addresses that can result from mail exchanger lookups. /* .sp /* Specify zero to disable the limit. /* .sp diff --git a/postfix/src/util/auto_clnt.c b/postfix/src/util/auto_clnt.c index e78ec1946..6bd6e2eb8 100644 --- a/postfix/src/util/auto_clnt.c +++ b/postfix/src/util/auto_clnt.c @@ -212,8 +212,9 @@ VSTREAM *auto_clnt_access(AUTO_CLNT *auto_clnt) if (auto_clnt->vstream == 0) { auto_clnt_open(auto_clnt); } else { - event_request_timer(auto_clnt_event, (char *) auto_clnt, - auto_clnt->max_idle); + if (auto_clnt->max_idle > 0) + event_request_timer(auto_clnt_event, (char *) auto_clnt, + auto_clnt->max_idle); } return (auto_clnt->vstream); }