]> git.ipfire.org Git - thirdparty/postfix.git/commitdiff
snapshot-20000927
authorWietse Venema <wietse@porcupine.org>
Wed, 27 Sep 2000 05:00:00 +0000 (00:00 -0500)
committerViktor Dukhovni <viktor@dukhovni.org>
Tue, 5 Feb 2013 06:26:48 +0000 (06:26 +0000)
38 files changed:
postfix/HISTORY
postfix/Makefile.in
postfix/conf/master.cf
postfix/conf/postfix-script-nosgid
postfix/conf/postfix-script-sgid
postfix/html/Makefile.in
postfix/html/flushd.8.html [new file with mode: 0644]
postfix/html/sendmail.1.html
postfix/man/Makefile.in
postfix/man/man1/sendmail.1
postfix/man/man8/flushd.8 [new file with mode: 0644]
postfix/src/flushd/.indent.pro [new symlink]
postfix/src/flushd/Makefile.in [new file with mode: 0644]
postfix/src/flushd/flushd.c [new file with mode: 0644]
postfix/src/global/Makefile.in
postfix/src/global/clnt_stream.c
postfix/src/global/mail_flush.c
postfix/src/global/mail_flush.h
postfix/src/global/mail_params.h
postfix/src/global/mail_proto.h
postfix/src/global/mail_queue.c
postfix/src/global/mail_queue.h
postfix/src/global/mail_scan.c
postfix/src/global/mail_version.h
postfix/src/nqmgr/qmgr.c
postfix/src/nqmgr/qmgr.h
postfix/src/nqmgr/qmgr_deliver.c
postfix/src/postsuper/postsuper.c
postfix/src/qmgr/Makefile.in
postfix/src/qmgr/qmgr.c
postfix/src/qmgr/qmgr.h
postfix/src/qmgr/qmgr_deliver.c
postfix/src/sendmail/Makefile.in
postfix/src/sendmail/sendmail.c
postfix/src/smtpd/smtpd.c
postfix/src/smtpd/smtpd_check.c
postfix/src/util/vstring_vstream.c
postfix/src/util/vstring_vstream.h

index c8c9a95969b88dcdf852ba784d5abf2d3f8f0b11..4e9246e8d6238800b201b72e7853fc0f591cd698 100644 (file)
@@ -4292,3 +4292,15 @@ Apologies for any names omitted.
        Cleanup: deleted the per-recipient bounce protocol.  Future
        bounce logfiles will support per-recipient bounce addresses.
        Files:  global/bounce.c, bounce/bounce_recip_service.
+
+20000925
+
+       Workaround: sendmail allows MAIL FROM and RCPT TO envelope
+       addresses like <the dude <dude@site>> so we will never get
+       rid of them. To disallow, specify "strict_rfc821_envelopes
+       = yes".  File: smtpd/smtpd.c.
+
+20000926-8
+
+       First implementation of a logfile-based fast flush server,
+       which is the basis for ETRN and "sendmail -qRsite".
index fcc8c66e64922123781414edd86f0925c7cdd17c..6cf1ec72bd814457fc0dc7b6f62af46db906b49f 100644 (file)
@@ -6,7 +6,7 @@ DIRS    = src/util src/global src/dns src/master src/postfix src/smtpstone \
        src/lmtp src/trivial-rewrite src/qmgr src/smtp src/bounce src/pipe \
        src/showq src/postalias src/postcat src/postconf src/postdrop \
        src/postkick src/postlock src/postlog src/postmap src/postsuper \
-       src/nqmgr src/spawn # src/base64 proto man html
+       src/nqmgr src/spawn src/flushd # src/base64 proto man html
 
 default: update
 
index 473cfa386296b217596a1ab5b79d9935a0781da3..b3b1fa7f7d5bf1fb712d59701588ebd8751a3bc5 100644 (file)
@@ -75,6 +75,7 @@ bounce          unix  -       -       n       -       0       bounce
 defer    unix  -       -       n       -       0       bounce
 smtp     unix  -       -       n       -       -       smtp
 showq     unix n       -       n       -       -       showq
+flush    unix  n       -       n       -       -       flushd
 error     unix -       -       n       -       -       error
 local    unix  -       n       n       -       -       local
 lmtp     unix  -       -       n       -       -       lmtp
index 5dd1ef238b17a57f914b962bb91c8e86332586fd..425fe6acd8a13b9709bee1ce77d90fbaf8843150 100755 (executable)
@@ -187,7 +187,7 @@ check)
                chmod 755 pid
                chown $mail_owner pid
        }
-       for dir in incoming active bounce defer deferred saved corrupt; do
+       for dir in incoming active bounce defer deferred flush saved corrupt; do
                test -d $dir || {
                        $WARN creating missing Postfix $dir directory
                        mkdir $dir || exit 1
index 780b475b0e5bd2a857a68a70180b1255ac36225e..1c6231f13ef402f76347fd1e9c43ad6063e486e4 100755 (executable)
@@ -188,7 +188,7 @@ check)
                chmod 755 pid
                chown $mail_owner pid
        }
-       for dir in incoming active bounce defer deferred saved corrupt; do
+       for dir in incoming active bounce defer deferred flush saved corrupt; do
                test -d $dir || {
                        $WARN creating missing Postfix $dir directory
                        mkdir $dir || exit 1
index 4431a1bf977eefc80f02731fe7ff3dfc3ec49acc..35f235000f2f3d3702471376753ddff60e094b08 100644 (file)
@@ -5,7 +5,7 @@ SHELL   = /bin/sh
 DAEMONS        =  bounce.8.html cleanup.8.html defer.8.html error.8.html local.8.html \
        lmtp.8.html master.8.html pickup.8.html pipe.8.html qmgr.8.html \
        showq.8.html smtp.8.html smtpd.8.html trivial-rewrite.8.html \
-       nqmgr.8.html spawn.8.html
+       nqmgr.8.html spawn.8.html flushd.8.html
 COMMANDS= mailq.1.html newaliases.1.html postalias.1.html postcat.1.html \
        postconf.1.html postfix.1.html postkick.1.html postlock.1.html \
        postlog.1.html postdrop.1.html postmap.1.html sendmail.1.html \
@@ -36,6 +36,9 @@ defer.8.html: bounce.8.html
 error.8.html: ../src/error/error.c
        srctoman $? | nroff -man | man2html | postlink >$@
 
+flushd.8.html: ../src/flushd/flushd.c
+       srctoman $? | nroff -man | man2html | postlink >$@
+
 cleanup.8.html: ../src/cleanup/cleanup.c
        srctoman $? | nroff -man | man2html | postlink >$@
 
diff --git a/postfix/html/flushd.8.html b/postfix/html/flushd.8.html
new file mode 100644 (file)
index 0000000..dc67ace
--- /dev/null
@@ -0,0 +1,134 @@
+<html> <head> </head> <body> <pre>
+
+
+
+FLUSHD(8)                                               FLUSHD(8)
+
+
+<b>NAME</b>
+       flushd - Postfix fast flush daemon
+
+<b>SYNOPSIS</b>
+       <b>flushd</b> [generic Postfix daemon options]
+
+<b>DESCRIPTION</b>
+       The flush server maintains so-called "fast flush" logfiles
+       with information about what messages are queued for a spe-
+       cific  site.  This program expects to be run from the <a href="master.8.html"><b>mas-</b>
+       <b>ter</b>(8)</a> process manager.
+
+       This server implements the following requests:
+
+       FLUSH_REQ_ADD sitename queue_id
+              Append a record to the per-site fast flush  logfile
+              for the specified queue ID.
+
+       FLUSH_REQ_SEND sitename
+              Arrange  for  the delivery of all messages that are
+              listed in the fast flush logfile for the  specified
+              site.   After the logfile is processed, the file is
+              truncated to length zero.
+
+       The response to the client is one of:
+
+       FLUSH_STAT_OK
+              The request completed normally.
+
+       FLUSH_STAT_BAD
+              The flush server rejected the request (bad  request
+              name, bad request parameter value).
+
+       FLUSH_STAT_UNKNOWN
+              The specified site has no fast flush logfile and is
+              not configured to have one.
+
+<b>SECURITY</b>
+       The fast flush server is moderately security-sensitive. It
+       does  not  talk  to the network, but it does talk to local
+       unprivileged users, in order to emulate "sendmail -qRsite"
+       behavior.   For  this  reason all strings in a request are
+       truncated at ine_length_limit.
+
+       The fast flush server can run chrooted at fixed low privi-
+       lege.
+
+<b>DIAGNOSTICS</b>
+       Problems and transactions are logged to <b>syslogd</b>(8).
+
+<b>BUGS</b>
+       In  reality,  this  server schedules delivery of messages,
+       regardless of their destination. This limitation is due to
+       the  fact  that  one  queue  runner has to handle mail for
+
+
+
+                                                                1
+
+
+
+
+
+FLUSHD(8)                                               FLUSHD(8)
+
+
+       multiple destinations.
+
+<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>
+       command after a configuration change.
+
+       <b>fast</b><i>_</i><b>flush</b><i>_</i><b>maps</b>
+              The  table with names of destinations that this MTA
+              provides the  fast  flush  service  for,  and  with
+              clients  that  may issue the ETRN command for those
+              destinations. Postfix maintains fast flush logfiles
+              only for destinations listed in this table.
+
+       <b>line</b><i>_</i><b>length</b><i>_</i><b>limit</b>
+              Maximal  length  of  strings in a fast flush client
+              request.
+
+<b>SEE</b> <b>ALSO</b>
+       <a href="smtp.8.html">smtp(8)</a> Postfix SMTP client
+       smtpd) Postfix SMTP server
+       <a href="qmgr.8.html">qmgr(8)</a> Postfix queue manager
+       syslogd(8) system logging
+
+<b>LICENSE</b>
+       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
+       Yorktown Heights, NY 10598, USA
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+                                                                2
+
+
+</pre> </body> </html>
index 8c037cbe0216f0ffbd65d19999eb9eeac6011a1b..5da935a3fd1783888c31ad126b70bf8a71a65882 100644 (file)
@@ -185,12 +185,12 @@ SENDMAIL(1)                                           SENDMAIL(1)
               The   interval   between   queue   runs.   Use  the
               <b>queue</b><i>_</i><b>run</b><i>_</i><b>delay</b> configuration parameter instead.
 
