]> git.ipfire.org Git - thirdparty/postfix.git/commitdiff
snapshot-19991110
authorWietse Venema <wietse@porcupine.org>
Wed, 10 Nov 1999 05:00:00 +0000 (00:00 -0500)
committerWietse Venema <wietse@porcupine.org>
Thu, 17 Jan 2013 23:09:46 +0000 (18:09 -0500)
95 files changed:
postfix/.indent.pro
postfix/0README
postfix/HISTORY
postfix/INSTALL.sh
postfix/RELEASE_NOTES
postfix/auxiliary/rmail/rmail [moved from postfix/aux/rmail/rmail with 100% similarity]
postfix/bounce/.indent.pro
postfix/cleanup/.indent.pro
postfix/cleanup/cleanup_message.c
postfix/conf/sample-aliases.cf
postfix/conf/sample-canonical.cf
postfix/conf/sample-debug.cf
postfix/conf/sample-ldap.cf
postfix/conf/sample-local.cf
postfix/conf/sample-misc.cf
postfix/conf/sample-rate.cf
postfix/conf/sample-relocated.cf
postfix/conf/sample-resource.cf
postfix/conf/sample-rewrite.cf
postfix/conf/sample-smtp.cf
postfix/conf/sample-smtpd.cf
postfix/conf/sample-transport.cf
postfix/conf/sample-virtual.cf
postfix/dns/.indent.pro
postfix/dns/dns_lookup.c
postfix/error/.indent.pro
postfix/fsstone/.indent.pro
postfix/global/.indent.pro
postfix/global/bounce.h
postfix/global/mail_copy.c
postfix/global/mail_copy.h
postfix/global/mail_params.h
postfix/global/mail_version.h
postfix/global/rewrite_clnt.c
postfix/html/faq.html
postfix/html/index.html
postfix/html/pipe.8.html
postfix/html/postalias.1.html
postfix/html/postmap.1.html
postfix/html/sendmail.1.html
postfix/local/.indent.pro
postfix/local/local.h
postfix/man/man1/postalias.1
postfix/man/man1/postmap.1
postfix/man/man1/sendmail.1
postfix/man/man8/pipe.8
postfix/master/.indent.pro
postfix/master/Makefile.in
postfix/master/master.c
postfix/master/multi_server.c
postfix/master/single_server.c
postfix/master/trigger_server.c
postfix/pickup/.indent.pro
postfix/pickup/pickup.c
postfix/pipe/.indent.pro
postfix/pipe/pipe.c
postfix/postalias/.indent.pro
postfix/postalias/postalias.c
postfix/postcat/.indent.pro
postfix/postconf/.indent.pro
postfix/postdrop/.indent.pro
postfix/postfix/.indent.pro
postfix/postkick/.indent.pro
postfix/postlock/.indent.pro
postfix/postlock/Makefile.in
postfix/postlog/.indent.pro
postfix/postmap/.indent.pro
postfix/postmap/postmap.c
postfix/postsuper/.indent.pro
postfix/qmgr/.indent.pro
postfix/qmgr/qmgr.c
postfix/qmgr/qmgr_active.c
postfix/qmgr/qmgr_message.c
postfix/sendmail/.indent.pro
postfix/sendmail/sendmail.c
postfix/showq/.indent.pro
postfix/smtp/.indent.pro
postfix/smtpd/.indent.pro
postfix/smtpd/Makefile.in
postfix/smtpd/smtpd.c
postfix/smtpd/smtpd_check.c
postfix/smtpd/smtpd_token.c
postfix/smtpd/smtpd_token.h
postfix/smtpd/smtpd_token.in [new file with mode: 0644]
postfix/smtpd/smtpd_token.ref [new file with mode: 0644]
postfix/smtpstone/.indent.pro
postfix/trivial-rewrite/.indent.pro
postfix/util/.indent.pro
postfix/util/Makefile.in
postfix/util/dict_ldap.c
postfix/util/dict_unix.c
postfix/util/inet_addr_local.c
postfix/util/timed_wait.c
postfix/util/watchdog.c [new file with mode: 0644]
postfix/util/watchdog.h [new file with mode: 0644]

index b65f4ec2434c41cc91fa8bdb535e382d249f7794..6819c7dcae5b7b74d39edf411b66b8a17d1f9100 100644 (file)
@@ -87,7 +87,6 @@
 -TSINGLE_SERVER
 -TSINK_COMMAND
 -TSINK_STATE
--TSMTPD_REST_TABLE
 -TSMTPD_STATE
 -TSMTPD_TOKEN
 -TSMTP_ADDR
 -TVSTREAM_POPEN_ARGS
 -TVSTRING
 -TWAIT_STATUS_T
+-TWATCHDOG
 -TWATCH_FD
index b09fc924709addc52b1e2ce892e1c2c072e8a27d..083ebe270bf3b58bf1385b22bb17254ce454db24 100644 (file)
@@ -151,6 +151,7 @@ Test programs:
 
 Miscellaneous:
 
+    auxiliary/         Auxiliary software etc.
     bin/               Postfix command executables
     conf/              Sample configuration files
     include/           Installed include files
index 4a63ed4740873effd7ee779183acf9e98da23875..2f8367cb26b0681c8662d62bf65cbca5d4b1a944 100644 (file)
@@ -3053,7 +3053,7 @@ Apologies for any names omitted.
 19990908
 
        Portability: Unixware has <sysexits.h> only after sendmail
-       is installed. Changed postlock.c to use global/sys_exists.h.
+       is installed. Changed postlock.c to use global/sys_exits.h.
 
 19990909
 
@@ -3091,6 +3091,87 @@ Apologies for any names omitted.
        File: smtpd/smtpd_access.c.
 
        Cleanup: removed spurious sender address checks for <>.
+       File: smtpd/smtpd_check.c.
 
        Cleanup: the smtp client now consistently logs host[address]
        for all connection attempts.
+
+19990919
+
+       Feature: in an SMTPD access map, an all-numeric right-hand
+       side now means OK, for better cooperation with out-of-band
+       authentication mechanisms.
+
+19990922
+
+       Security: recipient addresses must not start with '-', in
+       order to protect external commands. The old behavior is
+       re-instated when main.cf specifies:  "allow_min_user =
+       yes".  Credits to Mads Kiilerich @ Kiilerich.com.  File:
+       qmgr/qmgr_message.c.
+
+       Bugfix: after 19990831, the queue manager would throw away
+       defer logs after deferring mail to known-to-be-dead hosts
+       or message transports. This means that in some cases, mailq
+       would not show why mail is delayed, and that delayed mail
+       could be sent back with recipients missing from the error
+       report. Reported by Giulio Orsero @ tiscalinet.it.
+
+19990923
+
+       Bugfix: the above bugfix broke bounces of mail with bad
+       address syntax and relocated users. Problem diagnosed by
+       Dick Porter @ acm.org.
+
+       Documentation: added DO NOT EDIT THIS FILE. EDIT MAIN.CF
+       INSTEAD notices to the sample-xxx.cf files.
+
+19991007
+
+       Compatibility: ignore the sendmail -U (initial user
+       submission) option. Thomas Quinot @ cuivre.fr.eu.org.
+
+19991103
+
+       Code cleanup: don't send postmaster notifications when an
+       SMTP client sends a DATA command while no recipients were
+       accepted.  This can happen when a pipelined client runs
+       into an UCE block. File:  smtpd/smtpd.c.
+
+19991104
+
+       Robustness: do not apply UCE header checks to mail that is
+       generated by Postfix (bounces, forwarded mail etc.).  Files:
+       smtpd/smtpd.c, pickup/pickup.c, cleanup/cleanup_message.c.
+
+       Robustness: new generic watchdog module that can deal with
+       clocks that jump occasionally. Files: util/watchdog.c,
+       master/master.c, master/{single,multi,trigger}_server.c.
+       This hopefully ends the false watchdog alarms that happen
+       when clocks are set or when laptops are resumed.
+
+       Code cleanup: BSMTP requires dot quoting as per RFC 821.
+       Based on code by Florian Lohoff @ rfc822.org. Files:
+       global/mail_copy.[hc], pipe/pipe.c.
+
+19991105
+
+       Bugfix: the crufty code in inet_addr_local() did not find
+       IP aliases. File: util/inet_addr_local.c.
+
+       Portability: the INSTALL.sh utility did not find users or
+       groups in NIS or Netinfo tables. The script no longer
+       searches the /etc/passwd and /etc/group files.  Instead it
+       now queries the unix:passwd.byname and unix:group.byname
+       maps.  For this, a -q (query) option was added to postmap
+       (and to postalias, for symmetry).  Files: util/dict_unix.c,
+       postalias/postalias.c, postmap/postmap.c, INSTALL.sh.
+
+       Bugfix: LDAP lookup timeout settings were ignored. Patch
+       by John Hensley. File: util/dict_ldap.c.
+
+19991110
+
+       Code cleanup: greatly simplified the SMTPD command parser
+       and somewhat simplified the code that groks RFC 822-style
+       address syntax in MAIL FROM and RCPT TO commands.
index fb3bd2c6228c696a4e515ea2347a1461379d96b9..0b740f319cd4071c7ce24d8f92b1db5261384ae2 100644 (file)
@@ -28,9 +28,9 @@ your changes interactively.
     command_directory - directory with Postfix administrative commands.
     queue_directory - directory with Postfix queues.
 
-    sendmail_path - full pathname of the sendmail command.
-    newaliases_path - full pathname of the newaliases command.
-    mailq_path - full pathname of the mailq command.
+    sendmail_path - full pathname of the Postfix sendmail command.
+    newaliases_path - full pathname of the Postfix newaliases command.
+    mailq_path - full pathname of the Postfix mailq command.
 
     owner - owner of Postfix queue files.
 
@@ -138,7 +138,7 @@ do
    esac
 done
 