-       <b>-t</b>     Extract  recipients  from  message  headers.   This
-              requires  that  no  recipients  be specified on the
-              command line.
-
-       <b>-v</b>     Enable verbose logging for debugging purposes. Mul-
-              tiple  <b>-v</b>  options  make  the software increasingly
+       <b>-qR</b><i>site</i>
+              Schedule immediate delivery of  all  mail  that  is
+              queued  for  the named <i>site</i>.  This functionality is
+              available only for sites that  are  configured  for
+              the  <b>fast</b>  <b>flush</b>  service  support  as described in
+              <b>flushd</b>(8).   For  other  sites,  this  command   is
 
 
 
@@ -203,16 +203,28 @@ SENDMAIL(1)                                           SENDMAIL(1)
 SENDMAIL(1)                                           SENDMAIL(1)
 
 
+              equivalent to using the slower <b>sendmail</b> <b>-q</b> instead.
+
+       <b>-qS</b><i>site</i>
+              The site name is ignored. This command  is  equiva-
+              lent to using the slower <b>sendmail</b> <b>-q</b> instead.
+
+       <b>-t</b>     Extract   recipients  from  message  headers.  This
+              requires that no recipients  be  specified  on  the
+              command line.
+
+       <b>-v</b>     Enable verbose logging for debugging purposes. Mul-
+              tiple <b>-v</b> options  make  the  software  increasingly
               verbose.
 
 <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
+       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.
 
 <b>DIAGNOSTICS</b>
-       Problems  are  logged  to  <b>syslogd</b>(8)  and to the standard
+       Problems are logged to  <b>syslogd</b>(8)  and  to  the  standard
        error stream.
 
 <b>ENVIRONMENT</b>
@@ -224,7 +236,7 @@ SENDMAIL(1)                                           SENDMAIL(1)
 
        <b>MAIL</b><i>_</i><b>DEBUG</b>
               Enable debugging with an external command, as spec-
-              ified   with   the  <b>debugger</b><i>_</i><b>command</b>  configuration
+              ified  with  the   <b>debugger</b><i>_</i><b>command</b>   configuration
               parameter.
 
 <b>FILES</b>
@@ -232,31 +244,19 @@ SENDMAIL(1)                                           SENDMAIL(1)
        /etc/postfix, configuration files
 
 <b>CONFIGURATION</b> <b>PARAMETERS</b>
-       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
+       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>alias</b><i>_</i><b>database</b>
-              Default  alias  database(s)  for  <b>newaliases</b>.   The
-              default  value  for  this  parameter is system-spe-
+              Default   alias  database(s)  for  <b>newaliases</b>.  The
+              default value for  this  parameter  is  system-spe-
               cific.
 
        <b>bounce</b><i>_</i><b>size</b><i>_</i><b>limit</b>
               The amount of original message context that is sent
               along with a non-delivery notification.
 
-       <b>database</b><i>_</i><b>type</b>
-              Default alias etc. database type. On many UNIX sys-
-              tems the default type is either <b>dbm</b> or <b>hash</b>.
-
-       <b>debugger</b><i>_</i><b>command</b>
-              Command that is executed after a Postfix daemon has
-              initialized.
-
-       <b>debug</b><i>_</i><b>peer</b><i>_</i><b>level</b>
-              Increment  in  verbose  logging level when a remote
-              host  matches  a  pattern  in  the  <b>debug</b><i>_</i><b>peer</b><i>_</i><b>list</b>
-              parameter.
 
 
 
@@ -269,60 +269,60 @@ SENDMAIL(1)                                           SENDMAIL(1)
 SENDMAIL(1)                                           SENDMAIL(1)
 
 
+       <b>database</b><i>_</i><b>type</b>
+              Default alias etc. database type. On many UNIX sys-
+              tems the default type is either <b>dbm</b> or <b>hash</b>.
+
+       <b>debugger</b><i>_</i><b>command</b>
+              Command that is executed after a Postfix daemon has
+              initialized.
+
+       <b>debug</b><i>_</i><b>peer</b><i>_</i><b>level</b>
+              Increment in verbose logging level  when  a  remote
+              host  matches  a  pattern  in  the  <b>debug</b><i>_</i><b>peer</b><i>_</i><b>list</b>
+              parameter.
+
        <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
+              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.
 
        <b>fork</b><i>_</i><b>attempts</b>
-              Number of attempts to <b>fork</b>() a process before  giv-
+              Number  of attempts to <b>fork</b>() a process before giv-
               ing up.
 
        <b>fork</b><i>_</i><b>delay</b>
-              Delay   in   seconds   between   successive  <b>fork</b>()
+              Delay  in   seconds   between   successive   <b>fork</b>()
               attempts.
 
        <b>hopcount</b><i>_</i><b>limit</b>
               Limit the number of <b>Received:</b> message headers.
 
        <b>mail</b><i>_</i><b>owner</b>
-              The owner of the mail queue  and  of  most  Postfix
+              The  owner  of  the  mail queue and of most Postfix
               processes.
 
        <b>command</b><i>_</i><b>directory</b>
-              Directory  with  Postfix support commands (default:
+              Directory with Postfix support  commands  (default:
               <b>$program</b><i>_</i><b>directory</b>).
 
        <b>daemon</b><i>_</i><b>directory</b>
-              Directory with Postfix  daemon  programs  (default:
+              Directory  with  Postfix  daemon programs (default:
               <b>$program</b><i>_</i><b>directory</b>).
 
        <b>queue</b><i>_</i><b>directory</b>
-              Top-level  directory  of the Postfix queue. This is
+              Top-level directory of the Postfix queue.  This  is
               also the root directory of Postfix daemons that run
               chrooted.
 
        <b>queue</b><i>_</i><b>run</b><i>_</i><b>delay</b>
-              The  time  between successive scans of the deferred
+              The time between successive scans of  the  deferred
               queue.
 
 <b>SEE</b> <b>ALSO</b>
        <a href="pickup.8.html">pickup(8)</a> mail pickup daemon
        <a href="postalias.1.html">postalias(1)</a> maintain alias database
-       <a href="postdrop.1.html">postdrop(1)</a> privileged posting agent
-       <a href="postfix.1.html">postfix(1)</a> mail system control
-       <a href="postkick.1.html">postkick(1)</a> kick a Postfix daemon
-       <a href="qmgr.8.html">qmgr(8)</a> queue manager
-       <a href="showq.8.html">showq(8)</a> list mail queue
-       <a href="smtpd.8.html">smtpd(8)</a> SMTP server
-       syslogd(8) system logging
-
-<b>LICENSE</b>
-       The Secure Mailer license must be  distributed  with  this
-       software.
-
-
 
 
 
@@ -335,6 +335,19 @@ SENDMAIL(1)                                           SENDMAIL(1)
 SENDMAIL(1)                                           SENDMAIL(1)
 
 
+       <a href="postdrop.1.html">postdrop(1)</a> privileged posting agent
+       <a href="postfix.1.html">postfix(1)</a> mail system control
+       <a href="postkick.1.html">postkick(1)</a> kick a Postfix daemon
+       <a href="qmgr.8.html">qmgr(8)</a> queue manager
+       <a href="showq.8.html">showq(8)</a> list mail queue
+       <a href="smtpd.8.html">smtpd(8)</a> SMTP server
+       flushd(8) fast flush service
+       syslogd(8) system logging
+
+<b>LICENSE</b>
+       The  Secure  Mailer  license must be distributed with this
+       software.
+
 <b>AUTHOR(S)</b>
        Wietse Venema
        IBM T.J. Watson Research
@@ -365,19 +378,6 @@ SENDMAIL(1)                                           SENDMAIL(1)
 
 
 
-
-
-
-
-
-
-
-
-
-
-
-
-
 
 
 
index b66cb3de39844f39ea7f24ed7ea60fdaa93c0622..f82ef92699a56471d2eab423c95a670e6b44c7b5 100644 (file)
@@ -5,7 +5,7 @@ SHELL   = /bin/sh
 DAEMONS        = man8/bounce.8 man8/defer.8 man8/cleanup.8 man8/error.8 man8/local.8 \
        man8/lmtp.8 man8/master.8 man8/pickup.8 man8/pipe.8 man8/qmgr.8 \
        man8/showq.8 man8/smtp.8 man8/smtpd.8 man8/trivial-rewrite.8 \
-       man8/nqmgr.8 man8/spawn.8
+       man8/nqmgr.8 man8/spawn.8 man8/flushd.8
 COMMANDS= man1/postalias.1 man1/postcat.1 man1/postconf.1 man1/postfix.1 \
        man1/postkick.1 man1/postlock.1 man1/postlog.1 man1/postdrop.1 \
        man1/postmap.1 man1/sendmail.1 man1/mailq.1 man1/newaliases.1 \
@@ -38,6 +38,9 @@ man8/cleanup.8: ../src/cleanup/cleanup.c
 man8/error.8: ../src/error/error.c
        ../mantools/srctoman $? >$@
 
+man8/flushd.8: ../src/flushd/flushd.c
+       ../mantools/srctoman $? >$@
+
 man8/local.8: ../src/local/local.c
        ../mantools/srctoman $? >$@
 
index fc7821722953713c225bc32666defc872962e5f8..641e544aada684d7bd4d221ba2c189b2ca101a41 100644 (file)
@@ -135,6 +135,16 @@ Flush the mail queue. This is implemented by kicking the
 .IP "\fB-q\fIinterval\fR (ignored)"
 The interval between queue runs. Use the \fBqueue_run_delay\fR
 configuration parameter instead.
+.IP \fB-qR\fIsite\fR
+Schedule immediate delivery of all mail that is queued for the named
+\fIsite\fR.
+This functionality is available only for sites that are configured
+for the \fBfast flush\fR service support as described in
+\fBflushd\fR(8).  For other sites, this command is equivalent to
+using the slower \fBsendmail -q\fR instead.
+.IP \fB-qS\fIsite\fR
+The site name is ignored. This command is equivalent to using
+the slower \fBsendmail -q\fR instead.
 .IP \fB-t\fR
 Extract recipients from message headers. This requires that no
 recipients be specified on the command line.
@@ -228,6 +238,7 @@ postkick(1) kick a Postfix daemon
 qmgr(8) queue manager
 showq(8) list mail queue
 smtpd(8) SMTP server
+flushd(8) fast flush service
 syslogd(8) system logging
 .SH LICENSE
 .na
diff --git a/postfix/man/man8/flushd.8 b/postfix/man/man8/flushd.8
new file mode 100644 (file)
index 0000000..74a5c23
--- /dev/null
@@ -0,0 +1,94 @@
+.TH FLUSHD 8 
+.ad
+.fi
+.SH NAME
+flushd
+\-
+Postfix fast flush daemon
+.SH SYNOPSIS
+.na
+.nf
+\fBflushd\fR [generic Postfix daemon options]
+.SH DESCRIPTION
+.ad
+.fi
+The flush server maintains so-called "fast flush" logfiles with
+information about what messages are queued for a specific site.
+This program expects to be run from the \fBmaster\fR(8) process
+manager.
+
+This server implements the following requests:
+.IP "FLUSH_REQ_ADD sitename queue_id"
+Append a record to the per-site fast flush logfile for the specified
+queue ID.
+.IP "FLUSH_REQ_SEND sitename"
+Arrange for the delivery of all messages that are listed in the fast
+flush logfile for the specified site.  After the logfile is processed,
+the file is truncated to length zero.
+.PP
+The response to the client is one of:
+.IP FLUSH_STAT_OK
+The request completed normally.
+.IP FLUSH_STAT_BAD
+The flush server rejected the request (bad request name, bad
+request parameter value).
+.IP FLUSH_STAT_UNKNOWN
+The specified site has no fast flush logfile and is not configured
+to have one.
+.SH SECURITY
+.na
+.nf
+.ad
+.fi
+The fast flush server is moderately security-sensitive. It does not
+talk to the network, but it does talk to local unprivileged users, in
+order to emulate "sendmail -qRsite" behavior.  For this reason all
+strings in a request are truncated at \fline_length_limit\fR.
+
+The fast flush server can run chrooted at fixed low privilege.
+.SH DIAGNOSTICS
+.ad
+.fi
+Problems and transactions are logged to \fBsyslogd\fR(8).
+.SH BUGS
+.ad
+.fi
+In reality, this server schedules delivery of messages, regardless
+of their destination. This limitation is due to the fact that
+one queue runner has to handle mail for multiple destinations.
+.SH CONFIGURATION PARAMETERS
+.na
+.nf
+.ad
+.fi
+The following \fBmain.cf\fR parameters are especially relevant to
+this program. See the Postfix \fBmain.cf\fR file for syntax details
+and for default values. Use the \fBpostfix reload\fR command after
+a configuration change.
+.IP \fBfast_flush_maps\fR
+The table with names of destinations that this MTA provides the
+fast flush service for, and with clients that may issue the ETRN
+command for those destinations. Postfix maintains fast flush logfiles
+only for destinations listed in this table.
+.IP \fBline_length_limit\fR
+Maximal length of strings in a fast flush client request.
+.SH SEE ALSO
+.na
+.nf
+smtp(8) Postfix SMTP client
+smtpd) Postfix SMTP server
+qmgr(8) Postfix queue manager
+syslogd(8) system logging
+.SH LICENSE
+.na
+.nf
+.ad
+.fi
+The Secure Mailer license must be distributed with this software.
+.SH AUTHOR(S)
+.na
+.nf
+Wietse Venema
+IBM T.J. Watson Research
+P.O. Box 704
+Yorktown Heights, NY 10598, USA
diff --git a/postfix/src/flushd/.indent.pro b/postfix/src/flushd/.indent.pro
new file mode 120000 (symlink)
index 0000000..5c837ec
--- /dev/null
@@ -0,0 +1 @@
+../../.indent.pro
\ No newline at end of file
diff --git a/postfix/src/flushd/Makefile.in b/postfix/src/flushd/Makefile.in
new file mode 100644 (file)
index 0000000..7345e63
--- /dev/null
@@ -0,0 +1,76 @@
+SHELL  = /bin/sh
+SRCS   = flushd.c
+OBJS   = flushd.o
+HDRS   = 
+TESTSRC        =
+WARN   = -W -Wformat -Wimplicit -Wmissing-prototypes \
+       -Wparentheses -Wstrict-prototypes -Wswitch -Wuninitialized \
+       -Wunused
+DEFS   = -I. -I$(INC_DIR) -D$(SYSTYPE)
+CFLAGS = $(DEBUG) $(OPT) $(DEFS)
+TESTPROG= 
+PROG   = flushd
+INC_DIR = ../../include
+LIBS   = ../../lib/libmaster.a ../../lib/libglobal.a ../../lib/libutil.a
+
+.c.o:; $(CC) $(CFLAGS) -c $*.c
+
+$(PROG): $(OBJS) $(LIBS)
+       $(CC) $(CFLAGS) -o $@ $(OBJS) $(LIBS) $(SYSLIBS)
+
+Makefile: Makefile.in
+       (set -e; echo "# DO NOT EDIT"; $(OPTS) $(SHELL) ../../makedefs; cat $?) >$@
+
+test:  $(TESTPROG)
+
+update: ../../libexec/$(PROG)
+
+../../libexec/$(PROG): $(PROG)
+       cp $(PROG) ../../libexec
+
+printfck: $(OBJS) $(PROG)
+       rm -rf printfck
+       mkdir printfck
+       sed '1,/^# do not edit/!d' Makefile >printfck/Makefile
+       set -e; for i in *.c; do printfck -f .printfck $$i >printfck/$$i; done
+       cd printfck; make "INC_DIR=../../../include" `cd ..; ls *.o`
+
+lint:
+       lint $(DEFS) $(SRCS) $(LINTFIX)
+
+clean:
+       rm -f *.o *core $(PROG) $(TESTPROG) junk 
+       rm -rf printfck
+
+tidy:  clean
+
+depend: $(MAKES)
+       (sed '1,/^# do not edit/!d' Makefile.in; \
+       set -e; for i in [a-z][a-z0-9]*.c; do \
+           $(CC) -E $(DEFS) $(INCL) $$i | sed -n -e '/^# *1 *"\([^"]*\)".*/{' \
+           -e 's//'`echo $$i|sed 's/c$$/o/'`': \1/' -e 'p' -e '}'; \
+       done) | grep -v '[.][o][:][ ][/]' >$$$$ && mv $$$$ Makefile.in
+       @$(EXPORT) make -f Makefile.in Makefile 1>&2
+
+# do not edit below this line - it is generated by 'make depend'
+flushd.o: flushd.c
+flushd.o: ../../include/sys_defs.h
+flushd.o: ../../include/msg.h
+flushd.o: ../../include/events.h
+flushd.o: ../../include/vstream.h
+flushd.o: ../../include/vbuf.h
+flushd.o: ../../include/vstring.h
+flushd.o: ../../include/vstring_vstream.h
+flushd.o: ../../include/myflock.h
+flushd.o: ../../include/valid_hostname.h
+flushd.o: ../../include/htable.h
+flushd.o: ../../include/dict.h
+flushd.o: ../../include/argv.h
+flushd.o: ../../include/mail_params.h
+flushd.o: ../../include/mail_queue.h
+flushd.o: ../../include/mail_proto.h
+flushd.o: ../../include/iostuff.h
+flushd.o: ../../include/mail_flush.h
+flushd.o: ../../include/mail_conf.h
+flushd.o: ../../include/maps.h
+flushd.o: ../../include/mail_server.h
diff --git a/postfix/src/flushd/flushd.c b/postfix/src/flushd/flushd.c
new file mode 100644 (file)
index 0000000..189e287
--- /dev/null
@@ -0,0 +1,375 @@
+/*++
+/* NAME
+/*     flushd 8
+/* SUMMARY
+/*     Postfix fast flush daemon
+/* SYNOPSIS
+/*     \fBflushd\fR [generic Postfix daemon options]
+/* DESCRIPTION
+/*     The flush server maintains so-called "fast flush" logfiles with
+/*     information about what messages are queued for a specific site.
+/*     This program expects to be run from the \fBmaster\fR(8) process
+/*     manager.
+/*
+/*     This server implements the following requests:
+/* .IP "FLUSH_REQ_ADD sitename queue_id"
+/*     Append a record to the per-site fast flush logfile for the specified
+/*     queue ID.
+/* .IP "FLUSH_REQ_SEND sitename"
+/*     Arrange for the delivery of all messages that are listed in the fast 
+/*     flush logfile for the specified site.  After the logfile is processed, 
+/*     the file is truncated to length zero.
+/* .PP
+/*     The response to the client is one of:
+/* .IP FLUSH_STAT_OK
+/*     The request completed normally.
+/* .IP FLUSH_STAT_BAD
+/*     The flush server rejected the request (bad request name, bad
+/*     request parameter value).
+/* .IP FLUSH_STAT_UNKNOWN
+/*     The specified site has no fast flush logfile and is not configured
+/*     to have one.
+/* SECURITY
+/* .ad
+/* .fi
+/*     The fast flush server is moderately security-sensitive. It does not
+/*     talk to the network, but it does talk to local unprivileged users, in
+/*     order to emulate "sendmail -qRsite" behavior.  For this reason all
+/*     strings in a request are truncated at \fline_length_limit\fR.
+/*
+/*     The fast flush server can run chrooted at fixed low privilege.
+/* DIAGNOSTICS
+/*     Problems and transactions are logged to \fBsyslogd\fR(8).
+/* BUGS
+/*     In reality, this server schedules delivery of messages, regardless
+/*     of their destination. This limitation is due to the fact that
+/*     one queue runner has to handle mail for multiple destinations.
+/* CONFIGURATION PARAMETERS
+/* .ad
+/* .fi
+/*     The following \fBmain.cf\fR parameters are especially relevant to
+/*     this program. See the Postfix \fBmain.cf\fR file for syntax details
+/*     and for default values. Use the \fBpostfix reload\fR command after
+/*     a configuration change.
+/* .IP \fBfast_flush_maps\fR
+/*     The table with names of destinations that this MTA provides the
+/*     fast flush service for, and with clients that may issue the ETRN
+/*     command for those destinations. Postfix maintains fast flush logfiles
+/*     only for destinations listed in this table.
+/* .IP \fBline_length_limit\fR
+/*     Maximal length of strings in a fast flush client request.
+/* SEE ALSO
+/*     smtp(8) Postfix SMTP client
+/*     smtpd) Postfix SMTP server
+/*     qmgr(8) Postfix queue manager
+/*     syslogd(8) system logging
+/* 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 <stdlib.h>
+#include <utime.h>
+#include <errno.h>
+
+/* Utility library. */
+
+#include <msg.h>
+#include <events.h>
+#include <vstream.h>
+#include <vstring.h>
+#include <vstring_vstream.h>
+#include <myflock.h>
+#include <valid_hostname.h>
+#include <htable.h>
+#include <dict.h>
+
+/* Global library. */
+
+#include <mail_params.h>
+#include <mail_queue.h>
+#include <mail_proto.h>
+#include <mail_flush.h>
+#include <mail_conf.h>
+#include <maps.h>
+
+/* Single server skeleton. */
+
+#include <mail_server.h>
+
+ /*
+  * Tunable parameters.
+  */
+char   *var_fflush_maps;
+
+/* Application-specific. */
+
+#define STR(x) vstring_str(x)
+#define MAX_DUP_FILTER 10000
+
+static MAPS *fflush_maps;
+
+/* flush_append - append queue ID to per-site fast flush logfile */
+
+static int flush_append(const char *site, const char *queue_id)
+{
+    char   *myname = "flush_append";
+    VSTREAM *log;
+
+    if (msg_verbose)
+       msg_info("%s: site %s queue_id %s", myname, site, queue_id);
+
+    /*
+     * Open or create the logfile. We allow for the fact that a logfile
+     * exists for a site that is no longer listed in the fast flush maps.
+     */
+    if ((log = mail_queue_open(MAIL_QUEUE_FLUSH, site, O_WRONLY, 0600)) == 0) {
+       if (errno != ENOENT)
+           msg_fatal("%s: open fast flush log for site %s: %m", myname, site);
+       if (maps_find(fflush_maps, site, 0) == 0) {
+           msg_warn("no fast flush support configured for site %s", site);
+           return (FLUSH_STAT_UNKNOWN);
+       }
+       log = mail_queue_open(MAIL_QUEUE_FLUSH, site, O_CREAT | O_WRONLY, 0600);
+       if (log == 0)
+           msg_fatal("%s: open fast flush log for site %s: %m", myname, site);
+    }
+
+    /*
+     * We must lock the logfile, so that we don't lose information due to
+     * concurrent access. If the lock takes too long, the Postfix watchdog
+     * will eventually take care of the problem, but it will take a while.
+     */
+    if (myflock(vstream_fileno(log), MYFLOCK_EXCLUSIVE) < 0)
+       msg_fatal("%s: lock fast flush log for site %s: %m", myname, site);
+
+    /*
+     * Append the queue ID. With 15 bits if microsecond time, a queue ID is
+     * not recycled often enough for false hits to be a problem. If it does,
+     * then we could add other signature information, such as the file size
+     * in bytes.
+     */
+    vstream_fprintf(log, "%s\n", queue_id);
+
+    /*
+     * Clean up.
+     */
+    if (myflock(vstream_fileno(log), MYFLOCK_NONE) < 0)
+       msg_fatal("%s: unlock fast flush logfile for site %s: %m",
+                 myname, site);
+    if (vstream_fclose(log) != 0)
+       msg_warn("write fast flush logfile for site %s: %m", site);
+
+    return (FLUSH_STAT_OK);
+}
+
+/* flush_site - flush mail queued for site */
+
+static int flush_site(const char *site)
+{
+    char   *myname = "flush_site";
+    VSTRING *queue_id;
+    VSTRING *queue_file;
+    VSTREAM *log;
+    struct utimbuf tbuf;
+    static char qmgr_trigger[] = {
+       QMGR_REQ_SCAN_DEFERRED,         /* scan deferred queue */
+       QMGR_REQ_SCAN_INCOMING,         /* scan incoming queue */
+    };
+    HTABLE *dup_filter;
+
+    if (msg_verbose)
+       msg_info("%s: site %s", myname, site);
+
+    /*
+     * Open the logfile.
+     */
+    if ((log = mail_queue_open(MAIL_QUEUE_FLUSH, site, O_RDWR, 0600)) == 0) {
+       if (errno != ENOENT)
+           msg_fatal("%s: open fast flush log for site %s: %m", myname, site);
+       if (maps_find(fflush_maps, site, 0)) {
+           msg_warn("no fast flush log for site %s", site);
+           return (FLUSH_STAT_OK);
+       } else {
+           msg_warn("no fast flush support configured for site %s", site);
+           return (FLUSH_STAT_UNKNOWN);
+       }
+    }
+
+    /*
+     * We must lock the logfile, so that we don't lose information when it is
+     * truncated. Unfortunately, this means that the file can be locked for a
+     * significant amount of time. If things really get stuck the Postfix
+     * watchdog will take care of it.
+     */
+    if (myflock(vstream_fileno(log), MYFLOCK_EXCLUSIVE) < 0)
+       msg_fatal("%s: lock fast flush log for site %s: %m", myname, site);
+
+    /*
+     * This is the part that dominates running time: schedule the listed
+     * queue files for delivery by updating their file time stamps. This
+     * should take no more than a couple seconds under normal conditions
+     * (sites that receive millions of messages in a day do not use fast
+     * flush routinely). Filter out duplicate names to avoid hammering the
+     * file system, with some finite limit on the amount of memory that we
+     * are willing to sacrifice. Graceful degradation.
+     */
+    queue_id = vstring_alloc(10);
+    queue_file = vstring_alloc(10);
+    dup_filter = htable_create(10);
+    tbuf.actime = tbuf.modtime = event_time();
+    while (vstring_get_nonl(queue_id, log) != VSTREAM_EOF) {
+       if (dup_filter->used >= MAX_DUP_FILTER
+           || htable_find(dup_filter, STR(queue_id)) == 0) {
+           if (msg_verbose)
+               msg_info("%s: site %s: update %s time stamps",
+                        myname, site, STR(queue_file));
+           if (dup_filter->used <= MAX_DUP_FILTER)
+               htable_enter(dup_filter, STR(queue_id), 0);
+
+           mail_queue_path(queue_file, MAIL_QUEUE_DEFERRED, STR(queue_id));
+           if (utime(STR(queue_file), &tbuf) == 0)
+               continue;
+           if (errno != ENOENT)
+               msg_fatal("%s: update %s time stamps: %m",
+                         myname, STR(queue_file));
+
+           mail_queue_path(queue_file, MAIL_QUEUE_INCOMING, STR(queue_id));
+           if (utime(STR(queue_file), &tbuf) == 0)
+               continue;
+           if (errno != ENOENT)
+               msg_fatal("%s: update %s time stamps: %m",
+                         myname, STR(queue_file));
+       } else {
+           if (msg_verbose)
+               msg_info("%s: site %s: skip file %s as duplicate",
+                        myname, site, STR(queue_file));
+       }
+    }
+    htable_free(dup_filter, (void (*) (char *)) 0);
+    vstring_free(queue_file);
+    vstring_free(queue_id);
+
+    /*
+     * Truncate the fast flush logfile.
+     */
+    if (ftruncate(vstream_fileno(log), (off_t) 0) < 0)
+       msg_fatal("%s: truncate fast flush logfile for site %s: %m",
+                 myname, site);
+
+    /*
+     * Request delivery and clean up.
+     */
+    if (myflock(vstream_fileno(log), MYFLOCK_NONE) < 0)
+       msg_fatal("%s: unlock fast flush logfile for site %s: %m",
+                 myname, site);
+    if (vstream_fclose(log) != 0)
+       msg_warn("read fast flush logfile for site %s: %m", site);
+    if (msg_verbose)
+       msg_info("%s: requesting delivery for site %s", myname, site);
+    mail_trigger(MAIL_CLASS_PUBLIC, MAIL_SERVICE_QUEUE,
+                qmgr_trigger, sizeof(qmgr_trigger));
+
+    return (FLUSH_STAT_OK);
+}
+
+/* flush_service - perform service for client */
+
+static void flush_service(VSTREAM *client_stream, char *unused_service,
+                                 char **argv)
+{
+    VSTRING *request = vstring_alloc(10);
+    VSTRING *site = vstring_alloc(10);
+    VSTRING *queue_id;
+    int     status = FLUSH_STAT_BAD;
+
+    /*
+     * Sanity check. This service takes no command-line arguments.
+     */
+    if (argv[0])
+       msg_fatal("unexpected command-line argument: %s", argv[0]);
+
+    /*
+     * Vandalism control. Read no unlimited amounts of garbage from a public
+     * socket.
+     */
+    vstring_ctl(request, VSTRING_CTL_MAXLEN, var_line_limit, VSTRING_CTL_END);
+    vstring_ctl(site, VSTRING_CTL_MAXLEN, var_line_limit, VSTRING_CTL_END);
+
+    /*
+     * This routine runs whenever a client connects to the UNIX-domain socket
+     * dedicated to the fast flush service. What we see below is a little
+     * protocol to (1) read a request from the client (the name of the site)
+     * and (2) acknowledge that we have received the request. Since the site
+     * name maps onto the file system, make sure the site name is a valid
+     * SMTP hostname.
+     * 
+     * All connection-management stuff is handled by the common code in
+     * single_server.c.
+     */
+#define STREQ(x,y) (strcmp((x), (y)) == 0)
+
+    if (mail_scan(client_stream, "%s %s", request, site) == 2
+       && valid_hostname(STR(site))) {
+       if (STREQ(STR(request), FLUSH_REQ_ADD)) {
+           queue_id = vstring_alloc(10);
+           vstring_ctl(queue_id, VSTRING_CTL_MAXLEN, var_line_limit,
+                       VSTRING_CTL_END);
+           if (mail_scan(client_stream, "%s", queue_id) == 1)
+               status = flush_append(STR(site), STR(queue_id));
+           vstring_free(queue_id);
+       } else if (STREQ(STR(request), FLUSH_REQ_SEND)) {
+           status = flush_site(STR(site));
+       }
+    }
+    mail_print(client_stream, "%d", status);
+    vstring_free(site);
+    vstring_free(request);
+}
+
+/* pre_accept - see if tables have changed */
+
+static void pre_accept(char *unused_name, char **unused_argv)
+{
+    if (dict_changed()) {
+       msg_info("table has changed -- exiting");
+       exit(0);
+    }
+}
+
+/* pre_jail_init - pre-chroot initialization */
+
+static void pre_jail_init(char *unused_service, char **unused_argv)
+{
+    fflush_maps = maps_create(VAR_FFLUSH_MAPS, var_fflush_maps,
+                             DICT_FLAG_LOCK);
+}
+
+/* pre_accept_init - check map status */
+
+
+/* main - pass control to the single-threaded skeleton */
+
+int     main(int argc, char **argv)
+{
+    static CONFIG_STR_TABLE str_table[] = {
+       VAR_FFLUSH_MAPS, DEF_FFLUSH_MAPS, &var_fflush_maps, 0, 0,
+       0,
+    };
+
+    single_server_main(argc, argv, flush_service,
+                      MAIL_SERVER_PRE_INIT, pre_jail_init,
+                      MAIL_SERVER_PRE_ACCEPT, pre_accept,
+                      MAIL_SERVER_STR_TABLE, str_table,
+                      0);
+}
index 3168c858e067a4b533045b849471a6529de96f13..b09b2ec4a610d06895cd59a5b85fcab42dae61fc 100644 (file)
@@ -55,7 +55,7 @@ HDRS  = been_here.h bounce.h canon_addr.h cleanup_user.h clnt_stream.h \
 TESTSRC        = rec2stream.c stream2rec.c recdump.c
 WARN   = -W -Wformat -Wimplicit -Wmissing-prototypes \
        -Wparentheses -Wstrict-prototypes -Wswitch -Wuninitialized \
-       -Wunused 
+       -Wunused
 DEFS   = -I. -I$(INC_DIR) -D$(SYSTYPE)
 CFLAGS = $(DEBUG) $(OPT) $(DEFS)
 INCL   =
@@ -221,7 +221,7 @@ lint:
        lint $(DEFS) $(SRCS) $(LINTFIX)
 
 clean:
-       rm -f *.o $(LIB) *core $(TESTPROG) junk 
+       rm -f *.o $(LIB) *core $(TESTPROG) junk
        rm -rf printfck
 
 tidy:  clean
@@ -257,11 +257,13 @@ bounce.o: defer.h
 bounce.o: bounce.h
 bounce_log.o: bounce_log.c
 bounce_log.o: ../../include/sys_defs.h
+bounce_log.o: ../../include/msg.h
 bounce_log.o: ../../include/mymalloc.h
 bounce_log.o: ../../include/vstream.h
 bounce_log.o: ../../include/vbuf.h
 bounce_log.o: ../../include/vstring.h
 bounce_log.o: ../../include/vstring_vstream.h
+bounce_log.o: ../../include/stringops.h
 bounce_log.o: mail_queue.h
 bounce_log.o: bounce_log.h
 canon_addr.o: canon_addr.c
@@ -537,11 +539,13 @@ mail_error.o: mail_error.h
 mail_error.o: ../../include/name_mask.h
 mail_flush.o: mail_flush.c
 mail_flush.o: ../../include/sys_defs.h
-mail_flush.o: mail_proto.h
+mail_flush.o: ../../include/msg.h
 mail_flush.o: ../../include/vstream.h
 mail_flush.o: ../../include/vbuf.h
+mail_flush.o: mail_proto.h
 mail_flush.o: ../../include/iostuff.h
 mail_flush.o: mail_flush.h
+mail_flush.o: mail_params.h
 mail_open_ok.o: mail_open_ok.c
 mail_open_ok.o: ../../include/sys_defs.h
 mail_open_ok.o: ../../include/msg.h
@@ -591,6 +595,7 @@ mail_queue.o: ../../include/dir_forest.h
 mail_queue.o: ../../include/make_dirs.h
 mail_queue.o: ../../include/split_at.h
 mail_queue.o: ../../include/sane_fsops.h
+mail_queue.o: ../../include/valid_hostname.h
 mail_queue.o: file_id.h
 mail_queue.o: mail_params.h
 mail_queue.o: mail_queue.h
@@ -613,6 +618,7 @@ mail_scan.o: ../../include/vstring_vstream.h
 mail_scan.o: ../../include/mymalloc.h
 mail_scan.o: mail_proto.h
 mail_scan.o: ../../include/iostuff.h
+mail_scan.o: mail_params.h
 mail_scan_dir.o: mail_scan_dir.c
 mail_scan_dir.o: ../../include/sys_defs.h
 mail_scan_dir.o: ../../include/scan_dir.h
index 4513247c3a1dfb73eff7f9b508d2ee464555471c..6fd200bc64754d390e0557b35b758e3a8aacaa60 100644 (file)
@@ -74,7 +74,7 @@
 
  /*
   * CLNT_STREAM is an opaque structure. None of the access methods can easily
-  * be implemented as a macro, and access is not performance critica anyway.
+  * be implemented as a macro, and access is not performance critical anyway.
   */
 struct CLNT_STREAM {
     VSTREAM *vstream;                  /* buffered I/O */
index 42a48a6ab515e176fd2140eeb71c7b85df000559..e7b8fc8ca3ed581f7f38e24b73e9c3abbf77f539 100644 (file)
@@ -2,7 +2,7 @@
 /* NAME
 /*     mail_flush 3
 /* SUMMARY
-/*     flush backed up mail
+/*     mail flush service client interface
 /* SYNOPSIS
 /*     #include <mail_flush.h>
 /*
 /*
 /*     int     mail_flush_site(site)
 /*     const char *site;
+/*
+/*     int     mail_flush_append(site, queue_id)
+/*     const char *site;
+/*     const char *queue_id;
 /* DESCRIPTION
-/*     This module triggers delivery of backed up mail.
+/*     This module deals with delivery of backed up mail.
 /*
 /*     mail_flush_deferred() triggers delivery of all deferred
 /*     or incoming mail.
 /*
-/*     mail_flush_site() triggers delivery of all mail queued for
-/*     the named site. This routine may degenerate into a
-/*     mail_flush_deferred() call.
+/*     mail_flush_site() uses the "fash flush" service to trigger
+/*     delivery of messages queued for the specified site.
+/*     This service is available only for sites that are configured
+/*     to have a deferred mail logfile.
+/*
+/*     mail_flush_append() appends a record to the "fash flush"
+/*     logfile of the specified site, with the queue ID of mail
+/*     that should still be delivered.
 /* DIAGNOSTICS
-/*     The result is 0 in case of success, -1 in case of failure.
+/*     The result codes and their meaning are (see mail_flush(5h)):
+/* .IP MAIL_FLUSH_OK
+/*     The request completed normally.
+/* .IP MAIL_FLUSH_FAIL
+/*     The request failed.
+/* .IP "MAIL_FLUSH_UNKNOWN (mail_flush_site() only)"
+/*     The specified site is not configured for the fast flush service.
+/* .IP "MAIL_FLUSH_BAD (mail_flush_site() only)"
+/*     The fast flush server rejected the request.
 /* LICENSE
 /* .ad
 /* .fi
 /* System library. */
 
 #include "sys_defs.h"
+#include <unistd.h>
+#include <stdarg.h>
 
 /* Utility library. */
 
+#include <msg.h>
+#include <vstream.h>
+
 /* Global library. */
 
 #include <mail_proto.h>
 #include <mail_flush.h>
+#include <mail_params.h>
 
 /* mail_flush_deferred - flush deferred queue */
 
@@ -61,14 +84,74 @@ int     mail_flush_deferred(void)
                         qmgr_trigger, sizeof(qmgr_trigger)));
 }
 