-grep "^$owner:" /etc/passwd >/dev/null || {
+bin/postmap -c ./conf -q "$owner" unix:passwd.byname >/dev/null || {
     echo "$owner needs an entry in the passwd file" 1>&2
     echo "Remember, $owner must have a dedicated user id and group id." 1>&2
     exit 1
@@ -146,7 +146,7 @@ grep "^$owner:" /etc/passwd >/dev/null || {
 
 case $setgid in
 no) ;;
- *) grep "^$setgid:" /etc/group >/dev/null || {
+ *) bin/postmap -c ./conf -q "$setgid" unix:group.byname >/dev/null || {
        echo "$setgid needs an entry in the group file" 1>&2
        echo "Remember, $setgid must have a dedicated group id." 1>&2
        exit 1
@@ -174,7 +174,7 @@ rm -f junk
 
 # Install files. Be careful to not copy over running programs.
 
-for file in `ls libexec | grep '^[a-z]'`
+for file in `ls libexec`
 do
     compare_or_replace a+x,go-w libexec/$file $daemon_directory/$file || exit 1
 done
@@ -199,7 +199,7 @@ test -f $config_directory/main.cf || {
        s;^daemon_directory .*;daemon_directory = $daemon_directory;
        s;^command_directory .*;command_directory = $command_directory;
        s;^queue_directory .*;queue_directory = $queue_directory;
-       s;^mail_owner .*;mail_owner = $mail_owner;
+       s;^mail_owner .*;mail_owner = $owner;
     " conf/main.cf >$config_directory/main.cf || exit 1
 
     echo "Warning: you still need to edit myorigin/mydestination in" 1>&2
index f1792aba7e799d83add2b0be988390cc9c7e30a2..dee14e3e5c8872160cf6b6cfc1886fec780093aa 100644 (file)
@@ -1,11 +1,15 @@
-Incompatible changes with snapshot 19990911
+Incompatible changes with snapshot XXXXXXXX
 ===========================================
 
+- Recipient addresses may no longer begin with `-'. In order to
+reinstate the old behavior, specify "allow_min_user = yes" in
+main.cf.
+
 - You can not longer use virtual, canonical or aliases tables as
 SMTPD access control tables. Use the permit_recipient_map feature
 instead. The loss is compensated for.
 
-Major changes with snapshot 19990911
+Major changes with snapshot XXXXXXXX
 ====================================
 
 - Per-client/helo/sender/recipient UCE restrictions: you can now
@@ -23,7 +27,7 @@ UCE restrictions.  For example in main.cf:
     restrictive = reject_unknown_sender reject_unknown_client ...
     permissive = permit
 
-Then use "restrictive" or "restrictive" on the right-hand side of
+Then use "restrictive" or "permissive" on the right-hand side of
 your per-client/helo/sender/recipient SMTPD access tables.
 
 - Reject mail for non-existent local accounts. You can now use
@@ -51,8 +55,8 @@ permit_mynetworks, because permit_mynetworks accepts mail for
 non-existent local recipients.
 
 Unfortunately, permit_recipient_map does not combine well with
-check_relay_domains, because check_relay_domains permits either
-rejects mail, or accepts mail for non-existent local recipients.
+check_relay_domains, because check_relay_domains either rejects
+mail, or accepts mail regardless of whether a recipient exists.
 
 Incompatible changes with postfix-19990906
 ==========================================
index b65f4ec2434c41cc91fa8bdb535e382d249f7794..6819c7dcae5b7b74d39edf411b66b8a17d1f9100 100644 (file)
@@ -87,7 +87,6 @@
 -TSINGLE_SERVER
 -TSINK_COMMAND
 -TSINK_STATE
--TSMTPD_REST_TABLE
 -TSMTPD_STATE
 -TSMTPD_TOKEN
 -TSMTP_ADDR
 -TVSTREAM_POPEN_ARGS
 -TVSTRING
 -TWAIT_STATUS_T
+-TWATCHDOG
 -TWATCH_FD
index b65f4ec2434c41cc91fa8bdb535e382d249f7794..6819c7dcae5b7b74d39edf411b66b8a17d1f9100 100644 (file)
@@ -87,7 +87,6 @@
 -TSINGLE_SERVER
 -TSINK_COMMAND
 -TSINK_STATE
--TSMTPD_REST_TABLE
 -TSMTPD_STATE
 -TSMTPD_TOKEN
 -TSMTP_ADDR
 -TVSTREAM_POPEN_ARGS
 -TVSTRING
 -TWAIT_STATUS_T
+-TWATCHDOG
 -TWATCH_FD
index 2a862e54cc3cee641d2845a07a98cf30656873f0..25c55bcf972cd46385c3c63369835f1ebf864be6 100644 (file)
@@ -234,7 +234,7 @@ static void cleanup_header(void)
     if (msg_verbose)
        msg_info("%s: '%s'", myname, vstring_str(cleanup_header_buf));
 
-    if (cleanup_header_checks) {
+    if ((cleanup_flags & CLEANUP_FLAG_FILTER) && cleanup_header_checks) {
        char   *header = vstring_str(cleanup_header_buf);
        const char *value;
 
index b75c94261537261111d04b78085da46db8b35c81..80dd4a6e82ecaefa1fa73494ad4a55b7ce7bf148 100644 (file)
@@ -1,3 +1,6 @@
+# DO NOT EDIT THIS FILE. EDIT THE MAIN.CF FILE INSTEAD. THE STUFF
+# HERE JUST SERVES AS AN EXAMPLE.
+#
 # This file contains example settings of Postfix configuration
 # parameters that control alias database lookups.
 #
index 65c8fdd84bc14d6747858e0b883fe01c92685bc6..1e3b0a57c8c07bce02a8921b65294d9fd19a2d4f 100644 (file)
@@ -1,3 +1,6 @@
+# DO NOT EDIT THIS FILE. EDIT THE MAIN.CF FILE INSTEAD. THE STUFF
+# HERE JUST SERVES AS AN EXAMPLE.
+#
 # This file contains example settings of Postfix configuration
 # parameters that control canonical address map lookups.
 
index 056e22fbf2c495e590bf43f0ad484705d394222d..c8a8e97a66c8e941e34d8fe4c808db8c012597a1 100644 (file)
@@ -1,3 +1,6 @@
+# DO NOT EDIT THIS FILE. EDIT THE MAIN.CF FILE INSTEAD. THE STUFF
+# HERE JUST SERVES AS AN EXAMPLE.
+#
 # This file contains example settings of Postfix configuration
 # parameters that control debugging features.
 
index f68aee6a50e118e926f317e85cf36e0fe79678d6..0acb8682ec7fac268d6e99028dfe95b25c50a797 100644 (file)
@@ -1,3 +1,6 @@
+# DO NOT EDIT THIS FILE. EDIT THE MAIN.CF FILE INSTEAD. THE STUFF
+# HERE JUST SERVES AS AN EXAMPLE.
+#
 # This file contains example settings of Postfix configuration
 # parameters that control LDAP lookups. Source code for LDAP
 # lookup is available separately from http://www.postfix.org/
index b07c1c9d65c59106057e4b992892bcb731a14ce2..2cb6ff6d4a7f1577c1430aa56f851c8edbd47001 100644 (file)
@@ -1,3 +1,6 @@
+# DO NOT EDIT THIS FILE. EDIT THE MAIN.CF FILE INSTEAD. THE STUFF
+# HERE JUST SERVES AS AN EXAMPLE.
+#
 # This file contains example settings of Postfix configuration
 # parameters that control local delivery.
 # 
index f7a990529fdf9063485a2969ab4ce14aac905e80..99d809c668ff030cbcc0c75915a73508452a2506 100644 (file)
@@ -1,3 +1,6 @@
+# DO NOT EDIT THIS FILE. EDIT THE MAIN.CF FILE INSTEAD. THE STUFF
+# HERE JUST SERVES AS AN EXAMPLE.
+#
 # This file contains example settings for miscellaneous Postfix
 # configuration parameters.
 
index e95094dcd82553cc3fc9936fb986f776123dec30..28ccc19b24b1ba83376a770cfc6c807b47acd534 100644 (file)
@@ -1,3 +1,6 @@
+# DO NOT EDIT THIS FILE. EDIT THE MAIN.CF FILE INSTEAD. THE STUFF
+# HERE JUST SERVES AS AN EXAMPLE.
+#
 # This file contains example settings of Postfix parameters that
 # control delivery rates.
 
index aeea31ad028f12be5bfd292b3ec1466372ccaf1a..1c83ca53877a5b11822e5fe3c783a9cf057875be 100644 (file)
@@ -1,3 +1,6 @@
+# DO NOT EDIT THIS FILE. EDIT THE MAIN.CF FILE INSTEAD. THE STUFF
+# HERE JUST SERVES AS AN EXAMPLE.
+#
 # This file contains example settings of Postfix configuration
 # parameters that control relocated database lookups.
 
index 846355cdc291ca120d46f3466e30e8723afe1c01..aecc31200f4a85ddb2c2f1ed72a32a952d8193ff 100644 (file)
@@ -1,3 +1,6 @@
+# DO NOT EDIT THIS FILE. EDIT THE MAIN.CF FILE INSTEAD. THE STUFF
+# HERE JUST SERVES AS AN EXAMPLE.
+#
 # This file contains example settings of general Postfix resource
 # control parameters.
 # 
index 16ab6da8e382a468aaaea20fa8509f05069fb3be..5b5f3a5848c155c4887ac81d03ebc8d736040a73 100644 (file)
@@ -1,3 +1,6 @@
+# DO NOT EDIT THIS FILE. EDIT THE MAIN.CF FILE INSTEAD. THE STUFF
+# HERE JUST SERVES AS AN EXAMPLE.
+#
 # This file contains example settings of Postfix configuration
 # parameters that control address rewriting.
 
index 882f7394d20fd0a6aef1753d8b041353d3a859f2..084c0ad6d183a802d0392c956ad106839ce8e386 100644 (file)
@@ -1,3 +1,6 @@
+# DO NOT EDIT THIS FILE. EDIT THE MAIN.CF FILE INSTEAD. THE STUFF
+# HERE JUST SERVES AS AN EXAMPLE.
+#
 # This file contains example settings of Postfix configuration
 # parameters that control the SMTP client program.
 
index 1e2fd83a9cb758b999211d3926901776b5494887..521e9c45a0294fef8a609f686dd65d6de368ab5b 100644 (file)
@@ -1,3 +1,6 @@
+# DO NOT EDIT THIS FILE. EDIT THE MAIN.CF FILE INSTEAD. THE STUFF
+# HERE JUST SERVES AS AN EXAMPLE.
+#
 # This file contains example settings of Postfix configuration parameters
 # that control the SMTP server program.
 
index 0600dc30c155d41976c50582ade557b616284ec6..8ecd2b56bc2206d735e0f130e73a7a3528cb7113 100644 (file)
@@ -1,3 +1,6 @@
+# DO NOT EDIT THIS FILE. EDIT THE MAIN.CF FILE INSTEAD. THE STUFF
+# HERE JUST SERVES AS AN EXAMPLE.
+#
 # This file contains example settings of Postfix configuration
 # parameters that control the optional transport table lookups.
 
index bfea4df494101165d6b7d3e46639d9f437e5af72..3bebaab000e4ff45356410fa236f47b8b9c5b178 100644 (file)
@@ -1,3 +1,6 @@
+# DO NOT EDIT THIS FILE. EDIT THE MAIN.CF FILE INSTEAD. THE STUFF
+# HERE JUST SERVES AS AN EXAMPLE.
+#
 # This file contains example settings of Postfix configuration
 # parameters that control virtual database lookups.
 
index b65f4ec2434c41cc91fa8bdb535e382d249f7794..6819c7dcae5b7b74d39edf411b66b8a17d1f9100 100644 (file)
@@ -87,7 +87,6 @@
 -TSINGLE_SERVER
 -TSINK_COMMAND
 -TSINK_STATE
--TSMTPD_REST_TABLE
 -TSMTPD_STATE
 -TSMTPD_TOKEN
 -TSMTP_ADDR
 -TVSTREAM_POPEN_ARGS
 -TVSTRING
 -TWAIT_STATUS_T
+-TWATCHDOG
 -TWATCH_FD
index 865e6c64001b85b2c1e6d0bc738cd1a8b59b5098..90344cd5272a4ed476416bc854a53fd21ae39902 100644 (file)
@@ -163,7 +163,10 @@ static int dns_query(const char *name, int type, int flags,
      * only if the name server told us so.
      */
     len = res_search((char *) name, C_IN, type, reply->buf, sizeof(reply->buf));
+    reply_header = (HEADER *) reply->buf;
     if (len < 0) {
+       if (reply_header->rcode == SERVFAIL)
+           h_errno = NO_RECOVERY;
        if (why)
            vstring_sprintf(why, "Name service error for domain %s: %s",
                            name, dns_strerror(h_errno));
@@ -189,7 +192,6 @@ static int dns_query(const char *name, int type, int flags,
      */
     if ((reply->end = reply->buf + len) > reply->buf + sizeof(reply->buf))
        reply->end = reply->buf + sizeof(reply->buf);
-    reply_header = (HEADER *) reply->buf;
     reply->query_start = reply->buf + sizeof(HEADER);
     reply->answer_start = 0;
     reply->query_count = ntohs(reply_header->qdcount);
index b65f4ec2434c41cc91fa8bdb535e382d249f7794..6819c7dcae5b7b74d39edf411b66b8a17d1f9100 100644 (file)
@@ -87,7 +87,6 @@
 -TSINGLE_SERVER
 -TSINK_COMMAND
 -TSINK_STATE
--TSMTPD_REST_TABLE
 -TSMTPD_STATE
 -TSMTPD_TOKEN
 -TSMTP_ADDR
 -TVSTREAM_POPEN_ARGS
 -TVSTRING
 -TWAIT_STATUS_T
+-TWATCHDOG
 -TWATCH_FD
index b65f4ec2434c41cc91fa8bdb535e382d249f7794..6819c7dcae5b7b74d39edf411b66b8a17d1f9100 100644 (file)
@@ -87,7 +87,6 @@
 -TSINGLE_SERVER
 -TSINK_COMMAND
 -TSINK_STATE
--TSMTPD_REST_TABLE
 -TSMTPD_STATE
 -TSMTPD_TOKEN
 -TSMTP_ADDR
 -TVSTREAM_POPEN_ARGS
 -TVSTRING
 -TWAIT_STATUS_T
+-TWATCHDOG
 -TWATCH_FD
index b65f4ec2434c41cc91fa8bdb535e382d249f7794..6819c7dcae5b7b74d39edf411b66b8a17d1f9100 100644 (file)
@@ -87,7 +87,6 @@
 -TSINGLE_SERVER
 -TSINK_COMMAND
 -TSINK_STATE
--TSMTPD_REST_TABLE
 -TSMTPD_STATE
 -TSMTPD_TOKEN
 -TSMTP_ADDR
 -TVSTREAM_POPEN_ARGS
 -TVSTRING
 -TWAIT_STATUS_T
+-TWATCHDOG
 -TWATCH_FD
index d7cf2f1d98a72c79a5e69cd52eb0fbf2a03eccca..c1316b26c03eea12df1daf0f0de5a3e016420f7a 100644 (file)
@@ -39,6 +39,7 @@ extern int bounce_flush(int, const char *, const char *, const char *);
 #define BOUNCE_FLAG_NONE       0       /* no flags up */
 #define BOUNCE_FLAG_CLEAN      (1<<0)  /* remove log on error */
 #define BOUNCE_FLAG_COPY       (1<<1)  /* postmaster notice */
+#define BOUNCE_FLAG_VERP       (1<<2)  /* personalized bounce */
 
  /*
   * Backwards compatibility.
index 4116270d4f32128bb588829da2a3b5b7662e6875..e91bf8bf5f977c5c90d9751b75990293aea1a5d2 100644 (file)
@@ -33,7 +33,9 @@
 /*     The binary OR of zero or more of the following:
 /* .RS
 /* .IP MAIL_COPY_QUOTE
-/*     prepend a `>' character to lines beginning with `From '.
+/*     Prepend a `>' character to lines beginning with `From '.
+/* .IP MAIL_COPY_DOT
+/*     Prepend a `.' character to lines beginning with `.'.
 /* .IP MAIL_COPY_TOFILE
 /*     On systems that support this, use fsync() to flush the
 /*     data to stable storage, and truncate the destination
@@ -166,6 +168,8 @@ int     mail_copy(const char *sender, const char *delivered,
        bp = vstring_str(buf);
        if ((flags & MAIL_COPY_QUOTE) && *bp == 'F' && !strncmp(bp, "From ", 5))
            VSTREAM_PUTC('>', dst);
+       if ((flags & MAIL_COPY_DOT) && *bp == '.')
+           VSTREAM_PUTC('.', dst);
        if (VSTRING_LEN(buf) && VSTREAM_FWRITE_BUF(dst, buf) != VSTRING_LEN(buf))
            break;
        if (type == REC_TYPE_NORM && VSTREAM_PUTC('\n', dst) == VSTREAM_EOF)
index ffa9682f075ea9436018d6df5f9cf936ddd20526..a121b90e1d60c28470b51446f524e848fb1143f2 100644 (file)
@@ -28,7 +28,10 @@ extern int mail_copy(const char *, const char *, VSTREAM *, VSTREAM *,
 #define MAIL_COPY_FROM         (1<<2)  /* prepend From_ */
 #define MAIL_COPY_DELIVERED    (1<<3)  /* prepend Delivered-To: */
 #define MAIL_COPY_RETURN_PATH  (1<<4)  /* prepend Return-Path: */
-#define MAIL_COPY_MBOX         (~0)    /* all turned on */
+#define MAIL_COPY_DOT          (1<<5)  /* escape dots - needed for bsmtp */
+#define MAIL_COPY_MBOX         (MAIL_COPY_FROM | MAIL_COPY_QUOTE | \
+                                   MAIL_COPY_TOFILE | MAIL_COPY_DELIVERED | \
+                                   MAIL_COPY_RETURN_PATH)
 #define MAIL_COPY_NONE         0       /* all turned off */
 
 /* LICENSE
index 1bdc983be383f034714320fd003db7eec32abdf5..6561a2d36e1d202cf9e31188cfeea97544a104f0 100644 (file)
@@ -207,6 +207,13 @@ extern char *var_db_type;
 #define DEF_ALWAYS_BCC         ""
 extern char *var_always_bcc;
 
+ /*
+  * Standards violation: permit RFC 822-style addresses in SMTP commands.
+  */
+#define VAR_ALLOW_RFC822_ENV   "allow_rfc822_envelopes"
+#define DEF_ALLOW_RFC822_ENV   1
+extern bool var_allow_rfc822_envelopes;
+
  /*
   * trivial rewrite/resolve service: mapping tables.
   */
@@ -833,6 +840,13 @@ extern bool var_soft_bounce;
 #define DEF_OWNREQ_SPECIAL             1
 extern bool var_ownreq_special;
 
+ /*
+  * Allow/disallow recipient addresses starting with `-'.
+  */
+#define VAR_ALLOW_MIN_USER             "allow_min_user"
+#define DEF_ALLOW_MIN_USER             0
+extern bool var_allow_min_user;
+
 extern void mail_params_init(void);
 
 /* LICENSE
index fff99cabfac0d2e134d60246e004aa461076112a..287086ab2edf4b801b405be7f843c78ecd2596a7 100644 (file)
@@ -15,7 +15,7 @@
   * Version of this program.
   */
 #define VAR_MAIL_VERSION       "mail_version"
-#define DEF_MAIL_VERSION       "Snapshot-19990912"
+#define DEF_MAIL_VERSION       "Snapshot-19991110"
 extern char *var_mail_version;
 
 /* LICENSE
index f301304e1e6efb4cfc9753a4b70bb0cfb9e25d33..0b03fb64fda6053ab10573674317e106b504afcf 100644 (file)
@@ -71,8 +71,8 @@
   */
 CLNT_STREAM *rewrite_clnt_stream = 0;
 
-VSTRING *last_addr;
-VSTRING *last_result;
+static VSTRING *last_addr;
+static VSTRING *last_result;
 
 /* rewrite_clnt - rewrite address to (transport, next hop, recipient) */
 
index 087b577df019c7230c9b1190d6bfce66fbacaa1a..57096651d05ab1529191877572f4a8798374e3fa 100644 (file)
 
 <li><a href="#timeouts">Mail fails with timeout or lost connection</a>
 
+<p>
+
 <li><a href="#bind">Undefined symbols: ___dn_expand, ___res_init etc.</a>
 
+<li><a href="#dbm">Undefined symbols: dbm_pagfno, dbm_dirfno etc.</a>
+
 <li><a href="#db">Using DB libraries on Solaris etc.</a>
 
 </ul>
@@ -1047,6 +1051,31 @@ Fix: use the right include files. For example:
 
 <hr>
 
+<a name="dbm"><h2>Undefined symbols: dbm_pagfno, dbm_dirfno etc.</h2></a>
+
+Question: When I build Postfix I get the following errors:
+
+<p>
+
+<pre>
+    Undefined                       first referenced
+     symbol                             in file
+       dbm_pagfno                          ../lib/libutil.a(dict_dbm.o)
+       dbm_dirfno                          ../lib/libutil.a(dict_dbm.o)
+</pre>
+
+<p>
+
+Answer: instead of using /usr/include/ndbm.h, you're building
+Postfix with some incompatible third-party ndbm.h include file,
+typically something in /usr/local/include.
+
+<p>
+
+Fix: get rid of the third-party ndbm.h include file.
+
+<hr>
+
 <a name="db"><h2>Using DB libraries on Solaris etc.</h2> </a>
 
 The old <b>dbm</b> UNIX database has severe limitations when you
@@ -1092,8 +1121,8 @@ include directory and of the object library.
 
 <p>
 
-One problem: older DB versions install a file <b>/usr/include/ndbm.h</b>
-that is incompatible with the one in <b>/usr/include</b>. Be sure
+One problem: older DB versions install a file <b>/usr/local/include/ndbm.h</b>
+that is incompatible with <b>/usr/include/ndbm.h</b>. Be sure
 to get rid of the bogus file, or the linker will fail to find
 <b>dbm_dirfno</b>.
 
index 9282ad42dbd83a59494ebfb3199c46b22d965cfc..6482cfbde0c9ff0ff7d4e89caec5121022e3756d 100644 (file)
@@ -28,10 +28,10 @@ First of all, thank you for your interest in the Postfix project.
 
 <p>
 
-What is Postfix? It is Wietse Venema's attempt to provide an
-alternative to the widely-used <a
-href="http://www.sendmail.org/">Sendmail</a> program.  Sendmail is
-responsible for an estimated 70% of all e-mail delivered on the
+What is Postfix? It is <a href="http://www.porcupine.org/wietse/">Wietse
+Venema's</a> attempt to provide an alternative to the widely-used
+<a href="http://www.sendmail.org/">Sendmail</a> program.  Sendmail
+is responsible for an estimated 70% of all e-mail delivered on the
 Internet.  With an estimated 100 million users, that's billions of
 messages daily.  A stunning number.
 
index 2e9f14f621beeb74daa8a61124fb13cbf5d0e6c9..eb63c2a48e56f3954516f98c94862d5933a2e387 100644 (file)
@@ -30,7 +30,7 @@ PIPE(8)                                                   PIPE(8)
        file at the end of a service definition.  The syntax is as
        follows:
 
-       <b>flags=FR</b>&gt; (optional)
+       <b>flags=FR.</b>&gt; (optional)
               Optional message processing flags.  By  default,  a
               message is copied unchanged.
 
@@ -43,7 +43,10 @@ PIPE(8)                                                   PIPE(8)
               <b>R</b>      Prepend  a  <b>Return-Path:</b> message header with
                      the envelope sender address.
 
-              &gt;      Prepend &gt; to lines starting  with  "<b>From</b>  ".
+              <b>.</b>      Prepend <b>.</b> to lines starting with  "<b>.</b>".  This
+                     is needed by, for example, <b>BSMTP</b> software.
+
+              &gt;      Prepend  &gt;  to  lines starting with "<b>From</b> ".
                      This is expected by, for example, <b>UUCP</b> soft-
                      ware.
 
@@ -51,15 +54,12 @@ PIPE(8)                                                   PIPE(8)
 
        <b>user</b>=<i>username</i>:<i>groupname</i>
               The external command is executed with the rights of
-              the  specified  <i>username</i>.   The software refuses to
-              execute commands with root privileges, or with  the
-              privileges  of  the mail system owner. If <i>groupname</i>
-              is specified, the corresponding group  ID  is  used
+              the specified <i>username</i>.  The  software  refuses  to
+              execute  commands with root privileges, or with the
+              privileges of the mail system owner.  If  <i>groupname</i>
+              is  specified,  the  corresponding group ID is used
               instead of the group ID of of <i>username</i>.
 
-       <b>argv</b>=<i>command</i>... (required)
-              The  command to be executed. This must be specified
-
 
 
                                                                 1
@@ -71,31 +71,33 @@ PIPE(8)                                                   PIPE(8)
 PIPE(8)                                                   PIPE(8)
 
 
+       <b>argv</b>=<i>command</i>... (required)
+              The command to be executed. This must be  specified
               as the last command attribute.  The command is exe-
               cuted  directly,  i.e.  without  interpretation  of
-              shell meta characters by  a  shell  command  inter-
+              shell  meta  characters  by  a shell command inter-
               preter.
 
               In  the  command  argument  vector,  the  following
               macros are recognized and replaced with correspond-
-              ing  information  from  the  Postfix  queue manager
+              ing information  from  the  Postfix  queue  manager
               delivery request:
 
               <b>${extension</b>}
-                     This macro expands to the extension part  of
-                     a  recipient  address.  For example, with an
+                     This  macro expands to the extension part of
+                     a recipient address.  For example,  with  an
                      address  <i>user+foo@domain</i>  the  extension  is
-                     <i>foo</i>.   A command-line argument that contains
-                     <b>${extension</b>} expands into as  many  command-
+                     <i>foo</i>.  A command-line argument that  contains
+                     <b>${extension</b>}  expands  into as many command-
                      line arguments as there are recipients.
 
               <b>${mailbox</b>}
-                     This  macro  expands  to  the complete local
-                     part of a recipient address.   For  example,
-                     with  an address <i>user+foo@domain</i> the mailbox
-                     is <i>user+foo</i>.  A command-line  argument  that
-                     contains  <b>${mailbox</b>}  expands  into  as many
-                     command-line arguments as there are  recipi-
+                     This macro expands  to  the  complete  local
+                     part  of  a recipient address.  For example,
+                     with an address <i>user+foo@domain</i> the  mailbox
+                     is  <i>user+foo</i>.   A command-line argument that
+                     contains <b>${mailbox</b>}  expands  into  as  many
+                     command-line  arguments as there are recipi-
                      ents.
 
               <b>${nexthop</b>}
@@ -103,28 +105,26 @@ PIPE(8)                                                   PIPE(8)
 
               <b>${recipient</b>}
                      This macro expands to the complete recipient
-                     address.   A command-line argument that con-
+                     address.  A command-line argument that  con-
                      tains <b>${recipient</b>} expands into as many com-
                      mand-line arguments as there are recipients.
 
               <b>${sender</b>}
-                     This macro expands to  the  envelope  sender
+                     This  macro  expands  to the envelope sender
                      address.
 
               <b>${user</b>}
                      This macro expands to the username part of a
-                     recipient address.   For  example,  with  an
+                     recipient  address.   For  example,  with an
                      address <i>user+foo@domain</i> the username part is
                      <i>user</i>.  A command-line argument that contains
-                     <b>${user</b>}  expands  into  as many command-line
+                     <b>${user</b>} expands into  as  many  command-line
                      arguments as there are recipients.
 
-       In addition to the  form  ${<i>name</i>},  the  forms  $<i>name</i>  and
-       $(<i>name</i>)  are also recognized.  Specify <b>$$</b> where a single <b>$</b>
+       In  addition  to  the  form  ${<i>name</i>},  the forms $<i>name</i> and
+       $(<i>name</i>) are also recognized.  Specify <b>$$</b> where a single  <b>$</b>
        is wanted.
 
-<b>DIAGNOSTICS</b>
-       Command exit status  codes  are  expected  to  follow  the
 
 
 
@@ -137,60 +137,60 @@ PIPE(8)                                                   PIPE(8)
 PIPE(8)                                                   PIPE(8)
 
 
-       conventions defined in &lt;<b>sysexits.h</b>&gt;.
+<b>DIAGNOSTICS</b>
+       Command  exit status codes are expected to follow the con-
+       ventions defined in &lt;<b>sysexits.h</b>&gt;.
 
-       Problems  and transactions are logged to <b>syslogd</b>(8).  Cor-
-       rupted message files are marked so that the queue  manager
+       Problems and transactions are logged to <b>syslogd</b>(8).   Cor-
+       rupted  message files are marked so that the queue manager
        can move them to the <b>corrupt</b> queue for further inspection.
 
 <b>SECURITY</b>
-       This program needs a dual personality  1)  to  access  the
-       private  Postfix  queue and IPC mechanisms, and 2) to exe-
+       This  program  needs  a  dual personality 1) to access the
+       private Postfix queue and IPC mechanisms, and 2)  to  exe-
        cute external commands as the specified user. It is there-
        fore security sensitive.
 
 <b>CONFIGURATION</b> <b>PARAMETERS</b>