-/* mail_flush_site - flush deferred mail for site */
+/* mail_flush_clnt - generic fast flush service client */
 
-int     mail_flush_site(const char *unused_site)
+static int mail_flush_clnt(const char *format, ...)
 {
+    VSTREAM *flush;
+    int     status;
+    va_list ap;
+
+    /*
+     * Connect to the fast flush service over local IPC.
+     */
+    if ((flush = mail_connect(MAIL_CLASS_PUBLIC, MAIL_SERVICE_FLUSH,
+                             BLOCKING)) == 0)
+       return (FLUSH_STAT_FAIL);
+
+    /*
+     * Do not get stuck forever.
+     */
+    vstream_control(flush,
+                   VSTREAM_CTL_TIMEOUT, var_ipc_timeout,
+                   VSTREAM_CTL_END);
+
+    /*
+     * Send a request with the site name, and receive the request completion
+     * status.
+     */
+    va_start(ap, format);
+    mail_vprint(flush, format, ap);
+    va_end(ap);
+    if (mail_scan(flush, "%d", &status) != 1)
+       status = FLUSH_STAT_FAIL;
 
     /*
-     * Until we have dedicated per-site queues, this call will degenerate
-     * into a mail_flush_deferred() call.
+     * Clean up.
      */
-    return (mail_flush_deferred());
+    vstream_fclose(flush);
+
+    return (status);
+}
+
+/* mail_flush_site - flush deferred mail for site */
+
+int     mail_flush_site(const char *site)
+{
+    char   *myname = "mail_flush_site";
+    int     status;
+
+    if (msg_verbose)
+       msg_info("%s: site %s", myname, site);
+    status = mail_flush_clnt("%s %s", FLUSH_REQ_SEND, site);
+    if (msg_verbose)
+       msg_info("%s: site %s status %d", myname, site, status);
+
+    return (status);
+}
+
+/* mail_flush_append - append record to fast flush log */
+
+int     mail_flush_append(const char *site, const char *queue_id)
+{
+    char   *myname = "mail_flush_append";
+    int     status;
+
+    if (msg_verbose)
+       msg_info("%s: site %s id %s", myname, site, queue_id);
+    status = mail_flush_clnt("%s %s %s", FLUSH_REQ_ADD, site, queue_id);
+    if (msg_verbose)
+       msg_info("%s: site %s id %s status %d", myname, site, queue_id, status);
+
+    return (status);
 }
index defd15c2a24d4275cb457e7c24e131cc0328a706..dfce76229b1db0a8182eb2d638517b0feda47bf9 100644 (file)
 /* DESCRIPTION
 /* .nf
 
- /* External interface. */
-
+ /*
+  * External interface.
+  */
 extern int mail_flush_deferred(void);
 extern int mail_flush_site(const char *);
+extern int mail_flush_append(const char *, const char *);
+
+ /*
+  * Mail flush server requests.
+  */
+#define FLUSH_REQ_ADD          "add"   /* add queue ID to site log */
+#define FLUSH_REQ_SEND         "send"  /* flush mail queued for site */
+
+ /*
+  * Mail flush server status codes.
+  */
+#define FLUSH_STAT_FAIL                -1      /* everyone */
+#define FLUSH_STAT_OK          0       /* everyone */
+#define FLUSH_STAT_UNKNOWN     2       /* mail_flush_site() only */
+#define FLUSH_STAT_BAD         3       /* mail_flush_site() only */
+
 
 /* LICENSE
-/* .ad
 /* .fi
 /*     The Secure Mailer license must be distributed with this software.
 /* AUTHOR(S)
@@ -26,5 +42,6 @@ extern int mail_flush_site(const char *);
 /*     P.O. Box 704
 /*     Yorktown Heights, NY 10598, USA
 /*--*/