-       The  following  <b>main.cf</b> parameters are especially relevant
-       to this program. See the Postfix <b>main.cf</b> file  for  syntax
-       details  and  for  default  values. Use the <b>postfix</b> <b>reload</b>
+       The following <b>main.cf</b> parameters are  especially  relevant
+       to  this  program. See the Postfix <b>main.cf</b> file for syntax
+       details and for default values.  Use  the  <b>postfix</b>  <b>reload</b>
        command after a configuration change.
 
 <b>Miscellaneous</b>
        <b>mail</b><i>_</i><b>owner</b>
-              The process privileges used while  not  running  an
+              The  process  privileges  used while not running an
               external command.
 
 <b>Resource</b> <b>controls</b>
-       In  the text below, <i>transport</i> is the first field in a <b>mas-</b>
+       In the text below, <i>transport</i> is the first field in a  <b>mas-</b>
        <b>ter.cf</b> entry.
 
        <i>transport_</i><b>destination</b><i>_</i><b>concurrency</b><i>_</i><b>limit</b>
               Limit the number of parallel deliveries to the same
-              destination,  for delivery via the named <i>transport</i>.
-              The default limit is taken from the  <b>default</b><i>_</i><b>desti-</b>
-              <b>nation</b><i>_</i><b>concurrency</b><i>_</i><b>limit</b>  parameter.   The limit is
+              destination, for delivery via the named  <i>transport</i>.
+              The  default limit is taken from the <b>default</b><i>_</i><b>desti-</b>
+              <b>nation</b><i>_</i><b>concurrency</b><i>_</i><b>limit</b> parameter.  The  limit  is
               enforced by the Postfix queue manager.
 
        <i>transport_</i><b>destination</b><i>_</i><b>recipient</b><i>_</i><b>limit</b>
-              Limit the number of recipients per  message  deliv-
-              ery,  for  delivery  via  the  named <i>transport</i>. The
-              default limit is taken  from  the  <b>default</b><i>_</i><b>destina-</b>
-              <b>tion</b><i>_</i><b>recipient</b><i>_</i><b>limit</b>   parameter.    The  limit  is
+              Limit  the  number of recipients per message deliv-
+              ery, for delivery  via  the  named  <i>transport</i>.  The
+              default  limit  is  taken from the <b>default</b><i>_</i><b>destina-</b>
+              <b>tion</b><i>_</i><b>recipient</b><i>_</i><b>limit</b>  parameter.   The   limit   is
               enforced by the Postfix queue manager.
 
        <i>transport_</i><b>time</b><i>_</i><b>limit</b>
-              Limit the time for delivery  to  external  command,
-              for  delivery  via the named <b>transport</b>. The default
-              limit is taken from the <b>command</b><i>_</i><b>time</b><i>_</i><b>limit</b>  parame-
-              ter.   The  limit  is enforced by the Postfix queue
+              Limit  the  time  for delivery to external command,
+              for delivery via the named <b>transport</b>.  The  default
+              limit  is taken from the <b>command</b><i>_</i><b>time</b><i>_</i><b>limit</b> parame-
+              ter.  The limit is enforced by  the  Postfix  queue
               manager.
 
 <b>SEE</b> <b>ALSO</b>
        <a href="bounce.8.html">bounce(8)</a> non-delivery status reports
        <a href="master.8.html">master(8)</a> process manager
        <a href="qmgr.8.html">qmgr(8)</a> queue manager
-       syslogd(8) system logging
-
 
 
 
@@ -203,8 +203,10 @@ PIPE(8)                                                   PIPE(8)
 PIPE(8)                                                   PIPE(8)
 
 
+       syslogd(8) system logging
+
 <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>
@@ -255,8 +257,6 @@ PIPE(8)                                                   PIPE(8)
 
 
 
-
-
 
 
 
index 051f475e8c5d0506fb5e71fceda18829c5545328..4e25fad1f3a3c1b9e72f4c20525efc8843582525 100644 (file)
@@ -9,15 +9,15 @@ POSTALIAS(1)                                         POSTALIAS(1)
        postalias - Postfix alias database maintenance
 
 <b>SYNOPSIS</b>
-       <b>postalias</b> [<b>-c</b> <i>config_dir</i>] [<b>-i</b>] [<b>-v</b>] [<b>-w</b>]
+       <b>postalias</b> [<b>-ivw</b>] [<b>-c</b> <i>config_dir</i>] [<b>-q</b> <i>key</i>]
        [<i>file_type</i>:]<i>file_name</i> ...
 
 <b>DESCRIPTION</b>
-       The  <b>postalias</b>  command  creates  a  new   Postfix   alias
-       database, or updates an existing one. The input and output
-       file formats are expected to be compatible  with  Sendmail
-       version  8, and are expected to be suitable for the use as
-       NIS alias maps.
+       The <b>postalias</b> command creates or queries one or more Post-
+       fix alias databases, or updates an existing one. The input
+       and output file formats are expected to be compatible with
+       Sendmail  version  8,  and are expected to be suitable for
+       the use as NIS alias maps.
 
        While a database update is in progress, signal delivery is
        postponed,  and  an exclusive, advisory, lock is placed on
@@ -35,8 +35,13 @@ POSTALIAS(1)                                         POSTALIAS(1)
               default, <b>postalias</b> creates a new database from  the
               entries in <b>file</b><i>_</i><b>name</b>.
 
+       <b>-q</b> <i>key</i> Search  the  specified  maps  for <i>key</i> and print the
+              first value found on the  standard  output  stream.
+              The exit status is non-zero if the requested infor-
+              mation was not found.
+
        <b>-v</b>     Enable verbose logging for debugging purposes. Mul-
-              tiple <b>-v</b> options  make  the  software  increasingly
+              tiple  <b>-v</b>  options  make  the software increasingly
               verbose.
 
        <b>-w</b>     Do  not  warn  about  duplicate  entries;  silently
@@ -47,19 +52,14 @@ POSTALIAS(1)                                         POSTALIAS(1)
        <i>file_type</i>
               The type of database to be produced.
 
-              <b>btree</b>  The  output   is   a   btree   file,   named
-                     <i>file_name</i><b>.db</b>.   This  is  available  only on
-                     systems with support for <b>db</b> databases.
-
-              <b>dbm</b>    The output  consists  of  two  files,  named
-                     <i>file_name</i><b>.pag</b>  and  <i>file_name</i><b>.dir</b>.   This is
-                     available only on systems with  support  for
-                     <b>dbm</b> databases.
-
-              <b>hash</b>   The   output   is   a   hashed  file,  named
+              <b>btree</b>  The   output   is   a   btree   file,  named
                      <i>file_name</i><b>.db</b>.  This  is  available  only  on
                      systems with support for <b>db</b> databases.
 
+              <b>dbm</b>    The  output  consists  of  two  files, named
+                     <i>file_name</i><b>.pag</b> and  <i>file_name</i><b>.dir</b>.   This  is
+                     available  only  on systems with support for
+
 
 
                                                                 1
@@ -71,17 +71,23 @@ POSTALIAS(1)                                         POSTALIAS(1)
 POSTALIAS(1)                                         POSTALIAS(1)
 
 
-              When  no  <i>file_type</i> is specified, the software uses
-              the database type specified via  the  <b>database</b><i>_</i><b>type</b>
-              configuration  parameter.   The  default  value for
+                     <b>dbm</b> databases.
+
+              <b>hash</b>   The  output  is   a   hashed   file,   named
+                     <i>file_name</i><b>.db</b>.   This  is  available  only on
+                     systems with support for <b>db</b> databases.
+
+              When no <i>file_type</i> is specified, the  software  uses
+              the  database  type specified via the <b>database</b><i>_</i><b>type</b>
+              configuration parameter.   The  default  value  for
               this parameter depends on the host environment.
 
        <i>file_name</i>
-              The name of the alias  database  source  file  when
+              The  name  of  the  alias database source file when
               rebuilding a database.
 
 <b>DIAGNOSTICS</b>
-       Problems  are logged to the standard error stream. No out-
+       Problems are logged to the standard error stream. No  out-
        put means no problems were detected. Duplicate entries are
        skipped and are flagged with a warning.
 
@@ -93,12 +99,12 @@ POSTALIAS(1)                                         POSTALIAS(1)
               Enable verbose logging for debugging purposes.
 
 <b>CONFIGURATION</b> <b>PARAMETERS</b>
-       The  following  <b>main.cf</b> parameters are especially relevant
-       to this program. See the Postfix <b>main.cf</b> file  for  syntax
+       The following <b>main.cf</b> parameters are  especially  relevant
+       to  this  program. See the Postfix <b>main.cf</b> file for syntax
        details and for default values.
 
        <b>database</b><i>_</i><b>type</b>
-              Default  alias database type. On many UNIX systems,
+              Default alias database type. On many UNIX  systems,
               the default type is either <b>dbm</b> or <b>hash</b>.
 
 <b>STANDARDS</b>
@@ -109,7 +115,7 @@ POSTALIAS(1)                                         POSTALIAS(1)
        <a href="sendmail.1.html">sendmail(1)</a> mail posting and compatibility interface.
 
 <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>
@@ -122,12 +128,6 @@ POSTALIAS(1)                                         POSTALIAS(1)
 
 
 
-
-
-
-
-
-
                                                                 2
 
 
index 34f88ded0e799a3069dc2f41d4a185608c2b473f..263a52fbdcf394e03840b0eb1c4e5b61e6ee2e0a 100644 (file)
@@ -9,13 +9,13 @@ POSTMAP(1)                                             POSTMAP(1)
        postmap - Postfix lookup table management
 
 <b>SYNOPSIS</b>
-       <b>postmap</b> [<b>-c</b> <i>config_dir</i>] [<b>-i</b>] [<b>-v</b>] [<b>-w</b>]
-       [<i>file_type</i>:]<i>file_name</i>
+       <b>postmap</b> [<b>-ivw</b>] [<b>-c</b> <i>config_dir</i>] [<b>-q</b> <i>key</i>]
+       [<i>file_type</i>:]<i>file_name</i> ...
 
 <b>DESCRIPTION</b>
-       The <b>postmap</b> command creates a new Postfix lookup table, or
-       updates  an existing one. The input and output formats are
-       expected to be compatible with:
+       The <b>postmap</b> command creates or queries one or more Postfix
+       lookup  tables,  or updates an existing one. The input and
+       output file formats are expected to be compatible with:
 
            <b>makemap</b> <i>file_type</i> <i>file_name</i> &lt; <i>file_name</i>
 
@@ -54,11 +54,11 @@ POSTMAP(1)                                             POSTMAP(1)
               default,  <b>postmap</b>  creates  a new database from the
               entries in <b>file</b><i>_</i><b>name</b>.
 
-       <b>-v</b>     Enable verbose logging for debugging purposes. Mul-
-              tiple  <b>-v</b>  options  make  the software increasingly
-              verbose.
+       <b>-q</b> <i>key</i> Search the specified maps for  <i>key</i>  and  print  the
+              first  value  found  on the standard output stream.
+              The exit status is non-zero if the requested infor-
+              mation was not found.
 
-       B-w    Do  not  warn  about  duplicate  entries;  silently
 
 
 
@@ -71,6 +71,11 @@ POSTMAP(1)                                             POSTMAP(1)
 POSTMAP(1)                                             POSTMAP(1)
 
 
+       <b>-v</b>     Enable verbose logging for debugging purposes. Mul-
+              tiple <b>-v</b> options  make  the  software  increasingly
+              verbose.
+
+       <b>-w</b>     Do  not  warn  about  duplicate  entries;  silently
               ignore them.
 
        Arguments:
@@ -78,25 +83,25 @@ POSTMAP(1)                                             POSTMAP(1)
        <i>file_type</i>
               The type of database to be produced.
 
-              <b>btree</b>  The  output  file  is  a  btree  file, named
-                     <i>file_name</i><b>.db</b>.  This  is  available  only  on
+              <b>btree</b>  The output  file  is  a  btree  file,  named
+                     <i>file_name</i><b>.db</b>.   This  is  available  only on
                      systems with support for <b>db</b> databases.
 
-              <b>dbm</b>    The  output  consists  of  two  files, named
-                     <i>file_name</i><b>.pag</b> and  <i>file_name</i><b>.dir</b>.   This  is
-                     available  only  on systems with support for
+              <b>dbm</b>    The output  consists  of  two  files,  named
+                     <i>file_name</i><b>.pag</b>  and  <i>file_name</i><b>.dir</b>.   This is
+                     available only on systems with  support  for
                      <b>dbm</b> databases.
 
-              <b>hash</b>   The output file  is  a  hashed  file,  named
-                     <i>file_name</i><b>.db</b>.   This  is  available  only on
+              <b>hash</b>   The  output  file  is  a  hashed file, named
+                     <i>file_name</i><b>.db</b>.  This  is  available  only  on
                      systems with support for <b>db</b> databases.
 
-              When no <i>file_type</i> is specified, the  software  uses
-              the  database  type specified via the <b>database</b><i>_</i><b>type</b>
+              When  no  <i>file_type</i> is specified, the software uses
+              the database type specified via  the  <b>database</b><i>_</i><b>type</b>
               configuration parameter.
 
        <i>file_name</i>
-              The name of  the  lookup  table  source  file  when
+              The  name  of  the  lookup  table  source file when
               rebuilding a database.
 
 <b>DIAGNOSTICS</b>
@@ -113,19 +118,14 @@ POSTMAP(1)                                             POSTMAP(1)
 
 <b>CONFIGURATION</b> <b>PARAMETERS</b>
        <b>database</b><i>_</i><b>type</b>
-              Default  output  database  type.  On many UNIX sys-
-              tems, the default database type is either  <b>hash</b>  or
+              Default output database type.  On  many  UNIX  sys-
+              tems,  the  default database type is either <b>hash</b> or
               <b>dbm</b>.
 
 <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>
-       Wietse Venema
-       IBM T.J. Watson Research
-       P.O. Box 704
-
 
 
                                                                 2
@@ -137,6 +137,10 @@ POSTMAP(1)                                             POSTMAP(1)
 POSTMAP(1)                                             POSTMAP(1)
 
 
+<b>AUTHOR(S)</b>
+       Wietse Venema
+       IBM T.J. Watson Research
+       P.O. Box 704
        Yorktown Heights, NY 10598, USA
 
 
@@ -185,10 +189,6 @@ POSTMAP(1)                                             POSTMAP(1)
 
 
 
-
-
-
-
 
 
 
index 77c41d3c6583edca24fd96184295b660ac77c00c..f3d9963ee7af3855ebb387a1bfd8f466f2a3b17a 100644 (file)
@@ -100,6 +100,9 @@ SENDMAIL(1)                                           SENDMAIL(1)
               Log  mailer  traffic.  Use  the <b>debug</b><i>_</i><b>peer</b><i>_</i><b>list</b> and
               <b>debug</b><i>_</i><b>peer</b><i>_</i><b>level</b> configuration parameters  instead.
 
+       <b>-U</b> (ignored)
+              Initial user submission.
+
        <b>-bd</b>    Go  into  daemon  mode.  This  mode of operation is
               implemented by executing the <b>postfix</b> <b>start</b> command.
 
@@ -121,9 +124,6 @@ SENDMAIL(1)                                           SENDMAIL(1)
               address where delivery problems are sent to, unless
               the message contains an <b>Errors-To:</b> message  header.
 
-       <b>-h</b> <i>hop_count</i> (ignored)
-              Hop  count limit. Use the <b>hopcount</b><i>_</i><b>limit</b> configura-
-              tion parameter instead.
 
 
 
@@ -137,6 +137,10 @@ SENDMAIL(1)                                           SENDMAIL(1)
 SENDMAIL(1)                                           SENDMAIL(1)
 
 
+       <b>-h</b> <i>hop_count</i> (ignored)
+              Hop  count limit. Use the <b>hopcount</b><i>_</i><b>limit</b> configura-
+              tion parameter instead.
+
        <b>-i</b> (ignored)
               Lines beginning with "." get special treatment only
               with <b>-bs</b>.
@@ -187,10 +191,6 @@ SENDMAIL(1)                                           SENDMAIL(1)
 
 <b>SECURITY</b>
        By design, this program is not  set-user  (or  group)  id.
-       However,  it  must  handle  data  from  untrusted users or
-       untrusted machines.  Thus, the usual precautions  need  to
-       be taken against malicious inputs.
-
 
 
 
@@ -203,6 +203,10 @@ SENDMAIL(1)                                           SENDMAIL(1)
 SENDMAIL(1)                                           SENDMAIL(1)
 
 
+       However,  it  must  handle  data  from  untrusted users or
+       untrusted machines.  Thus, the usual precautions  need  to
+       be taken against malicious inputs.
+
 <b>DIAGNOSTICS</b>
        Problems  are  logged  to  <b>syslogd</b>(8)  and to the standard
        error stream.
@@ -252,11 +256,7 @@ SENDMAIL(1)                                           SENDMAIL(1)
 
        <b>debug</b><i>_</i><b>peer</b><i>_</i><b>list</b>
               List  of  domain or network patterns. When a remote
-              host matches a pattern, increase the  verbose  log-
-              ging   level   by   the  amount  specified  in  the
-              <b>debug</b><i>_</i><b>peer</b><i>_</i><b>level</b> parameter.
-
-
+              host  matches  a  pattern,  increase  the   verbose
 
 
 
@@ -269,6 +269,9 @@ SENDMAIL(1)                                           SENDMAIL(1)
 SENDMAIL(1)                                           SENDMAIL(1)
 
 