+/**INDENT** Error@33: Unmatched #endif */
 
 #endif
index 6902977b57a1e5e0539a41c4b6e7d989b4cedce0..a49f6746c594bf6cdd18ae1a2febbb33327ee28d 100644 (file)
@@ -1064,6 +1064,13 @@ extern void mail_params_init(void);
 #define DEF_FILTER_XPORT               ""
 extern char *var_filter_xport;
 
+ /*
+  * Fast flush support.
+  */
+#define VAR_FFLUSH_MAPS                        "fast_flush_maps"
+#define DEF_FFLUSH_MAPS                        ""
+extern char *var_fflush_maps;
+
 /* LICENSE
 /* .ad
 /* .fi
index 275680c51471ccfa72582d7d19730b0aed4fa3ab..78b76c864ec569f549b12847264cfd8787369e3e 100644 (file)
@@ -40,6 +40,7 @@
 #define MAIL_SERVICE_SMTPD     "smtpd"
 #define MAIL_SERVICE_SHOWQ     "showq"
 #define MAIL_SERVICE_ERROR     "error"
+#define MAIL_SERVICE_FLUSH     "flush"
 
  /*
   * Well-known socket or FIFO directories. The main difference is in file
index f5645ffac11dc23699bce3648722e609ffd16d7d..73ede8534f7d08f38d622ad234b5754b2ea188ab 100644 (file)
 #include <make_dirs.h>
 #include <split_at.h>
 #include <sane_fsops.h>
+#include <valid_hostname.h>
 
 /* Global library. */
 
@@ -281,6 +282,15 @@ int     mail_queue_id_ok(const char *queue_id)
 {
     const char *cp;
 
+    /*
+     * Must be in valid hostname form.
+     */
+    if (valid_hostname(queue_id))
+       return (1);
+
+    /*
+     * Must be in time+inum form.
+     */
     for (cp = queue_id; *cp; cp++)
        if (!ISALNUM(*cp))
            return (0);
index acba6a3d0f91705016b6ab785df7a482b6fca738..9486eb8ffefb5a497574e4f6f03a034b6655c44a 100644 (file)
@@ -27,6 +27,7 @@
 #define MAIL_QUEUE_DEFER       "defer"
 #define MAIL_QUEUE_BOUNCE      "bounce"
 #define MAIL_QUEUE_CORRUPT     "corrupt"
+#define MAIL_QUEUE_FLUSH       "flush"
 
  /*
   * Queue file modes.
index 0538c40bfe53e47c63f7a1403d145d6c3de0cffa..dfe96e2372eb562fc45b0c1a58b58ea882df9488 100644 (file)
@@ -33,6 +33,8 @@
 /*     White space in the format string is ignored.
 /* .IP %s
 /*     The corresponding argument has type (VSTRING *).
+/*     If the string has a size limit, no more characters will be read
+/*     into the string than is specified via that size limit.
 /* .IP %d
 /*     The corresponding argument has type (int *).
 /* .IP %ld
 /* Global library. */
 
 #include "mail_proto.h"
+#include "mail_params.h"
 
  /*
   * Provision for the user to register type-specific input conversion
@@ -145,7 +148,8 @@ void    mail_scan_register(int letter, const char *name, MAIL_SCAN_FN scanner)
 
 static int mail_scan_any(VSTREAM *stream, VSTRING *vp, char *what)
 {
-    if (vstring_fgets_null(vp, stream) == 0) {
+    if ((vp->maxlen ? vstring_fgets_null_bound(vp, stream, vp->maxlen)
+        : vstring_fgets_null(vp, stream)) == 0) {
        msg_warn("mail_scan_any: got EOF; expected: %s", what);
        return (-1);
     }
@@ -230,9 +234,10 @@ int     mail_vscan(VSTREAM *stream, const char *fmt, va_list ap)
     static VSTRING *tmp;
     MAIL_SCAN *tp;
 
-    if (tmp == 0)
+    if (tmp == 0) {
        tmp = vstring_alloc(100);
-
+       tmp->maxlen = var_line_limit;           /* good enough for numbers */
+    }
     for (count = 0, error = 0, cp = fmt; error == 0 && *cp != 0; cp++) {
        if (ISSPACE(*cp))
            continue;
index c6cebe89fa623fc88e0ad4046ffddba1c430e75e..138e4030f9e64508401014837db5dd9d757d0f9c 100644 (file)
@@ -15,7 +15,7 @@
   * Version of this program.
   */
 #define VAR_MAIL_VERSION       "mail_version"
-#define DEF_MAIL_VERSION       "Snapshot-20000924"
+#define DEF_MAIL_VERSION       "Snapshot-20000927"
 extern char *var_mail_version;
 
 /* LICENSE
index 7c1d11a950228f7c51589e5ff5b97ca4ad18b9d0..af253cecc472b0589ace0d8df6acd8e4661d6247 100644 (file)
@@ -332,12 +332,14 @@ char   *var_relocated_maps;
 char   *var_virtual_maps;
 char   *var_defer_xports;
 bool    var_allow_min_user;
+char   *var_fflush_maps;
 
 static QMGR_SCAN *qmgr_incoming;
 static QMGR_SCAN *qmgr_deferred;
 
 MAPS   *qmgr_relocated;
 MAPS   *qmgr_virtual;
+MAPS   *qmgr_fflush;
 
 /* qmgr_deferred_run_event - queue manager heartbeat */
 
@@ -471,6 +473,9 @@ static void qmgr_pre_init(char *unused_name, char **unused_argv)
     if (*var_virtual_maps)
        qmgr_virtual = maps_create("virtual", var_virtual_maps,
                                   DICT_FLAG_LOCK);
+    if (*var_fflush_maps)
+       qmgr_fflush = maps_create(VAR_FFLUSH_MAPS, var_fflush_maps,
+                                 DICT_FLAG_LOCK);
 }
 
 /* qmgr_post_init - post-jail initialization */
@@ -508,6 +513,7 @@ int     main(int argc, char **argv)
        VAR_RELOCATED_MAPS, DEF_RELOCATED_MAPS, &var_relocated_maps, 0, 0,
        VAR_VIRTUAL_MAPS, DEF_VIRTUAL_MAPS, &var_virtual_maps, 0, 0,
        VAR_DEFER_XPORTS, DEF_DEFER_XPORTS, &var_defer_xports, 0, 0,
+       VAR_FFLUSH_MAPS, DEF_FFLUSH_MAPS, &var_fflush_maps, 0, 0,
        0,
     };
     static CONFIG_INT_TABLE int_table[] = {
index 2da9dea0b403527621ce6a71a7bfad61701955b3..b062197592a1a7484541a2efc0636fb074d541ef 100644 (file)
@@ -275,6 +275,7 @@ extern int qmgr_message_count;
 extern int qmgr_recipient_count;
 extern MAPS *qmgr_relocated;
 extern MAPS *qmgr_virtual;
+extern MAPS *qmgr_fflush;
 
 extern void qmgr_message_free(QMGR_MESSAGE *);
 extern void qmgr_message_update_warn(QMGR_MESSAGE *);
index 1c92881aaf68249f9fff22e39d14fac592196301..8d70552c74ee38e3d03307b40ea3f8b45017bac1 100644 (file)
@@ -124,7 +124,7 @@ static int qmgr_deliver_send_request(QMGR_ENTRY *entry, VSTREAM *stream)
     QMGR_MESSAGE *message = entry->message;
 
     mail_print(stream, "%d %s %s %ld %ld %s %s %s %s %ld",
-              message->inspect_xport ? DEL_REQ_FLAG_BOUNCE : DEL_REQ_FLAG_DEFLT,
+         message->inspect_xport ? DEL_REQ_FLAG_BOUNCE : DEL_REQ_FLAG_DEFLT,
               message->queue_name, message->queue_id,
               message->data_offset, message->data_size,
               entry->queue->name, message->sender,
@@ -212,6 +212,12 @@ static void qmgr_deliver_update(int unused_event, char *context)
            if (queue->window == 0)
                qmgr_defer_todo(queue, queue->reason);
        }
+
+       /*
+        * Optionally add this message to the fast flush log for this site.
+        */
+       if (qmgr_fflush && maps_find(qmgr_fflush, queue->name, 0))
+           mail_flush_append(queue->name, message->queue_id);
     }
 
     /*
index ccd3f09af8c2c8f0a565f2f40aca2954f98ec3ca..e93ab349afcc2c7c83cbc03d85d8961260b70d01 100644 (file)
@@ -117,6 +117,7 @@ static struct queue_info queue_info[] = {
     MAIL_QUEUE_DEFERRED, MAIL_QUEUE_STAT_READY, RECURSE,
     MAIL_QUEUE_DEFER, 0600, RECURSE,
     MAIL_QUEUE_BOUNCE, 0600, RECURSE,
+    MAIL_QUEUE_FLUSH, 0600, RECURSE,
     0,
 };
 
index ad3320b48a9ac4682c63dbd85de97dc687096228..aa974a8c665b8701378c305fa5e00074fea1aa6b 100644 (file)
@@ -135,6 +135,7 @@ qmgr_deliver.o: ../../include/mail_proto.h
 qmgr_deliver.o: ../../include/recipient_list.h
 qmgr_deliver.o: ../../include/mail_params.h
 qmgr_deliver.o: ../../include/deliver_request.h
+qmgr_deliver.o: ../../include/mail_flush.h
 qmgr_deliver.o: qmgr.h
 qmgr_deliver.o: ../../include/scan_dir.h
 qmgr_deliver.o: ../../include/maps.h
index 374008e921903443f0911b9412e5f05dbdc16430..f8ae84f02f60956ed9eb0d7f03eb0959354a3b50 100644 (file)
@@ -292,12 +292,14 @@ bool    var_allow_min_user;
 int     var_qmgr_fudge;
 int     var_qmgr_hog;
 int     var_local_rcpt_lim;            /* XXX */
+char   *var_fflush_maps;
 
 static QMGR_SCAN *qmgr_incoming;
 static QMGR_SCAN *qmgr_deferred;
 
 MAPS   *qmgr_relocated;
 MAPS   *qmgr_virtual;
+MAPS   *qmgr_fflush;
 
 /* qmgr_deferred_run_event - queue manager heartbeat */
 
@@ -434,6 +436,9 @@ static void qmgr_pre_init(char *unused_name, char **unused_argv)
     if (*var_virtual_maps)
        qmgr_virtual = maps_create("virtual", var_virtual_maps,
                                   DICT_FLAG_LOCK);
+    if (*var_fflush_maps)
+       qmgr_fflush = maps_create(VAR_FFLUSH_MAPS, var_fflush_maps,
+                                 DICT_FLAG_LOCK);
 }
 
 /* qmgr_post_init - post-jail initialization */
@@ -471,6 +476,7 @@ int     main(int argc, char **argv)
        VAR_RELOCATED_MAPS, DEF_RELOCATED_MAPS, &var_relocated_maps, 0, 0,
        VAR_VIRTUAL_MAPS, DEF_VIRTUAL_MAPS, &var_virtual_maps, 0, 0,
        VAR_DEFER_XPORTS, DEF_DEFER_XPORTS, &var_defer_xports, 0, 0,
+       VAR_FFLUSH_MAPS, DEF_FFLUSH_MAPS, &var_fflush_maps, 0, 0,
        0,
     };
     static CONFIG_INT_TABLE int_table[] = {
index 45ceac8e99bcd50f03911fde770985d075d7fce9..71fe6d777d99c8df165024d9d5df0b8ffbf4b813 100644 (file)
@@ -242,6 +242,7 @@ extern int qmgr_message_count;
 extern int qmgr_recipient_count;
 extern MAPS *qmgr_relocated;
 extern MAPS *qmgr_virtual;
+extern MAPS *qmgr_fflush;
 
 extern void qmgr_message_free(QMGR_MESSAGE *);
 extern void qmgr_message_update_warn(QMGR_MESSAGE *);
index 466d5360d14b5c3c687342ba3a65e5f02b6cc0e9..0c6685c989b6a95a681ed0d5b6d092120ab0e0d8 100644 (file)
@@ -62,6 +62,7 @@
 #include <recipient_list.h>
 #include <mail_params.h>
 #include <deliver_request.h>
+#include <mail_flush.h>
 
 /* Application-specific. */
 
@@ -119,7 +120,7 @@ static int qmgr_deliver_send_request(QMGR_ENTRY *entry, VSTREAM *stream)
     QMGR_MESSAGE *message = entry->message;
 
     mail_print(stream, "%d %s %s %ld %ld %s %s %s %s %ld",
-              message->inspect_xport ? DEL_REQ_FLAG_BOUNCE : DEL_REQ_FLAG_DEFLT,
+         message->inspect_xport ? DEL_REQ_FLAG_BOUNCE : DEL_REQ_FLAG_DEFLT,
               message->queue_name, message->queue_id,
               message->data_offset, message->data_size,
               entry->queue->name, message->sender,
@@ -207,6 +208,12 @@ static void qmgr_deliver_update(int unused_event, char *context)
            if (queue->window == 0)
                qmgr_defer_todo(queue, queue->reason);
        }
+
+       /*
+        * Optionally add this message to the fast flush log for this site.
+        */
+       if (qmgr_fflush && maps_find(qmgr_fflush, queue->name, 0))
+           mail_flush_append(queue->name, message->queue_id);
     }
 
     /*
index 66a63f31f7b9382d1d86ae3a5ff7031af49715aa..66f780f0b433d156b561b655892cb9a3751a815d 100644 (file)
@@ -85,3 +85,4 @@ sendmail.o: ../../include/tok822.h
 sendmail.o: ../../include/resolve_clnt.h
 sendmail.o: ../../include/mail_flush.h
 sendmail.o: ../../include/mail_stream.h
+sendmail.o: ../../include/sys_exits.h
index 4863cd99c8525de907a8bbe53f38ed8c472ea704..412d57972f00e1599a7d6a22fe8c39e7bcece2d2 100644 (file)
 /* .IP "\fB-q\fIinterval\fR (ignored)"
 /*     The interval between queue runs. Use the \fBqueue_run_delay\fR
 /*     configuration parameter instead.
+/* .IP \fB-qR\fIsite\fR
+/*     Schedule immediate delivery of all mail that is queued for the named
+/*     \fIsite\fR.
+/*     This functionality is available only for sites that are configured
+/*     for the \fBfast flush\fR service support as described in
+/*     \fBflushd\fR(8).  For other sites, this command is equivalent to
+/*     using the slower \fBsendmail -q\fR instead.
+/* .IP \fB-qS\fIsite\fR
+/*     The site name is ignored. This command is equivalent to using
+/*     the slower \fBsendmail -q\fR instead.
 /* .IP \fB-t\fR
 /*     Extract recipients from message headers. This requires that no
 /*     recipients be specified on the command line.
 /*     qmgr(8) queue manager
 /*     showq(8) list mail queue
 /*     smtpd(8) SMTP server
+/*     flushd(8) fast flush service
 /*     syslogd(8) system logging
 /* LICENSE
 /* .ad
 #include <tok822.h>
 #include <mail_flush.h>
 #include <mail_stream.h>
+#include <sys_exits.h>
 
 /* Application-specific. */
 
@@ -547,6 +559,30 @@ static void flush_queue(void)
        msg_warn("Cannot flush mail queue - mail system is down");
 }
 
+/* flush_site - flush mail for site */
+
+static void flush_site(const char *site)
+{
+    int     code;
+
+    switch (code = mail_flush_site(site)) {
+    default:
+       msg_panic("flush_site: unknown result code %d", code);
+    case FLUSH_STAT_OK:
+       break;
+    case FLUSH_STAT_UNKNOWN:
+       msg_warn("No \"sendmail -qR\" support for site %s", site);
+       msg_warn("Using the slower \"sendmail -q\" instead");
+       flush_queue();
+       break;
+    case FLUSH_STAT_BAD:
+       msg_fatal("invalid request: %s", site);
+    case FLUSH_STAT_FAIL:
+       msg_warn("Cannot flush mail queue - mail system is down");
+       break;
+    }
+}
+
 /* sendmail_cleanup - callback for the runtime error handler */
 
 static void sendmail_cleanup(void)
@@ -591,6 +627,7 @@ int     main(int argc, char **argv)
     int     err;
     int     n;
     int     flags = SM_FLAG_DEFAULT;
+    char   *site_to_flush = 0;
 
     /*
      * Be consistent with file permissions.
@@ -777,11 +814,20 @@ int     main(int argc, char **argv)
            sender = optarg;
            break;
        case 'q':
-           if (optarg[0] && !ISDIGIT(optarg[0]))
+           if (ISDIGIT(optarg[0])) {
+               if (mode == SM_MODE_DAEMON) {
+                   if (msg_verbose)
+                       msg_info("-%c%s option ignored", c, optarg);
+
+               }
+           } else if (optarg[0] == 'R') {
+               site_to_flush = optarg + 1;
+           } else if (optarg[0] == 'S') {
+               msg_warn(
+                 "-qS is not implemented - using \"sendmail -q\" instead");
+               mode = SM_MODE_FLUSHQ;
+           } else {
                msg_fatal("-q%c is not implemented", optarg[0]);
-           if (mode == SM_MODE_DAEMON) {
-               if (msg_verbose)
-                   msg_info("-%c%s option ignored", c, optarg);
            }
            break;
        case 't':
@@ -801,6 +847,9 @@ int     main(int argc, char **argv)
     if (extract_recipients && mode != SM_MODE_ENQUEUE)
        msg_fatal("-t can be used only in delivery mode");
 
+    if (site_to_flush && mode != SM_MODE_ENQUEUE)
+       msg_fatal("-t can be used only in delivery mode");
+
     if (extract_recipients && argv[OPTIND])
        msg_fatal("cannot handle command-line recipients with -t");
 
@@ -814,7 +863,10 @@ int     main(int argc, char **argv)
        msg_panic("unknown operation mode: %d", mode);
        /* NOTREACHED */
     case SM_MODE_ENQUEUE:
-       enqueue(flags, sender, full_name, argv + OPTIND);
+       if (site_to_flush)
+           flush_site(site_to_flush);
+       else
+           enqueue(flags, sender, full_name, argv + OPTIND);
        exit(0);
        break;
     case SM_MODE_MAILQ:
index 765719bf5493253558b079136cb9f08f18e1035f..b57481f606790fc578e0a9f793d1b94beae7bc6a 100644 (file)
@@ -343,6 +343,7 @@ bool    var_smtpd_sasl_enable;
 char   *var_smtpd_sasl_opts;
 char   *var_smtpd_sasl_realm;
 char   *var_filter_xport;