+              logging  level  by  the  amount  specified  in  the
+              <b>debug</b><i>_</i><b>peer</b><i>_</i><b>level</b> parameter.
+
        <b>fork</b><i>_</i><b>attempts</b>
               Number of attempts to <b>fork</b>() a process before  giv-
               ing up.
@@ -320,13 +323,76 @@ SENDMAIL(1)                                           SENDMAIL(1)
        Wietse Venema
        IBM T.J. Watson Research
        P.O. Box 704
+
+
+
+                                                                5
+
+
+
+
+
+SENDMAIL(1)                                           SENDMAIL(1)
+
+
        Yorktown Heights, NY 10598, USA
 
 
 
 
 
-                                                                5
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+                                                                6
 
 
 </pre> </body> </html>
index b65f4ec2434c41cc91fa8bdb535e382d249f7794..6819c7dcae5b7b74d39edf411b66b8a17d1f9100 100644 (file)
@@ -87,7 +87,6 @@
 -TSINGLE_SERVER
 -TSINK_COMMAND
 -TSINK_STATE
--TSMTPD_REST_TABLE
 -TSMTPD_STATE
 -TSMTPD_TOKEN
 -TSMTP_ADDR
 -TVSTREAM_POPEN_ARGS
 -TVSTRING
 -TWAIT_STATUS_T
+-TWATCHDOG
 -TWATCH_FD
index 0332cebc091a19adce024419573279637dab6d57..b24376f7158f0f7d85623b3b40f313ef0a263c17 100644 (file)
@@ -125,12 +125,14 @@ typedef struct LOCAL_STATE {
 #define COPY_ATTR(attr)                attr.sender, attr.delivered, attr.fp
 
 #define MSG_LOG_STATE(m, p) \
-       msg_info("%s[%d]: local %s recip %s exten %s deliver %s", m, \
+       msg_info("%s[%d]: local %s recip %s exten %s deliver %s exp_from %s", \
+               m, \
                 p.level, \
                p.msg_attr.local ? p.msg_attr.local : "" , \
                p.msg_attr.recipient ? p.msg_attr.recipient : "", \
                p.msg_attr.extension ? p.msg_attr.extension : "", \
-               p.msg_attr.delivered ? p.msg_attr.delivered : "")
+               p.msg_attr.delivered ? p.msg_attr.delivered : "", \
+               p.msg_attr.exp_from ? p.msg_attr.exp_from : "")
 
  /*
   * "inner" nodes of the delivery graph.
index 63c092ea0d5eae02db6ea912a6df056e4d00c943..5315b5d225e98edd6b6c17b7863bec9f41e72cbc 100644 (file)
@@ -9,15 +9,15 @@ Postfix alias database maintenance
 .na
 .nf
 .fi
-\fBpostalias\fR [\fB-c \fIconfig_dir\fR] [\fB-i\fR] [\fB-v\fR]
-[\fB-w\fR] [\fIfile_type\fR:]\fIfile_name\fR ...
+\fBpostalias\fR [\fB-ivw\fR] [\fB-c \fIconfig_dir\fR] [\fB-q \fIkey\fR]
+[\fIfile_type\fR:]\fIfile_name\fR ...
 .SH DESCRIPTION
 .ad
 .fi
-The \fBpostalias\fR command creates a new Postfix alias database,
-or updates an existing one. The input and output file formats
-are expected to be compatible with Sendmail version 8, and are
-expected to be suitable for the use as NIS alias maps.
+The \fBpostalias\fR command creates or queries one or more Postfix
+alias databases, or updates an existing one. The input and output
+file formats are expected to be compatible with Sendmail version 8,
+and are expected to be suitable for the use as NIS alias maps.
 
 While a database update is in progress, signal delivery is
 postponed, and an exclusive, advisory, lock is placed on the
@@ -31,6 +31,10 @@ Read the \fBmain.cf\fR configuration file in the named directory.
 Incremental mode. Read entries from standard input and do not
 truncate an existing database. By default, \fBpostalias\fR creates
 a new database from the entries in \fBfile_name\fR.
+.IP "\fB-q \fIkey\fR"
+Search the specified maps for \fIkey\fR and print the first value
+found on the standard output stream. The exit status is non-zero
+if the requested information was not found.
 .IP \fB-v\fR
 Enable verbose logging for debugging purposes. Multiple \fB-v\fR
 options make the software increasingly verbose.
index 45f95d7f0cc96c994b0e02c1b8d3dc6abed5200c..f23c330d1ebdf03113e3c0396ee79aa94e5a76e8 100644 (file)
@@ -9,14 +9,14 @@ Postfix lookup table management
 .na
 .nf
 .fi
-\fBpostmap\fR [\fB-c \fIconfig_dir\fR] [\fB-i\fR] [\fB-v\fR]
-[\fB-w\fR] [\fIfile_type\fR:]\fIfile_name\fR
+\fBpostmap\fR [\fB-ivw\fR] [\fB-c \fIconfig_dir\fR] [\fB-q \fIkey\fR]
+[\fIfile_type\fR:]\fIfile_name\fR ...
 .SH DESCRIPTION
 .ad
 .fi
-The \fBpostmap\fR command creates a new Postfix lookup table,
-or updates an existing one. The input and output formats are
-expected to be compatible with:
+The \fBpostmap\fR command creates or queries one or more Postfix
+lookup tables, or updates an existing one. The input and output
+file formats are expected to be compatible with:
 
 .ti +4
 \fBmakemap \fIfile_type\fR \fIfile_name\fR < \fIfile_name\fR
@@ -50,10 +50,14 @@ Read the \fBmain.cf\fR configuration file in the named directory.
 Incremental mode. Read entries from standard input and do not
 truncate an existing database. By default, \fBpostmap\fR creates
 a new database from the entries in \fBfile_name\fR.
+.IP "\fB-q \fIkey\fR"
+Search the specified maps for \fIkey\fR and print the first value
+found on the standard output stream. The exit status is non-zero
+if the requested information was not found.
 .IP \fB-v\fR
 Enable verbose logging for debugging purposes. Multiple \fB-v\fR
 options make the software increasingly verbose.
-.IP \f\B-w\fR
+.IP \fB-w\fR
 Do not warn about duplicate entries; silently ignore them.
 .PP
 Arguments:
index 9c57eb740388f8110678c9afd22778bca80e4ed3..3a3becd2daa365dff4a3505c50b76ed218519699 100644 (file)
@@ -76,6 +76,8 @@ configuration parameter instead.
 .IP "\fB-X \fIlog_file\fR (ignored)"
 Log mailer traffic. Use the \fBdebug_peer_list\fR and
 \fBdebug_peer_level\fR configuration parameters instead.
+.IP "\fB-U\fR (ignored)"
+Initial user submission.
 .IP \fB-bd\fR
 Go into daemon mode. This mode of operation is implemented by
 executing the \fBpostfix start\fR command.
index f602d935bc52b8da7eff4d96a8bee3e711276bbc..18215d1d642c76b03183fb716e8141290c06e259 100644 (file)
@@ -30,7 +30,7 @@ to the \fBbounce\fR(8) or \fBdefer\fR(8) daemon as appropriate.
 .fi
 The external command attributes are given in the \fBmaster.cf\fR
 file at the end of a service definition.  The syntax is as follows:
-.IP "\fBflags=FR>\fR (optional)"
+.IP "\fBflags=FR.>\fR (optional)"
 Optional message processing flags. By default, a message is
 copied unchanged.
 .RS
@@ -42,6 +42,9 @@ flag also causes an empty line to be appended to the message.
 .IP \fBR\fR
 Prepend a \fBReturn-Path:\fR message header with the envelope sender
 address.
+.IP \fB.\fR
+Prepend \fB.\fR to lines starting with "\fB.\fR". This is needed
+by, for example, \fBBSMTP\fR software.
 .IP \fB>\fR
 Prepend \fB>\fR to lines starting with "\fBFrom \fR". This is expected
 by, for example, \fBUUCP\fR software.
index b65f4ec2434c41cc91fa8bdb535e382d249f7794..6819c7dcae5b7b74d39edf411b66b8a17d1f9100 100644 (file)
@@ -87,7 +87,6 @@
 -TSINGLE_SERVER
 -TSINK_COMMAND
 -TSINK_STATE
--TSMTPD_REST_TABLE
 -TSMTPD_STATE
 -TSMTPD_TOKEN
 -TSMTP_ADDR
 -TVSTREAM_POPEN_ARGS
 -TVSTRING
 -TWAIT_STATUS_T
+-TWATCHDOG
 -TWATCH_FD
index 9f9c4285ac69e1814e1e82f817e22a63651784c9..a499576de6830453eaa142b8b77c9516cc841750 100644 (file)
@@ -90,6 +90,7 @@ master.o: ../include/iostuff.h
 master.o: ../include/vstream.h
 master.o: ../include/stringops.h
 master.o: ../include/myflock.h
+master.o: ../include/watchdog.h
 master.o: ../include/mail_params.h
 master.o: ../include/debug_process.h
 master.o: ../include/mail_task.h
@@ -202,6 +203,7 @@ multi_server.o: ../include/stringops.h
 multi_server.o: ../include/sane_accept.h
 multi_server.o: ../include/myflock.h
 multi_server.o: ../include/safe_open.h
+multi_server.o: ../include/watchdog.h
 multi_server.o: ../include/mail_task.h
 multi_server.o: ../include/debug_process.h
 multi_server.o: ../include/mail_params.h
@@ -227,6 +229,7 @@ single_server.o: ../include/sane_accept.h
 single_server.o: ../include/myflock.h
 single_server.o: ../include/safe_open.h
 single_server.o: ../include/listen.h
+single_server.o: ../include/watchdog.h
 single_server.o: ../include/mail_params.h
 single_server.o: ../include/mail_task.h
 single_server.o: ../include/debug_process.h
@@ -252,6 +255,7 @@ trigger_server.o: ../include/sane_accept.h
 trigger_server.o: ../include/myflock.h
 trigger_server.o: ../include/safe_open.h
 trigger_server.o: ../include/listen.h
+trigger_server.o: ../include/watchdog.h
 trigger_server.o: ../include/mail_params.h
 trigger_server.o: ../include/mail_task.h
 trigger_server.o: ../include/debug_process.h
index c245fc4608157f4a585de087b33f46b40f51ec27..ecc70bf183dcdf752cb435993edbd54db5959eb7 100644 (file)
 #include <vstream.h>
 #include <stringops.h>
 #include <myflock.h>
+#include <watchdog.h>
 
 /* Global library. */
 
 
 #include "master.h"
 
-/* master_watchdog - something got stuck */
-
-static NORETURN master_watchdog(int unused_sig)
-{
-
-    /*
-     * This runs as a signal handler. We should not do anything that could
-     * involve memory managent, but exiting without explanation would be
-     * worse.
-     */
-    msg_fatal("watchdog timer");
-}
-
 int     main(int argc, char **argv)
 {
     static VSTREAM *lock_fp;
@@ -180,6 +168,7 @@ int     main(int argc, char **argv)
     int     test_lock = 0;
     int     fd_limit = open_limit(0);
     VSTRING *why;
+    WATCHDOG *watchdog;
 
     /*
      * Initialize.
@@ -332,13 +321,13 @@ int     main(int argc, char **argv)
      * multiple things at the same time, it really is all a single thread, so
      * that there are no concurrency conflicts within the master process.
      */
-    signal(SIGALRM, master_watchdog);
+    watchdog = watchdog_create(1000, (WATCHDOG_FN) 0, (char *) 0);
     for (;;) {
 #ifdef HAS_VOLATILE_LOCKS
        if (myflock(vstream_fileno(lock_fp), MYFLOCK_EXCLUSIVE) < 0)
            msg_fatal("refresh exclusive lock: %m");
 #endif
-       alarm(1000);                            /* same as trigger servers */
+       watchdog_start(watchdog);               /* same as trigger servers */
        event_loop(-1);
        if (master_gotsighup) {
            msg_info("reload configuration");
index 68a6fcda94bf16314fbcfc220da1c6cccecb8fc2..2af61dc9df174cef95783885404dc9632b4f58db 100644 (file)
 #include <myflock.h>
 #include <safe_open.h>
 #include <listen.h>
+#include <watchdog.h>
 
 /* Global library. */
 
@@ -185,19 +186,6 @@ static NORETURN multi_server_exit(void)
     exit(0);
 }
 
-/* multi_server_watchdog - something got stuck */
-
-static NORETURN multi_server_watchdog(int unused_sig)
-{
-
-    /*
-     * This runs as a signal handler. We should not do anything that could
-     * involve memory managent, but exiting without explanation would be
-     * worse.
-     */
-    msg_fatal("watchdog timer");
-}
-
 /* multi_server_abort - terminate after abnormal master exit */
 
 static void multi_server_abort(int unused_event, char *unused_context)
@@ -274,12 +262,6 @@ static void multi_server_accept_local(int unused_event, char *context)
     int     time_left = -1;
     int     fd;
 
-    /*
-     * Some buggy systems cause Postfix to lock up.
-     */
-    signal(SIGALRM, multi_server_watchdog);
-    alarm(var_daemon_timeout);
-
     /*
      * Be prepared for accept() to fail because some other process already
      * got the connection (the number of processes competing for clients is
@@ -314,12 +296,6 @@ static void multi_server_accept_inet(int unused_event, char *context)
     int     time_left = -1;
     int     fd;
 
-    /*
-     * Some buggy systems cause Postfix to lock up.
-     */
-    signal(SIGALRM, multi_server_watchdog);
-    alarm(var_daemon_timeout);
-
     /*
      * Be prepared for accept() to fail because some other process already
      * got the connection (the number of processes competing for clients is
@@ -369,6 +345,7 @@ NORETURN multi_server_main(int argc, char **argv, MULTI_SERVER_FN service,...)
     char   *lock_path;
     VSTRING *why;
     int     alone = 0;
+    WATCHDOG *watchdog;
 
     /*
      * Process environment options as early as we can.
@@ -585,11 +562,19 @@ NORETURN multi_server_main(int argc, char **argv, MULTI_SERVER_FN service,...)
     }
     event_enable_read(MASTER_STATUS_FD, multi_server_abort, (char *) 0);
     close_on_exec(MASTER_STATUS_FD, CLOSE_ON_EXEC);
+    watchdog = watchdog_create(var_daemon_timeout, (WATCHDOG_FN) 0, (char *) 0);
+
+    /*
+     * The event loop, at last.
+     */
     while (var_use_limit == 0 || use_count < var_use_limit || client_count > 0) {
+       if (multi_server_lock != 0) {
+           watchdog_stop(watchdog);
+           if (myflock(vstream_fileno(multi_server_lock), MYFLOCK_EXCLUSIVE) < 0)
+               msg_fatal("select lock: %m");
+       }
+       watchdog_start(watchdog);
        delay = loop ? loop(multi_server_name, multi_server_argv) : -1;
-       if (multi_server_lock != 0
-       && myflock(vstream_fileno(multi_server_lock), MYFLOCK_EXCLUSIVE) < 0)
-           msg_fatal("select lock: %m");
        event_loop(delay);
     }
     multi_server_exit();
index 744afc4200312594d1178f50a6c67ce22b2987ef..15e500e41739359976c24fa34c79a498898f9245 100644 (file)
 #include <myflock.h>
 #include <safe_open.h>
 #include <listen.h>
+#include <watchdog.h>
 
 /* Global library. */
 
@@ -175,19 +176,6 @@ static NORETURN single_server_exit(void)
     exit(0);
 }
 
-/* single_server_watchdog - something got stuck */
-
-static NORETURN single_server_watchdog(int unused_sig)
-{
-
-    /*
-     * This runs as a signal handler. We should not do anything that could
-     * involve memory managent, but exiting without explanation would be
-     * worse.
-     */
-    msg_fatal("watchdog timer");
-}
-
 /* single_server_abort - terminate after abnormal master exit */
 
 static void single_server_abort(int unused_event, char *unused_context)
@@ -245,12 +233,6 @@ static void single_server_accept_local(int unused_event, char *context)
     int     time_left = -1;
     int     fd;
 
-    /*
-     * Some buggy systems cause Postfix to lock up.
-     */
-    signal(SIGALRM, single_server_watchdog);
-    alarm(var_daemon_timeout);
-
     /*
      * Be prepared for accept() to fail because some other process already
      * got the connection. We use select() + accept(), instead of simply
@@ -284,12 +266,6 @@ static void single_server_accept_inet(int unused_event, char *context)
     int     time_left = -1;
     int     fd;
 
-    /*
-     * Some buggy systems cause Postfix to lock up.
-     */
-    signal(SIGALRM, single_server_watchdog);
-    alarm(var_daemon_timeout);
-
     /*
      * Be prepared for accept() to fail because some other process already
      * got the connection. We use select() + accept(), instead of simply
@@ -338,6 +314,7 @@ NORETURN single_server_main(int argc, char **argv, SINGLE_SERVER_FN service,...)
     char   *lock_path;
     VSTRING *why;
     int     alone = 0;
+    WATCHDOG *watchdog;
 
     /*
      * Process environment options as early as we can.
@@ -554,11 +531,19 @@ NORETURN single_server_main(int argc, char **argv, SINGLE_SERVER_FN service,...)
     }
     event_enable_read(MASTER_STATUS_FD, single_server_abort, (char *) 0);
     close_on_exec(MASTER_STATUS_FD, CLOSE_ON_EXEC);
+    watchdog = watchdog_create(var_daemon_timeout, (WATCHDOG_FN) 0, (char *) 0);
+
+    /*
+     * The event loop, at last.
+     */
     while (var_use_limit == 0 || use_count < var_use_limit) {
+       if (single_server_lock != 0) {
+           watchdog_stop(watchdog);
+           if (myflock(vstream_fileno(single_server_lock), MYFLOCK_EXCLUSIVE) < 0)
+               msg_fatal("select lock: %m");
+       }
+       watchdog_start(watchdog);
        delay = loop ? loop(single_server_name, single_server_argv) : -1;
-       if (single_server_lock != 0
-           && myflock(vstream_fileno(single_server_lock), MYFLOCK_EXCLUSIVE) < 0)
-           msg_fatal("select lock: %m");
        event_loop(delay);
     }
     single_server_exit();
index 791c101ea435c2f93b137b48ae5ee1af44ed59d0..7c777319c14f94e70252202f6e1cd934404454b9 100644 (file)
 #include <myflock.h>
 #include <safe_open.h>
 #include <listen.h>
+#include <watchdog.h>
 
 /* Global library. */
 
@@ -182,19 +183,6 @@ static NORETURN trigger_server_exit(void)
     exit(0);
 }
 
-/* trigger_server_watchdog - something got stuck */
-
-static NORETURN trigger_server_watchdog(int unused_sig)
-{
-
-    /*
-     * This runs as a signal handler. We should not do anything that could
-     * involve memory managent, but exiting without explanation would be
-     * worse.
-     */
-    msg_fatal("watchdog timer");
-}
-
 /* trigger_server_abort - terminate after abnormal master exit */
 
 static void trigger_server_abort(int unused_event, char *unused_context)
@@ -249,12 +237,6 @@ static void trigger_server_accept_fifo(int unused_event, char *context)
     if (msg_verbose)
        msg_info("%s: trigger arrived", myname);
 
-    /*
-     * Some buggy systems cause Postfix to lock up.
-     */
-    signal(SIGALRM, trigger_server_watchdog);
-    alarm(1000);
-
     /*
      * Read whatever the other side wrote into the FIFO. The FIFO read end is
      * non-blocking so we won't get stuck when multiple processes wake up.
@@ -277,12 +259,6 @@ static void trigger_server_accept_local(int unused_event, char *context)
     if (msg_verbose)
        msg_info("%s: trigger arrived", myname);
 
-    /*
-     * Some buggy systems cause Postfix to lock up.
-     */
-    signal(SIGALRM, trigger_server_watchdog);
-    alarm(1000);
-
     /*
      * Read a message from a socket. Be prepared for accept() to fail because
      * some other process already got the connection. The socket is
@@ -339,6 +315,7 @@ NORETURN trigger_server_main(int argc, char **argv, TRIGGER_SERVER_FN service,..
     char   *lock_path;
     VSTRING *why;
     int     alone = 0;
+    WATCHDOG *watchdog;
 
     /*
      * Process environment options as early as we can.
@@ -566,11 +543,19 @@ NORETURN trigger_server_main(int argc, char **argv, TRIGGER_SERVER_FN service,..
     }
     event_enable_read(MASTER_STATUS_FD, trigger_server_abort, (char *) 0);
     close_on_exec(MASTER_STATUS_FD, CLOSE_ON_EXEC);
+    watchdog = watchdog_create(1000, (WATCHDOG_FN) 0, (char *) 0);
+
+    /*
+     * The event loop, at last.
+     */
     while (var_use_limit == 0 || use_count < var_use_limit) {
+       if (trigger_server_lock != 0) {
+           watchdog_stop(watchdog);
+           if (myflock(vstream_fileno(trigger_server_lock), MYFLOCK_EXCLUSIVE) < 0)
+               msg_fatal("select lock: %m");
+       }
+       watchdog_start(watchdog);
        delay = loop ? loop(trigger_server_name, trigger_server_argv) : -1;
-       if (trigger_server_lock != 0
-           && myflock(vstream_fileno(trigger_server_lock), MYFLOCK_EXCLUSIVE) < 0)
-           msg_fatal("select lock: %m");
        event_loop(delay);
     }
     trigger_server_exit();
index b65f4ec2434c41cc91fa8bdb535e382d249f7794..6819c7dcae5b7b74d39edf411b66b8a17d1f9100 100644 (file)
@@ -87,7 +87,6 @@
 -TSINGLE_SERVER
 -TSINK_COMMAND
 -TSINK_STATE
--TSMTPD_REST_TABLE
 -TSMTPD_STATE
 -TSMTPD_TOKEN
 -TSMTP_ADDR
 -TVSTREAM_POPEN_ARGS
 -TVSTRING
 -TWAIT_STATUS_T
+-TWATCHDOG
 -TWATCH_FD
index cbcd8ec54b4ec81290102a9760d8cadaccaadf0d..1c76dd2cbaef202b7cc830e2312262bc3367fe30 100644 (file)
@@ -140,7 +140,7 @@ static int file_read_error(PICKUP_INFO *info, int type)
 static int cleanup_service_error(PICKUP_INFO *info, int status)
 {
     msg_warn("%s: %s", info->path, cleanup_strerror(status));
-    return (status == CLEANUP_STAT_BAD ?
+    return ((status & CLEANUP_STAT_BAD) ?
            REMOVE_MESSAGE_FILE : KEEP_MESSAGE_FILE);
 }
 
@@ -345,10 +345,12 @@ static int pickup_file(PICKUP_INFO *info)
      * easier to implement the many possible error exits without forgetting
      * to close files, or to release memory.
      */
+#define PICKUP_CLEANUP_FLAGS   (CLEANUP_FLAG_BOUNCE | CLEANUP_FLAG_FILTER)
+
     buf = vstring_alloc(100);
     cleanup = mail_connect_wait(MAIL_CLASS_PRIVATE, MAIL_SERVICE_CLEANUP);
     if (mail_scan(cleanup, "%s", buf) != 1
-       || mail_print(cleanup, "%d", CLEANUP_FLAG_BOUNCE) != 0) {
+       || mail_print(cleanup, "%d", PICKUP_CLEANUP_FLAGS) != 0) {
        status = KEEP_MESSAGE_FILE;
     } else {
        info->id = mystrdup(vstring_str(buf));
index b65f4ec2434c41cc91fa8bdb535e382d249f7794..6819c7dcae5b7b74d39edf411b66b8a17d1f9100 100644 (file)
@@ -87,7 +87,6 @@
 -TSINGLE_SERVER
 -TSINK_COMMAND
 -TSINK_STATE
--TSMTPD_REST_TABLE
 -TSMTPD_STATE
 -TSMTPD_TOKEN
 -TSMTP_ADDR
 -TVSTREAM_POPEN_ARGS
 -TVSTRING
 -TWAIT_STATUS_T
+-TWATCHDOG
 -TWATCH_FD
index ed9f8af8a998cc595be5775c7f4a89f49e21a25b..134d76ea39a12d86af08dd305b35f4dc9869c551 100644 (file)
@@ -22,7 +22,7 @@
 /* .fi
 /*     The external command attributes are given in the \fBmaster.cf\fR
 /*     file at the end of a service definition.  The syntax is as follows:
-/* .IP "\fBflags=FR>\fR (optional)"
+/* .IP "\fBflags=FR.>\fR (optional)"
 /*     Optional message processing flags. By default, a message is
 /*     copied unchanged.
 /* .RS
@@ -34,6 +34,9 @@
 /* .IP \fBR\fR
 /*     Prepend a \fBReturn-Path:\fR message header with the envelope sender
 /*     address.
+/* .IP \fB.\fR
+/*     Prepend \fB.\fR to lines starting with "\fB.\fR". This is needed
+/*     by, for example, \fBBSMTP\fR software.
 /* .IP \fB>\fR
 /*     Prepend \fB>\fR to lines starting with "\fBFrom \fR". This is expected
 /*     by, for example, \fBUUCP\fR software.
@@ -430,6 +433,9 @@ static void get_service_attr(PIPE_ATTR *attr, char **argv)
                case 'F':
                    attr->flags |= MAIL_COPY_FROM;
                    break;
+               case '.':
+                   attr->flags |= MAIL_COPY_DOT;
+                   break;
                case '>':
                    attr->flags |= MAIL_COPY_QUOTE;
                    break;
index b65f4ec2434c41cc91fa8bdb535e382d249f7794..6819c7dcae5b7b74d39edf411b66b8a17d1f9100 100644 (file)
@@ -87,7 +87,6 @@
 -TSINGLE_SERVER
 -TSINK_COMMAND
 -TSINK_STATE
--TSMTPD_REST_TABLE
 -TSMTPD_STATE
 -TSMTPD_TOKEN
 -TSMTP_ADDR
 -TVSTREAM_POPEN_ARGS
 -TVSTRING
 -TWAIT_STATUS_T
+-TWATCHDOG
 -TWATCH_FD
index 96de6a61071e1c8d8050955472d7ae812255e519..93b8d5fe9dd1cee79ddb09607e15fb06cfef716c 100644 (file)
@@ -5,13 +5,13 @@
 /*     Postfix alias database maintenance
 /* SYNOPSIS
 /* .fi
-/*     \fBpostalias\fR [\fB-c \fIconfig_dir\fR] [\fB-i\fR] [\fB-v\fR]
-/*             [\fB-w\fR] [\fIfile_type\fR:]\fIfile_name\fR ...
+/*     \fBpostalias\fR [\fB-ivw\fR] [\fB-c \fIconfig_dir\fR] [\fB-q \fIkey\fR]
+/*             [\fIfile_type\fR:]\fIfile_name\fR ...
 /* DESCRIPTION
-/*     The \fBpostalias\fR command creates a new Postfix alias database,
-/*     or updates an existing one. The input and output file formats
-/*     are expected to be compatible with Sendmail version 8, and are
-/*     expected to be suitable for the use as NIS alias maps.
+/*     The \fBpostalias\fR command creates or queries one or more Postfix
+/*     alias databases, or updates an existing one. The input and output
+/*     file formats are expected to be compatible with Sendmail version 8,
+/*     and are expected to be suitable for the use as NIS alias maps.
 /*
 /*     While a database update is in progress, signal delivery is
 /*     postponed, and an exclusive, advisory, lock is placed on the
 /*     Incremental mode. Read entries from standard input and do not
 /*     truncate an existing database. By default, \fBpostalias\fR creates
 /*     a new database from the entries in \fBfile_name\fR.
+/* .IP "\fB-q \fIkey\fR"
+/*     Search the specified maps for \fIkey\fR and print the first value
+/*     found on the standard output stream. The exit status is non-zero
+/*     if the requested information was not found.
 /* .IP \fB-v\fR
 /*     Enable verbose logging for debugging purposes. Multiple \fB-v\fR
 /*     options make the software increasingly verbose.
@@ -272,11 +276,28 @@ static void postalias(char *map_type, char *path_name,
        vstream_fclose(source_fp);
 }
 
+/* postalias_query - query a map and print the result to stdout */
+
+static int postalias_query(const char *map_type, const char *map_name,
+                                  const char *key)
+{
+    DICT   *dict;
+    const char *value;
+
+    dict = dict_open3(map_type, map_name, O_RDONLY, DICT_FLAG_LOCK);
+    if ((value = dict_get(dict, key)) != 0) {
+       vstream_printf("%s\n", value);
+       vstream_fflush(VSTREAM_OUT);
+    }
+    dict_close(dict);
+    return (value != 0);
+}
+
 /* usage - explain */
 
 static NORETURN usage(char *myname)
 {
-    msg_fatal("usage: %s [-c config_dir] [-i] [-v] [-w] [output_type:]file...",
+    msg_fatal("usage: %s [-ivw] [-c config_dir] [-q key] [map_type:]file...",
              myname);
 }
 
@@ -289,6 +310,8 @@ int     main(int argc, char **argv)
     struct stat st;
     int     open_flags = O_RDWR | O_CREAT | O_TRUNC;
     int     dict_flags = DICT_FLAG_DUP_WARN;
+    char   *query = 0;
+    int     found;
 
     /*
      * Be consistent with file permissions.
@@ -323,7 +346,7 @@ int     main(int argc, char **argv)
     /*
      * Parse JCL.
      */
-    while ((ch = GETOPT(argc, argv, "c:ivw")) > 0) {
+    while ((ch = GETOPT(argc, argv, "c:iq:vw")) > 0) {
        switch (ch) {
        default:
            usage(argv[0]);
@@ -335,6 +358,9 @@ int     main(int argc, char **argv)
        case 'i':
            open_flags &= ~O_TRUNC;
            break;
+       case 'q':
+           query = optarg;
+           break;
        case 'v':
            msg_verbose++;
            break;
@@ -350,15 +376,31 @@ int     main(int argc, char **argv)
      * Use the map type specified by the user, or fall back to a default
      * database type.
      */
-    if (optind + 1 > argc)
-       usage(argv[0]);
-    while (optind < argc) {
-       if ((path_name = split_at(argv[optind], ':')) != 0) {
-           postalias(argv[optind], path_name, open_flags, dict_flags);
-       } else {
-           postalias(var_db_type, argv[optind], open_flags, dict_flags);
+    if (query == 0) {                          /* create/update map(s) */
+       if (optind + 1 > argc)
+           usage(argv[0]);
+       while (optind < argc) {
+           if ((path_name = split_at(argv[optind], ':')) != 0) {
+               postalias(argv[optind], path_name, open_flags, dict_flags);
+           } else {
+               postalias(var_db_type, argv[optind], open_flags, dict_flags);
+           }
+           optind++;
+       }
+       exit(0);
+    } else {                                   /* query map(s) */
+       if (optind + 1 > argc)
+           usage(argv[0]);
+       while (optind < argc) {
+           if ((path_name = split_at(argv[optind], ':')) != 0) {
+               found = postalias_query(argv[optind], path_name, query);
+           } else {
+               found = postalias_query(var_db_type, argv[optind], query);
+           }
+           if (found)
+               exit(0);
+           optind++;
        }
-       optind++;
+       exit(1);
     }
-    exit(0);
 }
index b65f4ec2434c41cc91fa8bdb535e382d249f7794..6819c7dcae5b7b74d39edf411b66b8a17d1f9100 100644 (file)
@@ -87,7 +87,6 @@
 -TSINGLE_SERVER
 -TSINK_COMMAND
 -TSINK_STATE
--TSMTPD_REST_TABLE
 -TSMTPD_STATE
 -TSMTPD_TOKEN
 -TSMTP_ADDR
 -TVSTREAM_POPEN_ARGS
 -TVSTRING
 -TWAIT_STATUS_T
+-TWATCHDOG
 -TWATCH_FD
index b65f4ec2434c41cc91fa8bdb535e382d249f7794..6819c7dcae5b7b74d39edf411b66b8a17d1f9100 100644 (file)
@@ -87,7 +87,6 @@
 -TSINGLE_SERVER
 -TSINK_COMMAND
 -TSINK_STATE
--TSMTPD_REST_TABLE
 -TSMTPD_STATE
 -TSMTPD_TOKEN
 -TSMTP_ADDR
 -TVSTREAM_POPEN_ARGS
 -TVSTRING
 -TWAIT_STATUS_T
+-TWATCHDOG
 -TWATCH_FD
index b65f4ec2434c41cc91fa8bdb535e382d249f7794..6819c7dcae5b7b74d39edf411b66b8a17d1f9100 100644 (file)
@@ -87,7 +87,6 @@
 -TSINGLE_SERVER
 -TSINK_COMMAND
 -TSINK_STATE
--TSMTPD_REST_TABLE
 -TSMTPD_STATE
 -TSMTPD_TOKEN
 -TSMTP_ADDR
 -TVSTREAM_POPEN_ARGS
 -TVSTRING
 -TWAIT_STATUS_T
+-TWATCHDOG
 -TWATCH_FD
index b65f4ec2434c41cc91fa8bdb535e382d249f7794..6819c7dcae5b7b74d39edf411b66b8a17d1f9100 100644 (file)
@@ -87,7 +87,6 @@
 -TSINGLE_SERVER
 -TSINK_COMMAND
 -TSINK_STATE
--TSMTPD_REST_TABLE
 -TSMTPD_STATE
 -TSMTPD_TOKEN
 -TSMTP_ADDR
 -TVSTREAM_POPEN_ARGS
 -TVSTRING
 -TWAIT_STATUS_T
+-TWATCHDOG
 -TWATCH_FD
index b65f4ec2434c41cc91fa8bdb535e382d249f7794..6819c7dcae5b7b74d39edf411b66b8a17d1f9100 100644 (file)
@@ -87,7 +87,6 @@
 -TSINGLE_SERVER
 -TSINK_COMMAND
 -TSINK_STATE
--TSMTPD_REST_TABLE
 -TSMTPD_STATE
 -TSMTPD_TOKEN
 -TSMTP_ADDR
 -TVSTREAM_POPEN_ARGS
 -TVSTRING
 -TWAIT_STATUS_T
+-TWATCHDOG
 -TWATCH_FD
index b65f4ec2434c41cc91fa8bdb535e382d249f7794..6819c7dcae5b7b74d39edf411b66b8a17d1f9100 100644 (file)
@@ -87,7 +87,6 @@
 -TSINGLE_SERVER
 -TSINK_COMMAND
 -TSINK_STATE
--TSMTPD_REST_TABLE
 -TSMTPD_STATE
 -TSMTPD_TOKEN
 -TSMTP_ADDR
 -TVSTREAM_POPEN_ARGS
 -TVSTRING
 -TWAIT_STATUS_T
+-TWATCHDOG
 -TWATCH_FD
index 6117bc9e71d96936efc8c436da04d601a77ab28c..c2ee45d3c418ace7a554fc95ac4a4375609ad151 100644 (file)
@@ -65,3 +65,4 @@ postlock.o: ../include/mail_params.h
 postlock.o: ../include/dot_lockfile.h
 postlock.o: ../include/deliver_flock.h
 postlock.o: ../include/mail_conf.h
+postlock.o: ../include/sys_exits.h
index b65f4ec2434c41cc91fa8bdb535e382d249f7794..6819c7dcae5b7b74d39edf411b66b8a17d1f9100 100644 (file)
@@ -87,7 +87,6 @@
 -TSINGLE_SERVER
 -TSINK_COMMAND
 -TSINK_STATE
--TSMTPD_REST_TABLE
 -TSMTPD_STATE
 -TSMTPD_TOKEN
 -TSMTP_ADDR
 -TVSTREAM_POPEN_ARGS
 -TVSTRING
 -TWAIT_STATUS_T
+-TWATCHDOG
 -TWATCH_FD
index b65f4ec2434c41cc91fa8bdb535e382d249f7794..6819c7dcae5b7b74d39edf411b66b8a17d1f9100 100644 (file)
@@ -87,7 +87,6 @@
 -TSINGLE_SERVER
 -TSINK_COMMAND
 -TSINK_STATE
--TSMTPD_REST_TABLE
 -TSMTPD_STATE
 -TSMTPD_TOKEN
 -TSMTP_ADDR
 -TVSTREAM_POPEN_ARGS
 -TVSTRING
 -TWAIT_STATUS_T
+-TWATCHDOG
 -TWATCH_FD
index f44c232abe489b316d52cf6335f6d310b5134bc6..af6a2b7c609d49b018e70fd1765a18af238e154a 100644 (file)
@@ -5,12 +5,12 @@
 /*     Postfix lookup table management
 /* SYNOPSIS
 /* .fi
-/*     \fBpostmap\fR [\fB-c \fIconfig_dir\fR] [\fB-i\fR] [\fB-v\fR]
-/*             [\fB-w\fR] [\fIfile_type\fR:]\fIfile_name\fR
+/*     \fBpostmap\fR [\fB-ivw\fR] [\fB-c \fIconfig_dir\fR] [\fB-q \fIkey\fR]
+/*             [\fIfile_type\fR:]\fIfile_name\fR ...
 /* DESCRIPTION
-/*     The \fBpostmap\fR command creates a new Postfix lookup table,
-/*     or updates an existing one. The input and output formats are
-/*     expected to be compatible with:
+/*     The \fBpostmap\fR command creates or queries one or more Postfix
+/*     lookup tables, or updates an existing one. The input and output
+/*     file formats are expected to be compatible with:
 /*
 /* .ti +4
 /*     \fBmakemap \fIfile_type\fR \fIfile_name\fR < \fIfile_name\fR
 /*     Incremental mode. Read entries from standard input and do not
 /*     truncate an existing database. By default, \fBpostmap\fR creates
 /*     a new database from the entries in \fBfile_name\fR.
+/* .IP "\fB-q \fIkey\fR"
+/*     Search the specified maps for \fIkey\fR and print the first value
+/*     found on the standard output stream. The exit status is non-zero
+/*     if the requested information was not found.
 /* .IP \fB-v\fR
 /*     Enable verbose logging for debugging purposes. Multiple \fB-v\fR
 /*     options make the software increasingly verbose.
-/* .IP \f\B-w\fR
+/* .IP \fB-w\fR
 /*     Do not warn about duplicate entries; silently ignore them.
 /* .PP
 /*     Arguments:
@@ -226,11 +230,28 @@ static void postmap(char *map_type, char *path_name,
        vstream_fclose(source_fp);
 }
 
+/* postmap_query - query a map and print the result to stdout */
+
+static int postmap_query(const char *map_type, const char *map_name,
+                                const char *key)
+{
+    DICT   *dict;
+    const char *value;
+
+    dict = dict_open3(map_type, map_name, O_RDONLY, DICT_FLAG_LOCK);
+    if ((value = dict_get(dict, key)) != 0) {
+       vstream_printf("%s\n", value);
+       vstream_fflush(VSTREAM_OUT);
+    }
+    dict_close(dict);
+    return (value != 0);
+}
+
 /* usage - explain */
 
 static NORETURN usage(char *myname)
 {
-    msg_fatal("usage: %s [-c config_dir] [-i] [-v] [-w] [output_type:]file...",
+    msg_fatal("usage: %s [-ivw] [-c config_dir] [-q key] [map_type:]file...",
              myname);
 }
 
@@ -243,6 +264,8 @@ int     main(int argc, char **argv)
     struct stat st;
     int     open_flags = O_RDWR | O_CREAT | O_TRUNC;
     int     dict_flags = DICT_FLAG_DUP_WARN;
+    char   *query = 0;
+    int     found;
 
     /*
      * Be consistent with file permissions.
@@ -277,7 +300,7 @@ int     main(int argc, char **argv)
     /*
      * Parse JCL.
      */
-    while ((ch = GETOPT(argc, argv, "c:ivw")) > 0) {
+    while ((ch = GETOPT(argc, argv, "c:iq:vw")) > 0) {
        switch (ch) {
        default:
            usage(argv[0]);
@@ -289,6 +312,9 @@ int     main(int argc, char **argv)
        case 'i':
            open_flags &= ~O_TRUNC;
            break;
+       case 'q':
+           query = optarg;
+           break;
        case 'v':
            msg_verbose++;
            break;
@@ -304,15 +330,31 @@ int     main(int argc, char **argv)
      * Use the map type specified by the user, or fall back to a default
      * database type.
      */
-    if (optind + 1 > argc)
-       usage(argv[0]);
-    while (optind < argc) {
-       if ((path_name = split_at(argv[optind], ':')) != 0) {
-           postmap(argv[optind], path_name, open_flags, dict_flags);
-       } else {
-           postmap(var_db_type, argv[optind], open_flags, dict_flags);
+    if (query == 0) {                          /* create/update map(s) */
+       if (optind + 1 > argc)
+           usage(argv[0]);
+       while (optind < argc) {
+           if ((path_name = split_at(argv[optind], ':')) != 0) {
+               postmap(argv[optind], path_name, open_flags, dict_flags);
+           } else {
+               postmap(var_db_type, argv[optind], open_flags, dict_flags);
+           }
+           optind++;
+       }
+       exit(0);
+    } else {                                   /* query map(s) */
+       if (optind + 1 > argc)
+           usage(argv[0]);
+       while (optind < argc) {
+           if ((path_name = split_at(argv[optind], ':')) != 0) {
+               found = postmap_query(argv[optind], path_name, query);
+           } else {
+               found = postmap_query(var_db_type, argv[optind], query);
+           }
+           if (found)
+               exit(0);
+           optind++;
        }
-       optind++;
+       exit(1);
     }
-    exit(0);
 }
index b65f4ec2434c41cc91fa8bdb535e382d249f7794..6819c7dcae5b7b74d39edf411b66b8a17d1f9100 100644 (file)
@@ -87,7 +87,6 @@
 -TSINGLE_SERVER
 -TSINK_COMMAND
 -TSINK_STATE
--TSMTPD_REST_TABLE
 -TSMTPD_STATE
 -TSMTPD_TOKEN
 -TSMTP_ADDR
 -TVSTREAM_POPEN_ARGS
 -TVSTRING
 -TWAIT_STATUS_T
+-TWATCHDOG
 -TWATCH_FD
index b65f4ec2434c41cc91fa8bdb535e382d249f7794..6819c7dcae5b7b74d39edf411b66b8a17d1f9100 100644 (file)
@@ -87,7 +87,6 @@
 -TSINGLE_SERVER
 -TSINK_COMMAND
 -TSINK_STATE
--TSMTPD_REST_TABLE
 -TSMTPD_STATE
 -TSMTPD_TOKEN
 -TSMTP_ADDR
 -TVSTREAM_POPEN_ARGS
 -TVSTRING
 -TWAIT_STATUS_T
+-TWATCHDOG
 -TWATCH_FD
index 7bfd25ff56f5335dcc99949980551347220b5262..2259cd1f7fb939b70676438ffe2d784a03e53787 100644 (file)
@@ -266,6 +266,7 @@ int     var_dest_rcpt_limit;
 char   *var_relocated_maps;
 char   *var_virtual_maps;
 char   *var_defer_xports;
+bool    var_allow_min_user;
 
 static QMGR_SCAN *qmgr_incoming;
 static QMGR_SCAN *qmgr_deferred;
@@ -460,6 +461,10 @@ int     main(int argc, char **argv)
        VAR_DEST_RCPT_LIMIT, DEF_DEST_RCPT_LIMIT, &var_dest_rcpt_limit, 0, 0,
        0,
     };
+    static CONFIG_BOOL_TABLE bool_table[] = {
+       VAR_ALLOW_MIN_USER, DEF_ALLOW_MIN_USER, &var_allow_min_user,
+       0,
+    };
 
     /*
      * Use the trigger service skeleton, because no-one else should be
index 257dbc4aa0daa4f396d7502c6b1e2e38c7eafac5..5fe689029dcc07cda833fab82e9426005128c4d2 100644 (file)
@@ -220,14 +220,6 @@ void    qmgr_active_feed(QMGR_SCAN *scan_info, const char *queue_id)
        qmgr_active_defer(MAIL_QUEUE_ACTIVE, queue_id, var_min_backoff_time);
     } else {
 
-       /*
-        * Reset the defer log. Leave the bounce log alone; if it is still
-        * around, something did not send it previously.
-        */
-       if (mail_queue_remove(MAIL_QUEUE_DEFER, queue_id) && errno != ENOENT)
-           msg_fatal("%s: %s: remove %s %s: %m", myname,
-                     queue_id, MAIL_QUEUE_DEFER, queue_id);
-
        /*
         * Special case if all recipients were already delivered. Send any
         * bounces and clean up.
index e47527a621a52e938a9a75ede6a8d59e84fe8e60..a5bfaff2cdefe0faac1440ed2ab88347a9e8bc51 100644 (file)
@@ -489,6 +489,24 @@ static void qmgr_message_resolve(QMGR_MESSAGE *message)
            }
        }
 
+       /*
+        * Bounce recipient addresses that start with `-'. External commands
+        * may misinterpret such addresses as command-line options.
+        * 
+        * In theory I could say people should always carefully set up their
+        * master.cf pipe mailer entries with `--' before the first
+        * non-option argument, but mistakes will happen regardless.
+        * 
+        * Therefore the protection is put in place here, in the queue manager,
+        * where it cannot be bypassed.
+        */
+       if (var_allow_min_user == 0 && recipient->address[0] == '-') {
+           qmgr_bounce_recipient(message, recipient,
+                                 "invalid recipient syntax: \"%s\"",
+                                 recipient->address);
+           continue;
+       }
+
        /*
         * Queues are identified by the transport name and by the next-hop
         * hostname. When the destination is local (no next hop), derive the
@@ -682,6 +700,17 @@ QMGR_MESSAGE *qmgr_message_alloc(const char *queue_name, const char *queue_id,
        qmgr_message_free(message);
        return (0);
     } else {
+
+       /*
+        * Reset the defer log. This code should not be here, but we must
+        * reset the defer log *after* acquiring the exclusive lock on the
+        * queue file and *before* resolving new recipients. Since all those
+        * operations are encapsulated so nicely by this routine, the defer
+        * log reset has to be done here as well.
+        */
+       if (mail_queue_remove(MAIL_QUEUE_DEFER, queue_id) && errno != ENOENT)
+           msg_fatal("%s: %s: remove %s %s: %m", myname,
+                     queue_id, MAIL_QUEUE_DEFER, queue_id);
        qmgr_message_sort(message);
        qmgr_message_resolve(message);
        qmgr_message_sort(message);
index b65f4ec2434c41cc91fa8bdb535e382d249f7794..6819c7dcae5b7b74d39edf411b66b8a17d1f9100 100644 (file)
@@ -87,7 +87,6 @@
 -TSINGLE_SERVER
 -TSINK_COMMAND
 -TSINK_STATE
--TSMTPD_REST_TABLE
 -TSMTPD_STATE
 -TSMTPD_TOKEN
 -TSMTP_ADDR
 -TVSTREAM_POPEN_ARGS
 -TVSTRING
 -TWAIT_STATUS_T
+-TWATCHDOG
 -TWATCH_FD
index dc100b778db9f1b081fa8090a1abbcd4719f7ab9..13d13e450eb5d980fc7e084ed1279bb8fac12bdc 100644 (file)
@@ -70,6 +70,8 @@
 /* .IP "\fB-X \fIlog_file\fR (ignored)"
 /*     Log mailer traffic. Use the \fBdebug_peer_list\fR and
 /*     \fBdebug_peer_level\fR configuration parameters instead.
+/* .IP "\fB-U\fR (ignored)"
+/*     Initial user submission.
 /* .IP \fB-bd\fR
 /*     Go into daemon mode. This mode of operation is implemented by
 /*     executing the \fBpostfix start\fR command.
@@ -660,7 +662,7 @@ int     main(int argc, char **argv)
            optind++;
            continue;
        }
-       if ((c = GETOPT(argc, argv, "B:C:F:IN:R:X:b:ce:f:h:imno:p:r:q:tvx")) <= 0)
+       if ((c = GETOPT(argc, argv, "B:C:F:IN:R:UX:b:ce:f:h:imno:p:r:q:tvx")) <= 0)
            break;
        switch (c) {
        default:
index b65f4ec2434c41cc91fa8bdb535e382d249f7794..6819c7dcae5b7b74d39edf411b66b8a17d1f9100 100644 (file)
@@ -87,7 +87,6 @@
 -TSINGLE_SERVER
 -TSINK_COMMAND
 -TSINK_STATE
--TSMTPD_REST_TABLE
 -TSMTPD_STATE
 -TSMTPD_TOKEN
 -TSMTP_ADDR
 -TVSTREAM_POPEN_ARGS
 -TVSTRING
 -TWAIT_STATUS_T
+-TWATCHDOG
 -TWATCH_FD
index b65f4ec2434c41cc91fa8bdb535e382d249f7794..6819c7dcae5b7b74d39edf411b66b8a17d1f9100 100644 (file)
@@ -87,7 +87,6 @@
 -TSINGLE_SERVER
 -TSINK_COMMAND
 -TSINK_STATE
--TSMTPD_REST_TABLE
 -TSMTPD_STATE
 -TSMTPD_TOKEN
 -TSMTP_ADDR
 -TVSTREAM_POPEN_ARGS
 -TVSTRING
 -TWAIT_STATUS_T
+-TWATCHDOG
 -TWATCH_FD
index b65f4ec2434c41cc91fa8bdb535e382d249f7794..6819c7dcae5b7b74d39edf411b66b8a17d1f9100 100644 (file)
@@ -87,7 +87,6 @@
 -TSINGLE_SERVER
 -TSINK_COMMAND
 -TSINK_STATE
--TSMTPD_REST_TABLE
 -TSMTPD_STATE
 -TSMTPD_TOKEN
 -TSMTP_ADDR
 -TVSTREAM_POPEN_ARGS
 -TVSTRING
 -TWAIT_STATUS_T
+-TWATCHDOG
 -TWATCH_FD
index a39502921636b3f71559c42ba203d19dfcbf8a07..2fa6b677a24e46653c6d842e2fce5bd7aada2ff7 100644 (file)
@@ -56,9 +56,6 @@ clean:
 
 tidy:  clean
 
-smtpd_token_test: smtpd_token_test.c smtpd_token.o $(LIBS)
-       $(CC) $(CFLAGS) -DTEST -o $@ $@.c smtpd_token.o $(LIBS) $(SYSLIBS)
-
 depend: $(MAKES)
        (sed '1,/^# do not edit/!d' Makefile.in; \
        set -e; for i in [a-z][a-z0-9]*.c; do \
@@ -67,7 +64,7 @@ depend: $(MAKES)
        done) | grep -v '[.][o][:][ ][/]' >$$$$ && mv $$$$ Makefile.in
        @make -f Makefile.in Makefile
 
-tests: smtpd_check_test smtpd_check_test2
+tests: smtpd_check_test smtpd_check_test2 smtpd_token_test
 
 smtpd_check_test: smtpd_check smtpd_check.in smtpd_check.ref
        ../postmap/postmap smtpd_check_access
@@ -81,6 +78,11 @@ smtpd_check_test2: smtpd_check smtpd_check.in2 smtpd_check.ref2
        diff smtpd_check.ref2 smtpd_check.tmp
        rm -f smtpd_check.tmp smtpd_check_access.*
 
+smtpd_token_test: smtpd_token smtpd_token.in smtpd_token.ref
+       ./smtpd_token <smtpd_token.in >smtpd_token.tmp 2>&1
+       diff smtpd_token.ref smtpd_token.tmp
+       rm -f smtpd_token.tmp
+
 # do not edit below this line - it is generated by 'make depend'
 smtpd.o: smtpd.c
 smtpd.o: ../include/sys_defs.h
@@ -111,6 +113,8 @@ smtpd.o: ../include/name_mask.h
 smtpd.o: ../include/mail_flush.h
 smtpd.o: ../include/mail_stream.h
 smtpd.o: ../include/mail_queue.h
+smtpd.o: ../include/tok822.h
+smtpd.o: ../include/resolve_clnt.h
 smtpd.o: ../include/mail_server.h
 smtpd.o: smtpd_token.h
 smtpd.o: smtpd.h
@@ -154,6 +158,7 @@ smtpd_check.o: ../include/argv.h
 smtpd_check.o: ../include/mymalloc.h
 smtpd_check.o: ../include/dict.h
 smtpd_check.o: ../include/vstream.h
+smtpd_check.o: ../include/htable.h
 smtpd_check.o: ../include/dns.h
 smtpd_check.o: ../include/namadr_list.h
 smtpd_check.o: ../include/domain_list.h
@@ -164,6 +169,9 @@ smtpd_check.o: ../include/mail_error.h
 smtpd_check.o: ../include/name_mask.h
 smtpd_check.o: ../include/resolve_local.h
 smtpd_check.o: ../include/own_inet_addr.h
+smtpd_check.o: ../include/mail_conf.h
+smtpd_check.o: ../include/maps.h
+smtpd_check.o: ../include/mail_addr_find.h
 smtpd_check.o: smtpd.h
 smtpd_check.o: ../include/mail_stream.h
 smtpd_check.o: smtpd_check.h
index 5f2f5a0c31a9ae99ea18bf1ba0b6910c349cf871..32468aa8dfef82dae8a6769eac8abda4111dc6ba 100644 (file)
 #include <mail_flush.h>
 #include <mail_stream.h>
 #include <mail_queue.h>
+#include <tok822.h>
 
 /* Single-threaded server skeleton. */
 
@@ -392,7 +393,7 @@ static void mail_open_stream(SMTPD_STATE *state)
        state->dest = mail_stream_service(MAIL_CLASS_PRIVATE,
                                          MAIL_SERVICE_CLEANUP);
        if (state->dest == 0
-           || mail_print(state->dest->stream, "%d", CLEANUP_FLAG_NONE) != 0)
+        || mail_print(state->dest->stream, "%d", CLEANUP_FLAG_FILTER) != 0)
            msg_fatal("unable to connect to the %s %s service",
                      MAIL_CLASS_PRIVATE, MAIL_SERVICE_CLEANUP);
     }
@@ -424,6 +425,50 @@ static void mail_open_stream(SMTPD_STATE *state)
     state->queue_id = mystrdup(state->dest->id);
 }
 
+/* extract_addr - extract address from rubble */
+
+static VSTRING *extract_addr(SMTPD_STATE *state, VSTRING *buf)
+{
+    char   *myname = "extract_addr";
+    TOK822 *tree;
+    TOK822 *tp;
+    int     naddr;
+    int     non_addr;
+
+    /*
+     * Some mailers send RFC822-style address forms (with comments and such)
+     * in SMTP envelopes. We cannot blame users for this: the blame is with
+     * programmers violating the RFC, and with sendmail for being permissive.
+     * 
+     * Extract the address from any surrounding junk. XXX Because of this, the
+     * SMTP command tokenizer must leave the address in externalized (quoted)
+     * form.
+     */
+#define STR(x) vstring_str(x)
+#define LEN(x) VSTRING_LEN(x)
+
+    if (msg_verbose)
+       msg_info("%s: input: %s", myname, STR(buf));
+    tree = tok822_parse(STR(buf));
+    for (naddr = non_addr = 0, tp = tree; tp != 0; tp = tp->next) {
+       if (tp->type == TOK822_ADDR) {
+           if (++naddr == 1)
+               tok822_internalize(buf, tp->head, TOK822_STR_DEFL);
+           else if (naddr == 2)
+               msg_warn("Multiple addresses from %s in %s command: %s",
+                        state->namaddr, state->where, STR(buf));
+       } else if (tp->type != '<' && tp->type != '>') {
+           if (++non_addr == 1)
+               msg_warn("Non-RFC 821 syntax from %s in %s command: %s",
+                        state->namaddr, state->where, STR(buf));
+       }
+    }
+    tok822_free_tree(tree);
+    if (msg_verbose)
+       msg_info("%s: result: %s", myname, STR(buf));
+    return (buf);
+}
+
 /* mail_cmd - process MAIL command */
 
 static int mail_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *argv)
@@ -447,14 +492,14 @@ static int mail_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *argv)
        smtpd_chat_reply(state, "503 Error: nested MAIL command");
        return (-1);
     }
-    if (argc < 4
-       || strcasecmp(argv[1].strval, "from") != 0
-       || strcmp(argv[2].strval, ":") != 0) {
+    if (argc < 3
+       || strcasecmp(argv[1].strval, "from:") != 0) {
        state->error_mask |= MAIL_ERROR_PROTOCOL;
        smtpd_chat_reply(state, "501 Syntax: MAIL FROM: <address>");
        return (-1);
     }
-    for (narg = 4; narg < argc; narg++) {
+    argv[2].strval = STR(extract_addr(state, argv[2].vstrval));
+    for (narg = 3; narg < argc; narg++) {
        arg = argv[narg].strval;
        if (strcasecmp(arg, "BODY=8BITMIME") == 0
            || strcasecmp(arg, "BODY=7BIT") == 0) {
@@ -471,7 +516,7 @@ static int mail_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *argv)
     state->time = time((time_t *) 0);
     if (SMTPD_STAND_ALONE(state) == 0
        && var_smtpd_delay_reject == 0
-       && (err = smtpd_check_mail(state, argv[3].strval)) != 0) {
+       && (err = smtpd_check_mail(state, argv[2].strval)) != 0) {
        smtpd_chat_reply(state, "%s", err);
        return (-1);
     }
@@ -491,8 +536,8 @@ static int mail_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *argv)
      */
     rec_fprintf(state->cleanup, REC_TYPE_TIME, "%ld",
                (long) time((time_t *) 0));
-    rec_fputs(state->cleanup, REC_TYPE_FROM, argv[3].strval);
-    state->sender = mystrdup(argv[3].strval);
+    rec_fputs(state->cleanup, REC_TYPE_FROM, argv[2].strval);
+    state->sender = mystrdup(argv[2].strval);
     smtpd_chat_reply(state, "250 Ok");
     return (0);
 }
@@ -545,20 +590,20 @@ static int rcpt_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *argv)
        smtpd_chat_reply(state, "503 Error: need MAIL command");
        return (-1);
     }
-    if (argc != 4
-       || strcasecmp(argv[1].strval, "to") != 0
-       || strcmp(argv[2].strval, ":") != 0) {
+    if (argc != 3
+       || strcasecmp(argv[1].strval, "to:") != 0) {
        state->error_mask |= MAIL_ERROR_PROTOCOL;
        smtpd_chat_reply(state, "501 Syntax: RCPT TO: <address>");
        return (-1);
     }
+    argv[2].strval = STR(extract_addr(state, argv[2].vstrval));
     if (var_smtpd_rcpt_limit && state->rcpt_count >= var_smtpd_rcpt_limit) {
        state->error_mask |= MAIL_ERROR_POLICY;
        smtpd_chat_reply(state, "452 Error: too many recipients");
        return (-1);
     }
     if (SMTPD_STAND_ALONE(state) == 0
-       && (err = smtpd_check_rcpt(state, argv[3].strval)) != 0) {
+       && (err = smtpd_check_rcpt(state, argv[2].strval)) != 0) {
        smtpd_chat_reply(state, "%s", err);
        return (-1);
     }
@@ -568,8 +613,8 @@ static int rcpt_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *argv)
      */
     state->rcpt_count++;
     if (state->recipient == 0)
-       state->recipient = mystrdup(argv[3].strval);
-    rec_fputs(state->cleanup, REC_TYPE_RCPT, argv[3].strval);
+       state->recipient = mystrdup(argv[2].strval);
+    rec_fputs(state->cleanup, REC_TYPE_RCPT, argv[2].strval);
     smtpd_chat_reply(state, "250 Ok");
     return (0);
 }
@@ -596,10 +641,13 @@ static int data_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *unused_argv)
     int     first = 1;
 
     /*
-     * Sanity checks.
+     * Sanity checks. With ESMTP command pipelining the client can send DATA
+     * before all recipients are rejected, so don't report that as a protocol
+     * error.
      */
     if (state->rcpt_count == 0) {
-       state->error_mask |= MAIL_ERROR_PROTOCOL;
+       if (state->cleanup == 0)
+           state->error_mask |= MAIL_ERROR_PROTOCOL;
        smtpd_chat_reply(state, "503 Error: need RCPT command");
        return (-1);
     }
index 9ef6997716e17a1fc5100c8470fc5410f783c336..4cc27582e1db6bbc9951525f0026fd665ef5d384 100644 (file)
@@ -1077,6 +1077,13 @@ static int check_table_result(SMTPD_STATE *state, char *table,
                                   "%d <%s>: %s rejected: Access denied",
                             var_access_map_code, reply_name, reply_class));
 
+    /*
+     * All-numeric result probably means OK - some out-of-band authentication
+     * mechanism uses this as time stamp.
+     */
+    if (value[strcspn(value, "0123456789")] == 0)
+       return (SMTPD_CHECK_OK);
+
     /*
      * 4xx or 5xx means NO as well. smtpd_check_reject() will validate the
      * response status code.
index 846cfc4038cc3f63ad732af00fbb64d1f6f898bc..7de161fa6d89c5aaf97043c060f9c4e7f86d8aef 100644 (file)
@@ -7,8 +7,10 @@
 /*     #include <smtpd_token.h>
 /*
 /*     typedef struct {
-           int tokval;
-           char *strval;
+/* .in +4
+/*         char *strval;
+/*         /* other stuff... */
+/* .in -4
 /*     } SMTPD_TOKEN;
 /*
 /*     int     smtpd_token(str, argvp)
@@ -20,8 +22,6 @@
 /*     via the function return value.
 /*
 /*     Token types:
-/* .IP SMTPD_TOK_ADDR
-/*     The token is of the form <text>, not including the angle brackets.
 /* .IP SMTPD_TOK_OTHER
 /*     The token is something else.
 /* .IP SMTPD_TOK_ERROR
@@ -29,8 +29,9 @@
 /* BUGS
 /*     This tokenizer understands just enough to tokenize SMTPD commands.
 /*     It understands backslash escapes, white space, quoted strings,
-/*     and addresses (including quoted text) enclosed by < and >. Any
-/*     other sequence of characters is lumped together as one token.
+/*     and addresses (including quoted text) enclosed by < and >.
+/*     The input is broken up into tokens by whitespace, except for
+/*     whitespace that is protected by quites etc.
 /* LICENSE
 /* .ad
 /* .fi
@@ -47,6 +48,7 @@
 #include <sys_defs.h>
 #include <ctype.h>
 #include <string.h>
+#include <unistd.h>
 
 /* Utility library. */
 
 
 #include "smtpd_token.h"
 
- /*
-  * Macros to make complex code more readable.
-  */
-#define COLLECT(cp,vp,c,cond) { \
-       while ((c = *cp) != 0) { \
-           if (c == '\\') { \
-               cp++; \
-               if ((c = *cp) == 0) \
-                   break; \
-           } else if (!(cond)) { \
-               break; \
-           } \
-           cp++; \
-           VSTRING_ADDCH(vp, c); \
-       } \
-    }
-
 /* smtp_quoted - read until closing quote */
 
-static char *smtp_quoted(char *cp, SMTPD_TOKEN *arg, int last)
+static char *smtp_quoted(char *cp, SMTPD_TOKEN *arg, int start, int last)
 {
+    static VSTRING *stack;
     int     c;
 
-    while ((c = *cp) != 0) {
+    if (stack == 0)
+       stack = vstring_alloc(1);
+    VSTRING_RESET(stack);
+    VSTRING_ADDCH(stack, last);
+
+    VSTRING_ADDCH(arg->vstrval, start);
+    for (;;) {
+       if ((c = *cp) == 0)
+           break;
        cp++;
-       if (c == '\\') {                        /* parse escape sequence */
-           if ((c = *cp) == 0)
-               break;                          /* end of input, punt */
-           cp++;
-           VSTRING_ADDCH(arg->vstrval, c);     /* store escaped character */
-       } else if (c == last) {
-           return (cp);                        /* closing quote */
-       } else if (c == '"') {
-           cp = smtp_quoted(cp, arg, c);       /* recurse */
+       VSTRING_ADDCH(arg->vstrval, c);
+       if (c == vstring_end(stack)[-1]) {      /* closing quote etc. */
+           vstring_truncate(stack, VSTRING_LEN(stack) - 1);
+           if (VSTRING_LEN(stack) == 0)
+               break;
        } else {
-           VSTRING_ADDCH(arg->vstrval, c);     /* store character */
+           if (c == '\\') {                    /* parse escape sequence */
+               if ((c = *cp) == 0)
+                   break;
+               cp++;
+               VSTRING_ADDCH(arg->vstrval, c);
+           } else if (c == '"') {
+               VSTRING_ADDCH(stack, '"');      /* highest precedence */
+           } else if (c == '(' && vstring_end(stack)[-1] != '"') {
+               VSTRING_ADDCH(stack, ')');      /* medium precedence */
+           } else if (c == '<' && vstring_end(stack)[-1] == '>') {
+               VSTRING_ADDCH(stack, '>');      /* lowest precedence */
+           }
        }
     }
-    arg->tokval = SMTPD_TOK_ERROR;             /* missing end */
     return (cp);
 }
 
@@ -103,45 +103,43 @@ static char *smtp_quoted(char *cp, SMTPD_TOKEN *arg, int last)
 
 static char *smtp_next_token(char *cp, SMTPD_TOKEN *arg)
 {
-    char   *special = "<[\">]:";
     int     c;
 
     VSTRING_RESET(arg->vstrval);
-    arg->tokval = SMTPD_TOK_OTHER;
 
-    for (;;) {
-       if ((c = *cp++) == 0) {
-           return (0);
-       } else if (ISSPACE(c)) {                /* whitespace, skip */
-           while (ISSPACE(*cp))
+#define STR(x) vstring_str(x)
+#define LEN(x) VSTRING_LEN(x)
+#define STREQ(x,y,l) ((x)[0] == (x)[0] && strncasecmp((x), (y), (l)) == 0)
+
+    while ((c = *cp) != 0) {
+       cp++;
+       if (ISSPACE(c)) {                       /* whitespace, skip */
+           while (*cp && ISSPACE(*cp))
                cp++;
-           continue;
+           if (LEN(arg->vstrval) > 0)          /* end of token */
+               break;
        } else if (c == '<') {                  /* <stuff> */
-           arg->tokval = SMTPD_TOK_ADDR;
-           cp = smtp_quoted(cp, arg, '>');
-           break;
-       } else if (c == '[') {                  /* [stuff], keep [] */
-           VSTRING_ADDCH(arg->vstrval, c);
-           cp = smtp_quoted(cp, arg, ']');
-           if (cp[-1] == ']')
-               VSTRING_ADDCH(arg->vstrval, ']');
-           break;
-       } else if (c == '"') {                  /* string */
-           cp = smtp_quoted(cp, arg, c);
-           break;
-       } else if (ISCNTRL(c) || strchr(special, c)) {
+           cp = smtp_quoted(cp, arg, c, '>');
+       } else if (c == '[') {                  /* [stuff] */
+           cp = smtp_quoted(cp, arg, c, ']');
+       } else if (c == '"') {                  /* "stuff" */
+           cp = smtp_quoted(cp, arg, c, c);
+       } else if (c == ':') {                  /* this is gross, but... */
            VSTRING_ADDCH(arg->vstrval, c);
-           break;
+           if (STREQ(STR(arg->vstrval), "to:", LEN(arg->vstrval))
+               || STREQ(STR(arg->vstrval), "from:", LEN(arg->vstrval)))
+               break;
        } else {                                /* other */
-           if (c == '\\')
+           if (c == '\\') {
                if ((c = *cp) == 0)
                    break;
+               cp++;
+           }
            VSTRING_ADDCH(arg->vstrval, c);
-           COLLECT(cp, arg->vstrval, c,
-                   !ISSPACE(c) && !ISCNTRL(c) && !strchr(special, c));
-           break;
        }
     }
+    if (LEN(arg->vstrval) == 0)                        /* no token found */
+       return (0);
     VSTRING_TERMINATE(arg->vstrval);
     arg->strval = vstring_str(arg->vstrval);
     return (cp);
@@ -168,7 +166,7 @@ int     smtpd_token(char *cp, SMTPD_TOKEN **argvp)
 
     if (smtp_argv == 0)
        smtp_argv = (SMTPD_TOKEN *) mvect_alloc(&mvect, sizeof(*smtp_argv), 1,
-                                            smtpd_token_init, (MVECT_FN) 0);
+                                           smtpd_token_init, (MVECT_FN) 0);
     for (n = 0; /* void */ ; n++) {
        smtp_argv = (SMTPD_TOKEN *) mvect_realloc(&mvect, n + 1);
        if ((cp = smtp_next_token(cp, smtp_argv + n)) == 0)
@@ -196,17 +194,18 @@ main(int unused_argc, char **unused_argv)
     int     i;
 
     for (;;) {
-       vstream_printf("enter SMTPD command: ");
+       if (isatty(STDIN_FILENO))
+           vstream_printf("enter SMTPD command: ");
        vstream_fflush(VSTREAM_OUT);
        if (vstring_fgets(vp, VSTREAM_IN) == 0)
            break;
+       if (*vstring_str(vp) == '#')
+           continue;
+       if (!isatty(STDIN_FILENO))
+           vstream_fputs(vstring_str(vp), VSTREAM_OUT);
        tok_argc = smtpd_token(vstring_str(vp), &tok_argv);
-       for (i = 0; i < tok_argc; i++) {
-           vstream_printf("Token type:  %s\n",
-                          tok_argv[i].tokval == SMTPD_TOK_ADDR ?
-                          "address" : "other");
+       for (i = 0; i < tok_argc; i++)
            vstream_printf("Token value: %s\n", tok_argv[i].strval);
-       }
     }
     exit(0);
 }
index 88489fa220b242b7fbd79e5f780718df11b4f8c6..841ddb3ce3d460471099f95e914315eced1567e3 100644 (file)
@@ -17,7 +17,6 @@
   * External interface.
   */
 typedef struct SMTPD_TOKEN {
-    int     tokval;
     char   *strval;
     VSTRING *vstrval;
 } SMTPD_TOKEN;
diff --git a/postfix/smtpd/smtpd_token.in b/postfix/smtpd/smtpd_token.in
new file mode 100644 (file)
index 0000000..3ef8f75
--- /dev/null
@@ -0,0 +1,9 @@
+mail from:<wietse@porcupine.org>
+mail from:<"wietse venema"@porcupine.org>
+mail from:wietse@porcupine.org
+mail from:<wietse @ porcupine.org>
+mail from:<"wietse venema"@porcupine.org ("wietse ) venema")>
+mail from:<"wietse venema" <wietse@porcupine.org>>
+mail from:<"wietse venema"@porcupine.org ( ("wietse ) venema") )>
+mail from:"wietse venema"@porcupine.org
+mail from:wietse\ venema@porcupine.org
diff --git a/postfix/smtpd/smtpd_token.ref b/postfix/smtpd/smtpd_token.ref
new file mode 100644 (file)
index 0000000..5d962fb
--- /dev/null
@@ -0,0 +1,36 @@
+mail from:<wietse@porcupine.org>
+Token value: mail
+Token value: from:
+Token value: <wietse@porcupine.org>
+mail from:<"wietse venema"@porcupine.org>
+Token value: mail
+Token value: from:
+Token value: <"wietse venema"@porcupine.org>
+mail from:wietse@porcupine.org
+Token value: mail
+Token value: from:
+Token value: wietse@porcupine.org
+mail from:<wietse @ porcupine.org>
+Token value: mail
+Token value: from:
+Token value: <wietse @ porcupine.org>
+mail from:<"wietse venema"@porcupine.org ("wietse ) venema")>
+Token value: mail
+Token value: from:
+Token value: <"wietse venema"@porcupine.org ("wietse ) venema")>
+mail from:<"wietse venema" <wietse@porcupine.org>>
+Token value: mail
+Token value: from:
+Token value: <"wietse venema" <wietse@porcupine.org>>
+mail from:<"wietse venema"@porcupine.org ( ("wietse ) venema") )>
+Token value: mail
+Token value: from:
+Token value: <"wietse venema"@porcupine.org ( ("wietse ) venema") )>
+mail from:"wietse venema"@porcupine.org
+Token value: mail
+Token value: from:
+Token value: "wietse venema"@porcupine.org
+mail from:wietse\ venema@porcupine.org
+Token value: mail
+Token value: from:
+Token value: wietse venema@porcupine.org
index b65f4ec2434c41cc91fa8bdb535e382d249f7794..6819c7dcae5b7b74d39edf411b66b8a17d1f9100 100644 (file)
@@ -87,7 +87,6 @@
 -TSINGLE_SERVER
 -TSINK_COMMAND
 -TSINK_STATE
--TSMTPD_REST_TABLE
 -TSMTPD_STATE
 -TSMTPD_TOKEN
 -TSMTP_ADDR
 -TVSTREAM_POPEN_ARGS
 -TVSTRING
 -TWAIT_STATUS_T
+-TWATCHDOG
 -TWATCH_FD
index b65f4ec2434c41cc91fa8bdb535e382d249f7794..6819c7dcae5b7b74d39edf411b66b8a17d1f9100 100644 (file)
@@ -87,7 +87,6 @@
 -TSINGLE_SERVER
 -TSINK_COMMAND
 -TSINK_STATE
--TSMTPD_REST_TABLE
 -TSMTPD_STATE
 -TSMTPD_TOKEN
 -TSMTP_ADDR
 -TVSTREAM_POPEN_ARGS
 -TVSTRING
 -TWAIT_STATUS_T
+-TWATCHDOG
 -TWATCH_FD
index b65f4ec2434c41cc91fa8bdb535e382d249f7794..6819c7dcae5b7b74d39edf411b66b8a17d1f9100 100644 (file)
@@ -87,7 +87,6 @@
 -TSINGLE_SERVER
 -TSINK_COMMAND
 -TSINK_STATE
--TSMTPD_REST_TABLE
 -TSMTPD_STATE
 -TSMTPD_TOKEN
 -TSMTP_ADDR
 -TVSTREAM_POPEN_ARGS
 -TVSTRING
 -TWAIT_STATUS_T
+-TWATCHDOG
 -TWATCH_FD
index 22a13435144ff5f057536b4ce2bdaf1c881dc00f..e7656653b4ebbd9643c7d4709b60e1a53efe320d 100644 (file)
@@ -20,7 +20,7 @@ SRCS  = argv.c argv_split.c attr.c basename.c binhash.c chroot_uid.c \
        vstream.c vstream_popen.c vstring.c vstring_vstream.c writable.c \
        write_buf.c write_wait.c dict_unix.c dict_pcre.c stream_listen.c \
        stream_connect.c stream_trigger.c dict_regexp.c mac_expand.c \
-       clean_env.c
+       clean_env.c watchdog.c
 OBJS   = argv.o argv_split.o attr.o basename.o binhash.o chroot_uid.o \
        close_on_exec.o concatenate.o dict.o dict_db.o dict_dbm.o \
        dict_env.o dict_ht.o dict_ldap.o dict_mysql.o dict_ni.o dict_nis.o \
@@ -42,7 +42,7 @@ OBJS  = argv.o argv_split.o attr.o basename.o binhash.o chroot_uid.o \
        vstream.o vstream_popen.o vstring.o vstring_vstream.o writable.o \
        write_buf.o write_wait.o dict_unix.o dict_pcre.o stream_listen.o \
        stream_connect.o stream_trigger.o dict_regexp.o mac_expand.o \
-       clean_env.o
+       clean_env.o watchdog.o
 HDRS   = argv.h attr.h binhash.h chroot_uid.h connect.h dict.h dict_db.h \
        dict_dbm.h dict_env.h dict_ht.h dict_ldap.h dict_mysql.h \
        dict_ni.h dict_nis.h dict_nisplus.h dir_forest.h events.h \
@@ -56,7 +56,8 @@ HDRS  = argv.h attr.h binhash.h chroot_uid.h connect.h dict.h dict_db.h \
        sigdelay.h split_at.h stat_as.h stringops.h sys_defs.h \
        timed_connect.h timed_wait.h trigger.h username.h valid_hostname.h \
        vbuf.h vbuf_print.h vstream.h vstring.h vstring_vstream.h \
-       dict_unix.h dict_pcre.h dict_regexp.h mac_expand.h clean_env.h
+       dict_unix.h dict_pcre.h dict_regexp.h mac_expand.h clean_env.h \
+       watchdog.h
 TESTSRC        = fifo_open.c fifo_rdwr_bug.c fifo_rdonly_bug.c select_bug.c \
        stream_test.c dup2_pass_on_exec.c
 WARN   = -W -Wformat -Wimplicit -Wmissing-prototypes \
@@ -71,7 +72,8 @@ TESTPROG= dict_open dup2_pass_on_exec events exec_command fifo_open \
        fifo_rdonly_bug fifo_rdwr_bug fifo_trigger fsspace fullname \
        inet_addr_host inet_addr_local mac_parse make_dirs msg_syslog \
        mystrtok peer_name sigdelay translit valid_hostname vstream_popen \
-       vstring vstring_vstream doze select_bug stream_test mac_expand
+       vstring vstring_vstream doze select_bug stream_test mac_expand \
+       watchdog
 
 LIB_DIR        = ../lib
 INC_DIR        = ../include
@@ -240,6 +242,11 @@ mac_expand: $(LIB)
        $(CC) $(CFLAGS) -DTEST -o $@ $@.c $(LIB) $(SYSLIBS)
        mv junk $@.o
 
+watchdog: $(LIB)
+       mv $@.o junk
+       $(CC) $(CFLAGS) -DTEST -o $@ $@.c $(LIB) $(SYSLIBS)
+       mv junk $@.o
+
 depend: $(MAKES)
        (sed '1,/^# do not edit/!d' Makefile.in; \
        set -e; for i in [a-z][a-z0-9]*.c; do \
@@ -852,6 +859,11 @@ vstring_vstream.o: vstring.h
 vstring_vstream.o: vbuf.h
 vstring_vstream.o: vstream.h
 vstring_vstream.o: vstring_vstream.h
+watchdog.o: watchdog.c
+watchdog.o: sys_defs.h
+watchdog.o: msg.h
+watchdog.o: mymalloc.h
+watchdog.o: watchdog.h
 writable.o: writable.c
 writable.o: sys_defs.h
 writable.o: msg.h
index 069bcf7236fd36dfd53b1825bafc5c591629ad1a..8ebdeb0969d4f2a11ecf6fa5304b08147661e061 100644 (file)
@@ -399,7 +399,7 @@ DICT   *dict_ldap_open(const char *ldapsource, int dummy, int dict_flags)
 
     /* get configured value of "ldapsource_timeout"; default to 10 */
     vstring_sprintf(config_param, "%s_timeout", ldapsource);
-    dict_ldap->timeout = get_mail_conf_int(config_param, 10, 0, 0);
+    dict_ldap->timeout = get_mail_conf_int(vstring_str(config_param), 10, 0, 0);
     if (msg_verbose)
        msg_info("%s: %s is %d", myname, vstring_str(config_param),
                 dict_ldap->timeout);
index 89a9d720482af4c90a884d5b603b1f688f78bcff..20d9a45403d7b0fd378399e2e24d29e2b8995ea8 100644 (file)
@@ -19,6 +19,9 @@
 /* .IP passwd.byname
 /*     The table is the UNIX password database. The key is a login name.
 /*     The result is a password file entry in passwd(5) format.
+/* .IP group.byname
+/*     The table is the UNIX group database. The key is a group name.
+/*     The result is a group file entry in group(5) format.
 /* SEE ALSO
 /*     dict(3) generic dictionary manager
 /* DIAGNOSTICS
 /* System library. */
 
 #include "sys_defs.h"
+#include <unistd.h>
 #include <string.h>
 #include <pwd.h>
+#include <grp.h>
 
 /* Utility library. */
 
@@ -76,6 +81,33 @@ static const char *dict_unix_getpwnam(DICT *unused_dict, const char *key)
     }
 }
 
+/* dict_unix_getgrnam - find group table entry */
+
+static const char *dict_unix_getgrnam(DICT *unused_dict, const char *key)
+{
+    struct group *grp;
+    static VSTRING *buf;
+    char  **cpp;
+
+    dict_errno = 0;
+
+    if ((grp = getgrnam(key)) == 0) {
+       return (0);
+    } else {
+       if (buf == 0)
+           buf = vstring_alloc(10);
+       vstring_sprintf(buf, "%s:%s:%d:",
+                       grp->gr_name, grp->gr_passwd, grp->gr_gid);
+       for (cpp = grp->gr_mem; *cpp; cpp++) {
+           vstring_strcat(buf, *cpp);
+           if (cpp[1])
+               VSTRING_ADDCH(buf, ',');
+       }
+       VSTRING_TERMINATE(buf);
+       return (vstring_str(buf));
+    }
+}
+
 /* dict_unix_update - add or update table entry */
 
 static void dict_unix_update(DICT *dict, const char *unused_name, const char *unused_value)
@@ -106,6 +138,7 @@ DICT   *dict_unix_open(const char *map, int unused_flags, int dict_flags)
     };
     static struct dict_unix_lookup dict_unix_lookup[] = {
        "passwd.byname", dict_unix_getpwnam,
+       "group.byname", dict_unix_getgrnam,
        0,
     };
     struct dict_unix_lookup *lp;
index 3acc2b3b92bf4e3cfce2959e1a442e4199f38e68..9a53d8d6f8a40b4e94965b24585916094929cbc3 100644 (file)
@@ -72,12 +72,12 @@ int     inet_addr_local(INET_ADDR_LIST *addr_list)
 {
     char   *myname = "inet_addr_local";
     struct ifconf ifc;
-    struct ifreq ifreq;
     struct ifreq *ifr;
     struct ifreq *the_end;
     int     sock;
     VSTRING *buf = vstring_alloc(1024);
     int     initial_count = addr_list->used;
+    struct in_addr addr;
 
     if ((sock = socket(PF_INET, SOCK_DGRAM, 0)) < 0)
        msg_fatal("%s: socket: %m", myname);
@@ -109,20 +109,18 @@ int     inet_addr_local(INET_ADDR_LIST *addr_list)
     }
 
     /*
-     * Get the IP address of each active IP network interface.
+     * Get the address of each IP network interface. According to BIND we
+     * must include interfaces that are down because the machine may still
+     * receive packets for that address (yes, via some other interface).
+     * Having no way to verify this claim on every machine, I will give them
+     * the benefit of the doubt.
      */
     the_end = (struct ifreq *) (ifc.ifc_buf + ifc.ifc_len);
     for (ifr = ifc.ifc_req; ifr < the_end;) {
        if (ifr->ifr_addr.sa_family == AF_INET) {       /* IP interface */
-           ifreq = *ifr;
-           if (ioctl(sock, SIOCGIFFLAGS, (char *) &ifreq) < 0)
-               msg_fatal("%s: ioctl SIOCGIFFLAGS: %m", myname);
-           if (ifreq.ifr_flags & IFF_UP) {     /* active interface */
-               if (ioctl(sock, SIOCGIFADDR, (char *) &ifreq) < 0)
-                   msg_fatal("%s: ioctl SIOCGIFADDR: %m", myname);
-               inet_addr_list_append(addr_list,
-                   &(((struct sockaddr_in *) & ifreq.ifr_addr)->sin_addr));
-           }
+           addr = ((struct sockaddr_in *) & ifr->ifr_addr)->sin_addr;
+           if (addr.s_addr != INADDR_ANY)      /* has IP address */
+               inet_addr_list_append(addr_list, &addr);
        }
        ifr = NEXT_INTERFACE(ifr);
     }
index 6e8293fb29144b50c061e4b92e66a47d245900c3..73f395feccdc6ec566573009af0e25e7e854682e 100644 (file)
@@ -83,6 +83,7 @@ int     timed_waitpid(pid_t pid, WAIT_STATUS_T *statusp, int options,
     char   *myname = "timed_waitpid";
     struct sigaction action;
     struct sigaction old_action;
+    int     time_left;
     int     wpid;
 
     /*
@@ -100,7 +101,7 @@ int     timed_waitpid(pid_t pid, WAIT_STATUS_T *statusp, int options,
     if (sigaction(SIGALRM, &action, &old_action) < 0)
        msg_fatal("%s: sigaction(SIGALRM): %m", myname);
     timed_wait_expired = 0;
-    alarm(time_limit);
+    time_left = alarm(time_limit);
 
     /*
      * Wait for only a limited amount of time.
@@ -114,6 +115,8 @@ int     timed_waitpid(pid_t pid, WAIT_STATUS_T *statusp, int options,
     alarm(0);
     if (sigaction(SIGALRM, &old_action, (struct sigaction *) 0) < 0)
        msg_fatal("%s: sigaction(SIGALRM): %m", myname);
+    if (time_left)
+       alarm(time_left);
 
     return (wpid);
 }
diff --git a/postfix/util/watchdog.c b/postfix/util/watchdog.c
new file mode 100644 (file)
index 0000000..db1e412
--- /dev/null
@@ -0,0 +1,228 @@
+/*++
+/* NAME
+/*     watchdog 3
+/* SUMMARY
+/*     watchdog timer
+/* SYNOPSIS
+/*     #include <watchdog.h>
+/*
+/*     WATCHDOG *watchdog_create(timeout, action, context)
+/*     unsigned timeout;
+/*     void    (*action)(WATCHDOG *watchdog, char *context);
+/*     char    *context;
+/*
+/*     void    watchdog_start(watchdog)
+/*     WATCHDOG *watchdog;
+/*
+/*     void    watchdog_stop(watchdog)
+/*     WATCHDOG *watchdog;
+/*
+/*     void    watchdog_destroy(watchdog)
+/*     WATCHDOG *watchdog;
+/* DESCRIPTION
+/*     This module implements watchdog timers that are based on ugly
+/*     UNIX alarm timers. The module is designed to survive systems
+/*     with clocks that jump occasionally.
+/*
+/*     Watchdog timers can be stacked. Only one watchdog timer can be
+/*     active at a time. Only the last created watchdog timer can be
+/*     manipulated. Watchdog timers must be destroyed in reverse order
+/*     of creation.
+/*
+/*     watchdog_create() suspends the current watchdog timer, if any,
+/*     and instantiates a new watchdog timer.
+/*
+/*     watchdog_start() starts or restarts the watchdog timer.
+/*
+/*     watchdog_stop() stops the watchdog timer.
+/*
+/*     watchdog_destroy() stops the watchdog timer, and resumes the
+/*     watchdog timer instance that was suspended by watchdog_create().
+/*
+/*     Arguments:
+/* .IP timeout
+/*     The watchdog time limit. When the watchdog timer runs, the
+/*     process must invoke watchdog_start(), watchdog_stop() or
+/*     watchdog_destroy() before the time limit is reached.
+/* .IP action
+/*     A null pointer, or pointer to function that is called when the
+/*     watchdog alarm goes off. The default action is to terminate
+/*     the process with a fatal error.
+/* .IP context
+/*     Application context that is passed to the action routine.
+/* .IP watchdog
+/*     Must be a pointer to the most recently created watchdog instance.
+/*     This argument is checked upon each call.
+/* BUGS
+/*     UNIX alarm timers are not stackable, so there can be at most one
+/*     watchdog instance active at any given time.
+/* SEE ALSO
+/*     msg(3) diagnostics interface
+/* DIAGNOSTICS
+/*     Fatal errors: memory allocation problem, system call failure.
+/*     Panics: interface violations.
+/* LICENSE
+/* .ad
+/* .fi
+/*     The Secure Mailer license must be distributed with this software.
+/* AUTHOR(S)
+/*     Wietse Venema
+/*     IBM T.J. Watson Research
+/*     P.O. Box 704
+/*     Yorktown Heights, NY 10598, USA
+/*--*/
+
+/* System library. */
+
+#include <sys_defs.h>
+#include <unistd.h>
+#include <signal.h>
+
+/* Utility library. */
+
+#include <msg.h>
+#include <mymalloc.h>
+#include <watchdog.h>
+
+/* Application-specific. */
+
+ /*
+  * Rather than having one timer that goes off when it is too late, we break
+  * up the time limit into smaller intervals so that we can deal with clocks
+  * that jump occasionally.
+  */
+#define WATCHDOG_STEPS 3
+
+ /*
+  * UNIX alarms are not stackable, but we can save and restore state, so that
+  * watchdogs can at least be nested, sort of.
+  */
+struct WATCHDOG {
+    unsigned timeout;                  /* our time resolution */
+    WATCHDOG_FN action;                        /* application routine */
+    char   *context;                   /* application context */
+    int     trip_run;                  /* number of successive timeouts */
+    WATCHDOG *saved_watchdog;          /* saved state */
+    struct sigaction saved_action;     /* saved state */
+    unsigned saved_time;               /* saved state */
+};
+
+ /*
+  * However, only one watchdog instance can be current, and the caller has to
+  * restore state before a prior watchdog instance can be manipulated.
+  */
+static WATCHDOG *watchdog_curr;
+
+/* watchdog_event - handle timeout event */
+
+static void watchdog_event(int unused_sig)
+{
+    char   *myname = "watchdog_event";
+    WATCHDOG *wp;
+
+    /*
+     * This routine runs as a signal handler. We should not do anything that
+     * could involve memory allocation/deallocation, but exiting without
+     * proper explanation would be unacceptable.
+     */
+    if ((wp = watchdog_curr) == 0)
+       msg_panic("%s: no instance", myname);
+    if (msg_verbose)
+       msg_info("%s: %p %d", myname, (char *) wp, wp->trip_run);
+    if (++(wp->trip_run) < WATCHDOG_STEPS) {
+       alarm(wp->timeout);
+    } else {
+       if (wp->action)
+           wp->action(wp, wp->context);
+       else
+           msg_fatal("watchdog timeout");
+    }
+}
+
+/* watchdog_create - create watchdog instance */
+
+WATCHDOG *watchdog_create(unsigned timeout, WATCHDOG_FN action, char *context)
+{
+    char   *myname = "watchdog_create";
+    struct sigaction sig_action;
+    WATCHDOG *wp;
+
+    wp = (WATCHDOG *) mymalloc(sizeof(*wp));
+    if ((wp->timeout = timeout / WATCHDOG_STEPS) == 0)
+       msg_panic("%s: timeout %d is too small", myname, timeout);
+    wp->action = action;
+    wp->context = context;
+    wp->saved_watchdog = watchdog_curr;
+    wp->saved_time = alarm(0);
+    sigemptyset(&sig_action.sa_mask);
+    sig_action.sa_flags = SA_RESTART;
+    sig_action.sa_handler = watchdog_event;
+    if (sigaction(SIGALRM, &sig_action, &wp->saved_action) < 0)
+       msg_fatal("%s: sigaction(SIGALRM): %m", myname);
+    if (msg_verbose)
+       msg_info("%s: %p %d", myname, (char *) wp, timeout);
+    return (watchdog_curr = wp);
+}
+
+/* watchdog_destroy - destroy watchdog instance, restore state */
+
+void    watchdog_destroy(WATCHDOG *wp)
+{
+    char   *myname = "watchdog_destroy";
+
+    watchdog_stop(wp);
+    watchdog_curr = wp->saved_watchdog;
+    if (sigaction(SIGALRM, &wp->saved_action, (struct sigaction *) 0) < 0)
+       msg_fatal("%s: sigaction(SIGALRM): %m", myname);
+    if (wp->saved_time)
+       alarm(wp->saved_time);
+    myfree((char *) wp);
+    if (msg_verbose)
+       msg_info("%s: %p", myname, (char *) wp);
+}
+
+/* watchdog_start - enable watchdog timer */
+
+void    watchdog_start(WATCHDOG *wp)
+{
+    char   *myname = "watchdog_start";
+
+    if (wp != watchdog_curr)
+       msg_panic("%s: wrong watchdog instance", myname);
+    wp->trip_run = 0;
+    alarm(wp->timeout);
+    if (msg_verbose)
+       msg_info("%s: %p", myname, (char *) wp);
+}
+
+/* watchdog_stop - disable watchdog timer */
+
+void    watchdog_stop(WATCHDOG *wp)
+{
+    char   *myname = "watchdog_stop";
+
+    if (wp != watchdog_curr)
+       msg_panic("%s: wrong watchdog instance", myname);
+    alarm(0);
+    if (msg_verbose)
+       msg_info("%s: %p", myname, (char *) wp);
+}
+
+#ifdef TEST
+
+#include <vstream.h>
+
+main(int unused_argc, char **unused_argv)
+{
+    WATCHDOG *wp;
+
+    msg_verbose = 1;
+
+    wp = watchdog_create(10, (WATCHDOG_FN) 0, (char *) 0);
+    do {
+       watchdog_start(wp);
+    } while (VSTREAM_GETCHAR() != VSTREAM_EOF);
+    watchdog_destroy(wp);
+}
+
+#endif
diff --git a/postfix/util/watchdog.h b/postfix/util/watchdog.h
new file mode 100644 (file)
index 0000000..926233b
--- /dev/null
@@ -0,0 +1,35 @@
+#ifndef _WATCHDOG_H_INCLUDED_
+#define _WATCHDOG_H_INCLUDED_
+
+/*++
+/* NAME
+/*     watchdog 3h
+/* SUMMARY
+/*     watchdog timer
+/* SYNOPSIS
+/*     #include "watchdog.h"
+ DESCRIPTION
+ .nf
+
+ /*
+  * External interface.
+  */
+typedef struct WATCHDOG WATCHDOG;
+typedef void (*WATCHDOG_FN) (WATCHDOG *, char *);
+extern WATCHDOG *watchdog_create(unsigned, WATCHDOG_FN, char *);
+extern void watchdog_start(WATCHDOG *);
+extern void watchdog_stop(WATCHDOG *);
+extern void watchdog_destroy(WATCHDOG *);
+
+/* LICENSE
+/* .ad
+/* .fi
+/*     The Secure Mailer license must be distributed with this software.
+/* AUTHOR(S)
+/*     Wietse Venema
+/*     IBM T.J. Watson Research
+/*     P.O. Box 704
+/*     Yorktown Heights, NY 10598, USA
+/*--*/
+
+#endif