+char   *var_fflush_maps;
 
  /*
   * Global state, for stand-alone mode queue file cleanup. When this is
@@ -527,7 +528,21 @@ static char *extract_addr(SMTPD_STATE *state, SMTPD_TOKEN *arg,
      */
     if (msg_verbose)
        msg_info("%s: input: %s", myname, STR(arg->vstrval));
-    tree = tok822_parse(STR(arg->vstrval));
+
+    /*
+     * Workaround: Sendmail allows arbitrary nesting of <>, so that overpaid
+     * peecee programmers can get away with monstrosities such as <the dude
+     * <dude@site>>. By peeling off the outermost <> we can deal with the
+     * most common problem instance. Don't destroy the input so that we can
+     * provide accurate diagnostics.
+     */
+    if (arg->strval[0] == '<' && vstring_end(arg->vstrval)[-1] == '>') {
+       vstring_end(arg->vstrval)[-1] = 0;
+       tree = tok822_parse(STR(arg->vstrval) + 1);
+       vstring_end(arg->vstrval)[-1] = '>';
+    } else {
+       tree = tok822_parse(STR(arg->vstrval));
+    }
 
     /*
      * Find trouble.
@@ -1092,7 +1107,7 @@ static int etrn_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *argv)
     /*
      * XXX The preliminary implementation causes a full deferred queue scan.
      */
-    if (mail_flush_site(argv[1].strval) < 0)
+    if (mail_flush_site(argv[1].strval) != 0)
        smtpd_chat_reply(state, "458 Unable to queue messages");
     else
        smtpd_chat_reply(state, "250 Queuing started");
@@ -1446,6 +1461,7 @@ int     main(int argc, char **argv)
        VAR_SMTPD_SASL_OPTS, DEF_SMTPD_SASL_OPTS, &var_smtpd_sasl_opts, 0, 0,
        VAR_SMTPD_SASL_REALM, DEF_SMTPD_SASL_REALM, &var_smtpd_sasl_realm, 1, 0,
        VAR_FILTER_XPORT, DEF_FILTER_XPORT, &var_filter_xport, 0, 0,
+       VAR_FFLUSH_MAPS, DEF_FFLUSH_MAPS, &var_fflush_maps, 0, 0,
        0,
     };
 
index 37402f1922a20bd8c6ade9889913aadb7c6025ca..28acfb048d31f17b0e1a084390667c0679779211 100644 (file)
 /*     smtpd_check_etrn() validates the domain name provided with the
 /*     ETRN command, and other client-provided information. Relevant
 /*     configuration parameters:
-/* .IP smtpd_etrn_restrictions
-/*     Restrictions on the hostname that is sent with the HELO/EHLO
-/*     command.
 /* .PP
 /*     smtpd_check_size() checks if a message with the given size can
 /*     be received (zero means that the message size is unknown).  The
@@ -313,6 +310,7 @@ static MAPS *rcpt_canon_maps;
 static MAPS *canonical_maps;
 static MAPS *virtual_maps;
 static MAPS *relocated_maps;
+static MAPS *fflush_maps;
 
  /*
   * Pre-opened access control lists.
@@ -327,7 +325,6 @@ static ARGV *client_restrctions;
 static ARGV *helo_restrctions;
 static ARGV *mail_restrctions;
 static ARGV *rcpt_restrctions;
-static ARGV *etrn_restrctions;
 
 static HTABLE *smtpd_rest_classes;
 
@@ -458,6 +455,8 @@ void    smtpd_check_init(void)
                               DICT_FLAG_LOCK);
     relocated_maps = maps_create(VAR_RELOCATED_MAPS, var_relocated_maps,
                                 DICT_FLAG_LOCK);
+    fflush_maps = maps_create(VAR_FFLUSH_MAPS, var_fflush_maps,
+                             DICT_FLAG_LOCK);
 
     /*
      * Reply is used as a cache for resolved addresses, and error_text is
@@ -475,7 +474,6 @@ void    smtpd_check_init(void)
     helo_restrctions = smtpd_check_parse(var_helo_checks);
     mail_restrctions = smtpd_check_parse(var_mail_checks);
     rcpt_restrctions = smtpd_check_parse(var_rcpt_checks);
-    etrn_restrctions = smtpd_check_parse(var_etrn_checks);
 
     /*
      * Parse the pre-defined restriction classes.
@@ -1879,6 +1877,8 @@ char   *smtpd_check_etrn(SMTPD_STATE *state, char *domain)
     int     status;
     char   *saved_etrn_name;
     char   *err;
+    const char *pattern;
+    ARGV   *restrictions;
 
     /*
      * Initialize.
@@ -1906,14 +1906,29 @@ char   *smtpd_check_etrn(SMTPD_STATE *state, char *domain)
            SMTPD_CHECK_ETRN_RETURN(err);
 
     /*
-     * Apply restrictions in the order as specified.
+     * Apply restrictions in the order as specified. If the domain is not
+     * configured for ETRN, reject the request.
      */
-    state->recursion = 0;
-    status = setjmp(smtpd_check_buf);
-    if (status == 0 && etrn_restrctions->argc)
-       status = generic_checks(state, etrn_restrctions, domain,
-                               SMTPD_NAME_ETRN, CHECK_ETRN_ACL);
-
+    if (*var_fflush_maps == 0
+       || (pattern = maps_find(fflush_maps, domain, 0)) == 0) {
+       status = smtpd_check_reject(state, MAIL_ERROR_POLICY,
+                                   "458 Unable to start queueing for %s",
+                                   domain);
+    } else if (strchr(pattern, ':') != 0) {
+       msg_warn("A fast flush map has an entry with lookup table: %s",
+                pattern);
+       msg_warn("do not specify lookup tables inside fast flush maps");
+       msg_warn("define a restriction class and specify its name instead");
+       status = SMTPD_CHECK_OK;
+    } else {
+       restrictions = argv_split(pattern, " \t\r\n");
+       state->recursion = 0;
+       status = setjmp(smtpd_check_buf);
+       if (status == 0)
+           status = generic_checks(state, restrictions, domain,
+                                   SMTPD_NAME_ETRN, CHECK_ETRN_ACL);
+       argv_free(restrictions);
+    }
     SMTPD_CHECK_ETRN_RETURN(status == SMTPD_CHECK_REJECT ? STR(error_text) : 0);
 }
 
@@ -2208,7 +2223,6 @@ static REST_TABLE rest_table[] = {
     "helo_restrictions", &helo_restrctions,
     "sender_restrictions", &mail_restrctions,
     "recipient_restrictions", &rcpt_restrctions,
-    "etrn_restrictions", &etrn_restrctions,
     0,
 };
 
index 078d255e1ac28ebf137cee2263e4a440b109d807..303fc49c6b6819afa6e1fb36010ca3098cdc7857 100644 (file)
 /*     VSTRING *vp;
 /*     VSTREAM *fp;
 /*     int     bound;
+/*
+/*     int     vstring_get_null_bound(vp, fp, bound)
+/*     VSTRING *vp;
+/*     VSTREAM *fp;
 /* DESCRIPTION
 /*     The routines in this module each read one newline or null-terminated
 /*     string from an input stream. In all cases the result is either the
 /*     vstring_get_null() reads a null-terminated string from the named
 /*     stream.
 /*
-/*     vstring_get_bound() and vstring_get_nonl_bound() read no more
-/*     than \fIbound\fR characters.  Otherwise they behave like the
-/*     unbounded versions documented above.
+/*     vstring_get_bound(), vstring_get_nonl_bound() and
+/*     vstring_get_null_bound() read no more than \fIbound\fR characters.
+/*     Otherwise they behave like the unbounded versions documented above.
 /* DIAGNOSTICS
 /*     Fatal errors: memory allocation failure.
 /*     Panic: improper string bound.
+/* BUGS
+/*     This code should honor the bound information that is already
+/*     part of a VSTRING.
 /* LICENSE
 /* .ad
 /* .fi
@@ -154,6 +161,22 @@ int     vstring_get_nonl_bound(VSTRING *vp, VSTREAM *fp, int bound)
     return (c == '\n' ? c : VSTRING_GET_RESULT(vp));
 }
 
+/* vstring_get_null_bound - read null-terminated string, up to bound */
+
+int     vstring_get_null_bound(VSTRING *vp, VSTREAM *fp, int bound)
+{
+    int     c;
+
+    if (bound <= 0)
+        msg_panic("vstring_get_null_bound: invalid bound %d", bound);
+
+    VSTRING_RESET(vp);
+    while (bound-- > 0 && (c = VSTREAM_GETC(fp)) != VSTREAM_EOF && c != 0)
+       VSTRING_ADDCH(vp, c);
+    VSTRING_TERMINATE(vp);
+    return (c == 0 ? c : VSTRING_GET_RESULT(vp));
+}
+
 #ifdef TEST
 
  /*
index 897167ca6402317eb226f0f2cfb2d905ed70b506..fa4d00f840a85b434769110b172dccc6bc219f4c 100644 (file)
@@ -24,6 +24,7 @@ extern int vstring_get_nonl(VSTRING *, VSTREAM *);
 extern int vstring_get_null(VSTRING *, VSTREAM *);
 extern int vstring_get_bound(VSTRING *, VSTREAM *, int);
 extern int vstring_get_nonl_bound(VSTRING *, VSTREAM *, int);
+extern int vstring_get_null_bound(VSTRING *, VSTREAM *, int);
 
  /*
   * Backwards compatibility for code that still uses the vstring_fgets()
@@ -39,6 +40,8 @@ extern int vstring_get_nonl_bound(VSTRING *, VSTREAM *, int);
        (vstring_get_bound((s), (p), (l)) == VSTREAM_EOF ? 0 : (s))
 #define vstring_fgets_nonl_bound(s, p, l) \
        (vstring_get_nonl_bound((s), (p), (l)) == VSTREAM_EOF ? 0 : (s))
+#define vstring_fgets_null_bound(s, p, l) \
+       (vstring_get_null_bound((s), (p), (l)) == VSTREAM_EOF ? 0 : (s))
 
 /* LICENSE
 /* .ad