]> git.ipfire.org Git - thirdparty/postfix.git/commitdiff
snapshot-19990505
authorWietse Venema <wietse@porcupine.org>
Wed, 5 May 1999 05:00:00 +0000 (00:00 -0500)
committerWietse Venema <wietse@porcupine.org>
Thu, 17 Jan 2013 03:34:20 +0000 (22:34 -0500)
42 files changed:
postfix/.indent.pro
postfix/DEBUG_README [new file with mode: 0644]
postfix/HISTORY
postfix/bounce/.indent.pro
postfix/cleanup/.indent.pro
postfix/conf/main.cf.default
postfix/dns/.indent.pro
postfix/error/.indent.pro
postfix/fsstone/.indent.pro
postfix/global/.indent.pro
postfix/global/mail_version.h
postfix/global/smtp_stream.c
postfix/libexec/.keep [new file with mode: 0644]
postfix/local/.indent.pro
postfix/master/.indent.pro
postfix/pickup/.indent.pro
postfix/pipe/.indent.pro
postfix/postalias/.indent.pro
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/postlog/.indent.pro
postfix/postmap/.indent.pro
postfix/postsuper/.indent.pro
postfix/qmgr/.indent.pro
postfix/sendmail/.indent.pro
postfix/showq/.indent.pro
postfix/smtp/.indent.pro
postfix/smtpd/.indent.pro
postfix/smtpd/smtpd_check.c
postfix/smtpd/smtpd_check.in2
postfix/smtpd/smtpd_check.ref
postfix/smtpd/smtpd_check.ref2
postfix/smtpd/smtpd_check_access
postfix/smtpstone/.indent.pro
postfix/trivial-rewrite/.indent.pro
postfix/util/.indent.pro
postfix/util/mac_expand.c
postfix/util/mac_expand.h

index fc9774ba8cf9e487205fe62983fb97c85c464288..ce21b568dc78716588719c44c5618d1dccb0827c 100644 (file)
@@ -43,7 +43,7 @@
 -TINET_ADDR_LIST
 -TINT_TABLE
 -TLOCAL_STATE
--TMAC_EXP_CONTEXT
+-TMAC_EXP
 -TMAC_HEAD
 -TMAC_PARSE
 -TMAIL_PRINT
diff --git a/postfix/DEBUG_README b/postfix/DEBUG_README
new file mode 100644 (file)
index 0000000..1ed6e6b
--- /dev/null
@@ -0,0 +1,63 @@
+1 - Purpose of this document
+============================
+
+This document describes how to debug parts of the Postfix mail
+system, either by making the software log a lot of detail to the
+syslog daemon, or by running some daemon processes under control
+of an interactive debugger.
+
+2 - Verbose logging for specific SMTP connections
+=================================================
+
+In /etc/postfix/main.cf, list the remote site name or address in
+the "debug_peer_list" parameter. For example, in order to make the
+software log a lot of information to the syslog daemon for connections
+from or to the loopback interface:
+
+    debug_peer_list = 127.0.0.1
+
+3 - Making daemon programs more verbose
+=======================================
+
+Append one or more -v options to commands in /etc/postfix/master.cf
+and type "postfix reload". This will cause a lot of activity to be
+logged to the syslog daemon.
+
+4 - Tracing a Postfix daemon process
+====================================
+
+Some systems allow you to inspect a running process with a system
+call tracer. For example:
+
+       # trace -p process-id
+       # strace -p process-id
+       # truss -p process-id
+       # ktrace -p process-id
+
+This can give valuable information about what a process is attempting
+to do. This is as much information as you can get without running
+a debugger program, as described in the next section.
+
+5 - Running daemon programs under an interactive debugger
+=========================================================
+
+Append a -D option to the suspect command in /etc/postfix/master.cf,
+for example:
+
+    smtp      inet  n       -       n       -       -       smtpd -D
+
+Edit the debugger_command definition in /etc/postfix/main.cf so
+that it invokes the debugger of your choice, for example:
+
+    debugger_command =
+         PATH=/usr/bin:/usr/X11R6/bin
+         xxgdb $daemon_directory/$process_name $process_id & sleep 5
+
+Export XAUTHORITY so that X access control works, for example:
+
+    % setenv XAUTHORITY ~/.Xauthority
+
+Stop and start the Postfix system. 
+
+Whenever the suspect daemon process is started, a debugger window
+pops up and you can watch in detail what happens.
index ad97268145b13ed57baaf4d17fbc88cf2ba0ab0d..8c534d4ab341ed20f6a709cf1bdc3c4c906011f6 100644 (file)
@@ -2710,3 +2710,9 @@ Apologies for any names omitted.
        mailbox_command of $user, $home, $shell, $recipient,
        $extension, $domain, and $recipient_delimiter. Files:
        local/command.c, local/dotforward.c, local/local_expand.c.
+
+19990506
+
+       Cleanup: eliminated misleading warnings about unknown HELO
+       etc. SMTPD restrictions when the HELO etc. information is
+       not available. File: smtpd/smtpd_check.c.
index fc9774ba8cf9e487205fe62983fb97c85c464288..ce21b568dc78716588719c44c5618d1dccb0827c 100644 (file)
@@ -43,7 +43,7 @@
 -TINET_ADDR_LIST
 -TINT_TABLE
 -TLOCAL_STATE
--TMAC_EXP_CONTEXT
+-TMAC_EXP
 -TMAC_HEAD
 -TMAC_PARSE
 -TMAIL_PRINT
index fc9774ba8cf9e487205fe62983fb97c85c464288..ce21b568dc78716588719c44c5618d1dccb0827c 100644 (file)
@@ -43,7 +43,7 @@
 -TINET_ADDR_LIST
 -TINT_TABLE
 -TLOCAL_STATE
--TMAC_EXP_CONTEXT
+-TMAC_EXP
 -TMAC_HEAD
 -TMAC_PARSE
 -TMAIL_PRINT
index 5aa96596ba6aa7abe2c1e1e88e15e85cef4b2825..83ded82759f68f6889da5d49ee2c3f7a36646d8c 100644 (file)
@@ -61,7 +61,7 @@ luser_relay =
 mail_name = Postfix
 mail_owner = postfix
 mail_spool_directory = /var/mail
-mail_version = Snapshot-19990504
+mail_version = Snapshot-19990505
 mailbox_command = 
 mailbox_transport = 
 maps_rbl_domains = rbl.maps.vix.com
index fc9774ba8cf9e487205fe62983fb97c85c464288..ce21b568dc78716588719c44c5618d1dccb0827c 100644 (file)
@@ -43,7 +43,7 @@
 -TINET_ADDR_LIST
 -TINT_TABLE
 -TLOCAL_STATE
--TMAC_EXP_CONTEXT
+-TMAC_EXP
 -TMAC_HEAD
 -TMAC_PARSE
 -TMAIL_PRINT
index fc9774ba8cf9e487205fe62983fb97c85c464288..ce21b568dc78716588719c44c5618d1dccb0827c 100644 (file)
@@ -43,7 +43,7 @@
 -TINET_ADDR_LIST
 -TINT_TABLE
 -TLOCAL_STATE
--TMAC_EXP_CONTEXT
+-TMAC_EXP
 -TMAC_HEAD
 -TMAC_PARSE
 -TMAIL_PRINT
index fc9774ba8cf9e487205fe62983fb97c85c464288..ce21b568dc78716588719c44c5618d1dccb0827c 100644 (file)
@@ -43,7 +43,7 @@
 -TINET_ADDR_LIST
 -TINT_TABLE
 -TLOCAL_STATE
--TMAC_EXP_CONTEXT
+-TMAC_EXP
 -TMAC_HEAD
 -TMAC_PARSE
 -TMAIL_PRINT
index fc9774ba8cf9e487205fe62983fb97c85c464288..ce21b568dc78716588719c44c5618d1dccb0827c 100644 (file)
@@ -43,7 +43,7 @@
 -TINET_ADDR_LIST
 -TINT_TABLE
 -TLOCAL_STATE
--TMAC_EXP_CONTEXT
+-TMAC_EXP
 -TMAC_HEAD
 -TMAC_PARSE
 -TMAIL_PRINT
index d11555493c5405d3794207576508bc01689cdb60..97dc67f3aebfd6c1a6c0da6db5eba788ac605329 100644 (file)
@@ -15,7 +15,7 @@
   * Version of this program.
   */
 #define VAR_MAIL_VERSION       "mail_version"
-#define DEF_MAIL_VERSION       "Snapshot-19990504"
+#define DEF_MAIL_VERSION       "Snapshot-19990505"
 extern char *var_mail_version;
 
 /* LICENSE
index bb499a640b0e9ddc14146523d61889abe82c2c74..ce7cefe37569143207c988ed5bb4ca102970650f 100644 (file)
@@ -57,7 +57,7 @@
 /*     A timeout error is reported to the vstream module as an I/O error.
 /* .PP
 /*     smtp_printf() formats its arguments and writes the result to
-/*     the named stream, followed by a CR LF stream. The stream is flushed.
+/*     the named stream, followed by a CR LF pair. The stream is flushed.
 /*     Long lines of text are not broken.
 /*
 /*     smtp_get() reads the named stream up to and including
@@ -207,8 +207,8 @@ void    smtp_timeout_setup(VSTREAM *stream, int maxtime)
      * XXX The timeout etc. state is static, so a process can have at most
      * one SMTP session at a time. We could use the VSTREAM file descriptor
      * number as key into a BINHASH table with per-stream contexts. This
-     * would allow us to keep talk to multiple SMTP streams at the same time.
-     * Another possibilty is to use the file descriptor as an index into a
+     * would allow us to talk to multiple SMTP streams at the same time.
+     * Another possibility is to use the file descriptor as an index into a
      * linear table of structure pointers. In either case we would need to
      * provide an smtp_timeout_cleanup() routine to dispose of memory that is
      * no longer needed.
diff --git a/postfix/libexec/.keep b/postfix/libexec/.keep
new file mode 100644 (file)
index 0000000..e69de29
index fc9774ba8cf9e487205fe62983fb97c85c464288..ce21b568dc78716588719c44c5618d1dccb0827c 100644 (file)
@@ -43,7 +43,7 @@
 -TINET_ADDR_LIST
 -TINT_TABLE
 -TLOCAL_STATE
--TMAC_EXP_CONTEXT
+-TMAC_EXP
 -TMAC_HEAD
 -TMAC_PARSE
 -TMAIL_PRINT
index fc9774ba8cf9e487205fe62983fb97c85c464288..ce21b568dc78716588719c44c5618d1dccb0827c 100644 (file)
@@ -43,7 +43,7 @@
 -TINET_ADDR_LIST
 -TINT_TABLE
 -TLOCAL_STATE
--TMAC_EXP_CONTEXT
+-TMAC_EXP
 -TMAC_HEAD
 -TMAC_PARSE
 -TMAIL_PRINT
index fc9774ba8cf9e487205fe62983fb97c85c464288..ce21b568dc78716588719c44c5618d1dccb0827c 100644 (file)
@@ -43,7 +43,7 @@
 -TINET_ADDR_LIST
 -TINT_TABLE
 -TLOCAL_STATE
--TMAC_EXP_CONTEXT
+-TMAC_EXP
 -TMAC_HEAD
 -TMAC_PARSE
 -TMAIL_PRINT
index fc9774ba8cf9e487205fe62983fb97c85c464288..ce21b568dc78716588719c44c5618d1dccb0827c 100644 (file)
@@ -43,7 +43,7 @@
 -TINET_ADDR_LIST
 -TINT_TABLE
 -TLOCAL_STATE
--TMAC_EXP_CONTEXT
+-TMAC_EXP
 -TMAC_HEAD
 -TMAC_PARSE
 -TMAIL_PRINT
index fc9774ba8cf9e487205fe62983fb97c85c464288..ce21b568dc78716588719c44c5618d1dccb0827c 100644 (file)
@@ -43,7 +43,7 @@
 -TINET_ADDR_LIST
 -TINT_TABLE
 -TLOCAL_STATE
--TMAC_EXP_CONTEXT
+-TMAC_EXP
 -TMAC_HEAD
 -TMAC_PARSE
 -TMAIL_PRINT
index fc9774ba8cf9e487205fe62983fb97c85c464288..ce21b568dc78716588719c44c5618d1dccb0827c 100644 (file)
@@ -43,7 +43,7 @@
 -TINET_ADDR_LIST
 -TINT_TABLE
 -TLOCAL_STATE
--TMAC_EXP_CONTEXT
+-TMAC_EXP
 -TMAC_HEAD
 -TMAC_PARSE
 -TMAIL_PRINT
index fc9774ba8cf9e487205fe62983fb97c85c464288..ce21b568dc78716588719c44c5618d1dccb0827c 100644 (file)
@@ -43,7 +43,7 @@
 -TINET_ADDR_LIST
 -TINT_TABLE
 -TLOCAL_STATE
--TMAC_EXP_CONTEXT
+-TMAC_EXP
 -TMAC_HEAD
 -TMAC_PARSE
 -TMAIL_PRINT
index fc9774ba8cf9e487205fe62983fb97c85c464288..ce21b568dc78716588719c44c5618d1dccb0827c 100644 (file)
@@ -43,7 +43,7 @@
 -TINET_ADDR_LIST
 -TINT_TABLE
 -TLOCAL_STATE
--TMAC_EXP_CONTEXT
+-TMAC_EXP
 -TMAC_HEAD
 -TMAC_PARSE
 -TMAIL_PRINT
index fc9774ba8cf9e487205fe62983fb97c85c464288..ce21b568dc78716588719c44c5618d1dccb0827c 100644 (file)
@@ -43,7 +43,7 @@
 -TINET_ADDR_LIST
 -TINT_TABLE
 -TLOCAL_STATE
--TMAC_EXP_CONTEXT
+-TMAC_EXP
 -TMAC_HEAD
 -TMAC_PARSE
 -TMAIL_PRINT
index fc9774ba8cf9e487205fe62983fb97c85c464288..ce21b568dc78716588719c44c5618d1dccb0827c 100644 (file)
@@ -43,7 +43,7 @@
 -TINET_ADDR_LIST
 -TINT_TABLE
 -TLOCAL_STATE
--TMAC_EXP_CONTEXT
+-TMAC_EXP
 -TMAC_HEAD
 -TMAC_PARSE
 -TMAIL_PRINT
index fc9774ba8cf9e487205fe62983fb97c85c464288..ce21b568dc78716588719c44c5618d1dccb0827c 100644 (file)
@@ -43,7 +43,7 @@
 -TINET_ADDR_LIST
 -TINT_TABLE
 -TLOCAL_STATE
--TMAC_EXP_CONTEXT
+-TMAC_EXP
 -TMAC_HEAD
 -TMAC_PARSE
 -TMAIL_PRINT
index fc9774ba8cf9e487205fe62983fb97c85c464288..ce21b568dc78716588719c44c5618d1dccb0827c 100644 (file)
@@ -43,7 +43,7 @@
 -TINET_ADDR_LIST
 -TINT_TABLE
 -TLOCAL_STATE
--TMAC_EXP_CONTEXT
+-TMAC_EXP
 -TMAC_HEAD
 -TMAC_PARSE
 -TMAIL_PRINT
index fc9774ba8cf9e487205fe62983fb97c85c464288..ce21b568dc78716588719c44c5618d1dccb0827c 100644 (file)
@@ -43,7 +43,7 @@
 -TINET_ADDR_LIST
 -TINT_TABLE
 -TLOCAL_STATE
--TMAC_EXP_CONTEXT
+-TMAC_EXP
 -TMAC_HEAD
 -TMAC_PARSE
 -TMAIL_PRINT
index fc9774ba8cf9e487205fe62983fb97c85c464288..ce21b568dc78716588719c44c5618d1dccb0827c 100644 (file)
@@ -43,7 +43,7 @@
 -TINET_ADDR_LIST
 -TINT_TABLE
 -TLOCAL_STATE
--TMAC_EXP_CONTEXT
+-TMAC_EXP
 -TMAC_HEAD
 -TMAC_PARSE
 -TMAIL_PRINT
index fc9774ba8cf9e487205fe62983fb97c85c464288..ce21b568dc78716588719c44c5618d1dccb0827c 100644 (file)
@@ -43,7 +43,7 @@
 -TINET_ADDR_LIST
 -TINT_TABLE
 -TLOCAL_STATE
--TMAC_EXP_CONTEXT
+-TMAC_EXP
 -TMAC_HEAD
 -TMAC_PARSE
 -TMAIL_PRINT
index fc9774ba8cf9e487205fe62983fb97c85c464288..ce21b568dc78716588719c44c5618d1dccb0827c 100644 (file)
@@ -43,7 +43,7 @@
 -TINET_ADDR_LIST
 -TINT_TABLE
 -TLOCAL_STATE
--TMAC_EXP_CONTEXT
+-TMAC_EXP
 -TMAC_HEAD
 -TMAC_PARSE
 -TMAIL_PRINT
index fc9774ba8cf9e487205fe62983fb97c85c464288..ce21b568dc78716588719c44c5618d1dccb0827c 100644 (file)
@@ -43,7 +43,7 @@
 -TINET_ADDR_LIST
 -TINT_TABLE
 -TLOCAL_STATE
--TMAC_EXP_CONTEXT
+-TMAC_EXP
 -TMAC_HEAD
 -TMAC_PARSE
 -TMAIL_PRINT
index fc9774ba8cf9e487205fe62983fb97c85c464288..ce21b568dc78716588719c44c5618d1dccb0827c 100644 (file)
@@ -43,7 +43,7 @@
 -TINET_ADDR_LIST
 -TINT_TABLE
 -TLOCAL_STATE
--TMAC_EXP_CONTEXT
+-TMAC_EXP
 -TMAC_HEAD
 -TMAC_PARSE
 -TMAIL_PRINT
index fc9774ba8cf9e487205fe62983fb97c85c464288..ce21b568dc78716588719c44c5618d1dccb0827c 100644 (file)
@@ -43,7 +43,7 @@
 -TINET_ADDR_LIST
 -TINT_TABLE
 -TLOCAL_STATE
--TMAC_EXP_CONTEXT
+-TMAC_EXP
 -TMAC_HEAD
 -TMAC_PARSE
 -TMAIL_PRINT
index 11cbf7b8ffaaa37952e0c02d46bb77515226eb86..426663d9630933f53b4ee49f0b2f7167ab1c47ae 100644 (file)
@@ -1179,61 +1179,69 @@ static int generic_checks(SMTPD_STATE *state, char *name,
     /*
      * HELO/EHLO parameter restrictions.
      */
-    if (state->helo_name) {
-       if (is_map_command(name, CHECK_HELO_ACL, cpp) && state->helo_name) {
+    if (is_map_command(name, CHECK_HELO_ACL, cpp) && state->helo_name) {
+       if (state->helo_name)
            *status = check_domain_access(state, **cpp, state->helo_name, FULL);
-           return (1);
-       }
-       if (strcasecmp(name, REJECT_INVALID_HOSTNAME) == 0) {
+       return (1);
+    }
+    if (strcasecmp(name, REJECT_INVALID_HOSTNAME) == 0) {
+       if (state->helo_name) {
            if (*state->helo_name != '[')
                *status = reject_invalid_hostname(state, state->helo_name);
            else
                *status = reject_invalid_hostaddr(state, state->helo_name);
-           return (1);
        }
-       if (strcasecmp(name, REJECT_UNKNOWN_HOSTNAME) == 0) {
+       return (1);
+    }
+    if (strcasecmp(name, REJECT_UNKNOWN_HOSTNAME) == 0) {
+       if (state->helo_name) {
            if (*state->helo_name != '[')
                *status = reject_unknown_hostname(state, state->helo_name);
            else
                *status = reject_invalid_hostaddr(state, state->helo_name);
-           return (1);
        }
-       if (strcasecmp(name, PERMIT_NAKED_IP_ADDR) == 0) {
+       return (1);
+    }
+    if (strcasecmp(name, PERMIT_NAKED_IP_ADDR) == 0) {
+       if (state->helo_name) {
            if (state->helo_name[strspn(state->helo_name, "0123456789.")] == 0
                && (*status = reject_invalid_hostaddr(state, state->helo_name)) == 0)
                *status = SMTPD_CHECK_OK;
-           return (1);
        }
-       if (strcasecmp(name, REJECT_NON_FQDN_HOSTNAME) == 0) {
+       return (1);
+    }
+    if (strcasecmp(name, REJECT_NON_FQDN_HOSTNAME) == 0) {
+       if (state->helo_name) {
            if (*state->helo_name != '[')
                *status = reject_non_fqdn_hostname(state, state->helo_name);
            else
                *status = reject_invalid_hostaddr(state, state->helo_name);
-           return (1);
        }
+       return (1);
     }
 
     /*
      * Sender mail address restrictions.
      */
-    if (state->sender) {
-       if (is_map_command(name, CHECK_SENDER_ACL, cpp) && state->sender) {
+    if (is_map_command(name, CHECK_SENDER_ACL, cpp) && state->sender) {
+       if (state->sender)
            *status = check_mail_access(state, **cpp, state->sender);
-           return (1);
-       }
-       if (strcasecmp(name, REJECT_UNKNOWN_ADDRESS) == 0) {
+       return (1);
+    }
+    if (strcasecmp(name, REJECT_UNKNOWN_ADDRESS) == 0) {
+       if (state->sender)
            *status = reject_unknown_address(state, state->sender);
-           return (1);
-       }
-       if (strcasecmp(name, REJECT_UNKNOWN_SENDDOM) == 0) {
+       return (1);
+    }
+    if (strcasecmp(name, REJECT_UNKNOWN_SENDDOM) == 0) {
+       if (state->sender)
            *status = reject_unknown_address(state, state->sender);
-           return (1);
-       }
-       if (strcasecmp(name, REJECT_NON_FQDN_SENDER) == 0) {
-           if (*state->sender)
-               *status = reject_non_fqdn_address(state, state->sender);
-           return (1);
-       }
+       return (1);
+    }
+    if (strcasecmp(name, REJECT_NON_FQDN_SENDER) == 0) {
+       if (*state->sender)
+           *status = reject_non_fqdn_address(state, state->sender);
+       return (1);
     }
     return (0);
 }
index f779a6e916523acdcca27d9adc11f17933644a71..039a9cfea413bc562b0de8a54038c617db3f9423 100644 (file)
@@ -86,7 +86,7 @@ client foo 127.0.0.2
 #
 # unknown sender/recipient domain
 #
-unknown_address_reject_code 550
+unknown_address_reject_code 554
 recipient_restrictions reject_unknown_recipient_domain,reject_unknown_sender_domain
 mail wietse@porcupine.org
 rcpt wietse@porcupine.org
index 42144270b4593a4dcfdfa63eeede2bc0fb9840e8..8bf92053fd2ca7de507c822d15d909443c90df8e 100644 (file)
@@ -18,18 +18,18 @@ OK
 >>> client unknown 168.100.189.13
 OK
 >>> client random.bad.domain 123.123.123.123
-./smtpd_check: reject: CONNECT from random.bad.domain[123.123.123.123]: 550 match bad.domain
-550 match bad.domain
+./smtpd_check: reject: CONNECT from random.bad.domain[123.123.123.123]: 554 match bad.domain
+554 match bad.domain
 >>> client friend.bad.domain 123.123.123.123
 OK
 >>> client bad.domain 123.123.123.123
-./smtpd_check: reject: CONNECT from bad.domain[123.123.123.123]: 550 match bad.domain
-550 match bad.domain
+./smtpd_check: reject: CONNECT from bad.domain[123.123.123.123]: 554 match bad.domain
+554 match bad.domain
 >>> client wzv.win.tue.nl 131.155.210.17
 OK
 >>> client aa.win.tue.nl 131.155.210.18
-./smtpd_check: reject: CONNECT from aa.win.tue.nl[131.155.210.18]: 550 match 131.155.210
-550 match 131.155.210
+./smtpd_check: reject: CONNECT from aa.win.tue.nl[131.155.210.18]: 554 match 131.155.210
+554 match 131.155.210
 >>> client_restrictions permit_mynetworks
 OK
 >>> #
@@ -55,8 +55,8 @@ OK
 >>> helo_restrictions permit_mynetworks,reject_unknown_client,reject_invalid_hostname,hash:./smtpd_check_access
 OK
 >>> helo random.bad.domain
-./smtpd_check: reject: HELO from foo[123.123.123.123]: 550 match bad.domain
-550 match bad.domain
+./smtpd_check: reject: HELO from foo[123.123.123.123]: 554 match bad.domain
+554 match bad.domain
 >>> helo friend.bad.domain
 OK
 >>> helo_restrictions reject_invalid_hostname,reject_unknown_hostname
@@ -97,25 +97,25 @@ OK
 >>> sender_restrictions hash:./smtpd_check_access
 OK
 >>> mail bad-sender@any.domain
-./smtpd_check: reject: MAIL from foo[123.123.123.123]: 550 match bad-sender@
-550 match bad-sender@
+./smtpd_check: reject: MAIL from foo[123.123.123.123]: 554 match bad-sender@
+554 match bad-sender@
 >>> mail bad-sender@good.domain
 OK
 >>> mail reject@this.address
-./smtpd_check: reject: MAIL from foo[123.123.123.123]: 550 match reject@this.address
-550 match reject@this.address
+./smtpd_check: reject: MAIL from foo[123.123.123.123]: 554 match reject@this.address
+554 match reject@this.address
 >>> mail Reject@this.address
-./smtpd_check: reject: MAIL from foo[123.123.123.123]: 550 match reject@this.address
-550 match reject@this.address
+./smtpd_check: reject: MAIL from foo[123.123.123.123]: 554 match reject@this.address
+554 match reject@this.address
 >>> mail foo@bad.domain
-./smtpd_check: reject: MAIL from foo[123.123.123.123]: 550 match bad.domain
-550 match bad.domain
+./smtpd_check: reject: MAIL from foo[123.123.123.123]: 554 match bad.domain
+554 match bad.domain
 >>> mail foo@Bad.domain
-./smtpd_check: reject: MAIL from foo[123.123.123.123]: 550 match bad.domain
-550 match bad.domain
+./smtpd_check: reject: MAIL from foo[123.123.123.123]: 554 match bad.domain
+554 match bad.domain
 >>> mail foo@random.bad.domain
-./smtpd_check: reject: MAIL from foo[123.123.123.123]: 550 match bad.domain
-550 match bad.domain
+./smtpd_check: reject: MAIL from foo[123.123.123.123]: 554 match bad.domain
+554 match bad.domain
 >>> mail foo@friend.bad.domain
 OK
 >>> #
@@ -135,8 +135,8 @@ OK
 >>> client foo 123.123.123.123
 OK
 >>> rcpt foo@watson.ibm.com
-./smtpd_check: reject: RCPT from foo[123.123.123.123]: 550 <foo@watson.ibm.com>: Relay access denied
-550 <foo@watson.ibm.com>: Relay access denied
+./smtpd_check: reject: RCPT from foo[123.123.123.123]: 554 <foo@watson.ibm.com>: Relay access denied
+554 <foo@watson.ibm.com>: Relay access denied
 >>> rcpt foo@porcupine.org
 OK
 >>> recipient_restrictions check_relay_domains
@@ -150,26 +150,26 @@ OK
 >>> client foo 123.123.123.123
 OK
 >>> rcpt foo@watson.ibm.com
-./smtpd_check: reject: RCPT from foo[123.123.123.123]: 550 <foo@watson.ibm.com>: Relay access denied
-550 <foo@watson.ibm.com>: Relay access denied
+./smtpd_check: reject: RCPT from foo[123.123.123.123]: 554 <foo@watson.ibm.com>: Relay access denied
+554 <foo@watson.ibm.com>: Relay access denied
 >>> rcpt foo@porcupine.org
 OK
 >>> recipient_restrictions hash:./smtpd_check_access
 OK
 >>> mail bad-sender@any.domain
-./smtpd_check: reject: MAIL from foo[123.123.123.123]: 550 match bad-sender@
-550 match bad-sender@
+./smtpd_check: reject: MAIL from foo[123.123.123.123]: 554 match bad-sender@
+554 match bad-sender@
 >>> mail bad-sender@good.domain
 OK
 >>> mail reject@this.address
-./smtpd_check: reject: MAIL from foo[123.123.123.123]: 550 match reject@this.address
-550 match reject@this.address
+./smtpd_check: reject: MAIL from foo[123.123.123.123]: 554 match reject@this.address
+554 match reject@this.address
 >>> mail foo@bad.domain
-./smtpd_check: reject: MAIL from foo[123.123.123.123]: 550 match bad.domain
-550 match bad.domain
+./smtpd_check: reject: MAIL from foo[123.123.123.123]: 554 match bad.domain
+554 match bad.domain
 >>> mail foo@random.bad.domain
-./smtpd_check: reject: MAIL from foo[123.123.123.123]: 550 match bad.domain
-550 match bad.domain
+./smtpd_check: reject: MAIL from foo[123.123.123.123]: 554 match bad.domain
+554 match bad.domain
 >>> mail foo@friend.bad.domain
 OK
 >>> #
@@ -180,8 +180,8 @@ OK
 >>> client spike.porcupine.org 168.100.189.2
 OK
 >>> client foo 127.0.0.2
-./smtpd_check: reject: CONNECT from foo[127.0.0.2]: 550 Service unavailable; [127.0.0.2] blocked using rbl.maps.vix.com
-550 Service unavailable; [127.0.0.2] blocked using rbl.maps.vix.com
+./smtpd_check: reject: CONNECT from foo[127.0.0.2]: 554 Service unavailable; [127.0.0.2] blocked using rbl.maps.vix.com
+554 Service unavailable; [127.0.0.2] blocked using rbl.maps.vix.com
 >>> #
 >>> # Hybrids
 >>> #
@@ -190,8 +190,8 @@ OK
 >>> client foo 131.155.210.17
 OK
 >>> rcpt foo@watson.ibm.com
-./smtpd_check: reject: RCPT from foo[131.155.210.17]: 550 <foo@watson.ibm.com>: Relay access denied
-550 <foo@watson.ibm.com>: Relay access denied
+./smtpd_check: reject: RCPT from foo[131.155.210.17]: 554 <foo@watson.ibm.com>: Relay access denied
+554 <foo@watson.ibm.com>: Relay access denied
 >>> recipient_restrictions check_client_access,hash:./smtpd_check_access,check_relay_domains
 OK
 >>> client foo 131.155.210.17
@@ -203,11 +203,11 @@ OK
 >>> recipient_restrictions check_helo_access,hash:./smtpd_check_access,check_relay_domains
 OK
 >>> helo bad.domain
-./smtpd_check: reject: HELO from foo[131.155.210.17]: 550 match bad.domain
-550 match bad.domain
+./smtpd_check: reject: HELO from foo[131.155.210.17]: 554 match bad.domain
+554 match bad.domain
 >>> rcpt foo@porcupine.org
-./smtpd_check: reject: RCPT from foo[131.155.210.17]: 550 match bad.domain
-550 match bad.domain
+./smtpd_check: reject: RCPT from foo[131.155.210.17]: 554 match bad.domain
+554 match bad.domain
 >>> helo 131.155.210.17
 ./smtpd_check: warning: valid_hostname: numeric hostname: 131.155.210.17
 OK
@@ -216,11 +216,11 @@ OK
 >>> recipient_restrictions check_sender_access,hash:./smtpd_check_access,check_relay_domains
 OK
 >>> mail foo@bad.domain
-./smtpd_check: reject: MAIL from foo[131.155.210.17]: 550 match bad.domain
-550 match bad.domain
+./smtpd_check: reject: MAIL from foo[131.155.210.17]: 554 match bad.domain
+554 match bad.domain
 >>> rcpt foo@porcupine.org
-./smtpd_check: reject: RCPT from foo[131.155.210.17]: 550 match bad.domain
-550 match bad.domain
+./smtpd_check: reject: RCPT from foo[131.155.210.17]: 554 match bad.domain
+554 match bad.domain
 >>> mail foo@friend.bad.domain
 OK
 >>> rcpt foo@porcupine.org
@@ -237,8 +237,8 @@ OK
 >>> rcpt wietse@wzv.win.tue.nl
 OK
 >>> rcpt wietse@trouble.org
-./smtpd_check: reject: RCPT from foo[131.155.210.17]: 550 <wietse@trouble.org> Access denied
-550 <wietse@trouble.org> Access denied
+./smtpd_check: reject: RCPT from foo[131.155.210.17]: 554 <wietse@trouble.org> Access denied
+554 <wietse@trouble.org> Access denied
 >>> rcpt wietse@porcupine.org
 OK
 >>> #
@@ -257,15 +257,15 @@ OK
 >>> mail foo@good.domain
 OK
 >>> rcpt foo@porcupine.org
-./smtpd_check: reject: RCPT from foo[131.155.210.17]: 550 match bad.domain
-550 match bad.domain
+./smtpd_check: reject: RCPT from foo[131.155.210.17]: 554 match bad.domain
+554 match bad.domain
 >>> helo good.domain
 OK
 >>> mail foo@bad.domain
 OK
 >>> rcpt foo@porcupine.org
-./smtpd_check: reject: RCPT from foo[131.155.210.17]: 550 match bad.domain
-550 match bad.domain
+./smtpd_check: reject: RCPT from foo[131.155.210.17]: 554 match bad.domain
+554 match bad.domain
 >>> #
 >>> # FQDN restrictions
 >>> #
index 8009cdb2e5646199958e88fe2276c8ab6c006a5f..5d099bda4b9b98809ae1542aadff99b240172eee 100644 (file)
@@ -18,18 +18,18 @@ OK
 >>> client unknown 168.100.189.13
 OK
 >>> client random.bad.domain 123.123.123.123
-./smtpd_check: reject: CONNECT from random.bad.domain[123.123.123.123]: 550 match bad.domain
-550 match bad.domain
+./smtpd_check: reject: CONNECT from random.bad.domain[123.123.123.123]: 554 match bad.domain
+554 match bad.domain
 >>> client friend.bad.domain 123.123.123.123
 OK
 >>> client bad.domain 123.123.123.123
-./smtpd_check: reject: CONNECT from bad.domain[123.123.123.123]: 550 match bad.domain
-550 match bad.domain
+./smtpd_check: reject: CONNECT from bad.domain[123.123.123.123]: 554 match bad.domain
+554 match bad.domain
 >>> client wzv.win.tue.nl 131.155.210.17
 OK
 >>> client aa.win.tue.nl 131.155.210.18
-./smtpd_check: reject: CONNECT from aa.win.tue.nl[131.155.210.18]: 550 match 131.155.210
-550 match 131.155.210
+./smtpd_check: reject: CONNECT from aa.win.tue.nl[131.155.210.18]: 554 match 131.155.210
+554 match 131.155.210
 >>> client_restrictions permit_mynetworks
 OK
 >>> #
@@ -55,8 +55,8 @@ OK
 >>> helo_restrictions permit_mynetworks,reject_unknown_client,reject_invalid_hostname,check_helo_access,hash:./smtpd_check_access
 OK
 >>> helo random.bad.domain
-./smtpd_check: reject: HELO from foo[123.123.123.123]: 550 match bad.domain
-550 match bad.domain
+./smtpd_check: reject: HELO from foo[123.123.123.123]: 554 match bad.domain
+554 match bad.domain
 >>> helo friend.bad.domain
 OK
 >>> #
@@ -87,25 +87,25 @@ OK
 >>> sender_restrictions check_sender_access,hash:./smtpd_check_access
 OK
 >>> mail bad-sender@any.domain
-./smtpd_check: reject: MAIL from foo[123.123.123.123]: 550 match bad-sender@
-550 match bad-sender@
+./smtpd_check: reject: MAIL from foo[123.123.123.123]: 554 match bad-sender@
+554 match bad-sender@
 >>> mail bad-sender@good.domain
 OK
 >>> mail reject@this.address
-./smtpd_check: reject: MAIL from foo[123.123.123.123]: 550 match reject@this.address
-550 match reject@this.address
+./smtpd_check: reject: MAIL from foo[123.123.123.123]: 554 match reject@this.address
+554 match reject@this.address
 >>> mail Reject@this.address
-./smtpd_check: reject: MAIL from foo[123.123.123.123]: 550 match reject@this.address
-550 match reject@this.address
+./smtpd_check: reject: MAIL from foo[123.123.123.123]: 554 match reject@this.address
+554 match reject@this.address
 >>> mail foo@bad.domain
-./smtpd_check: reject: MAIL from foo[123.123.123.123]: 550 match bad.domain
-550 match bad.domain
+./smtpd_check: reject: MAIL from foo[123.123.123.123]: 554 match bad.domain
+554 match bad.domain
 >>> mail foo@Bad.domain
-./smtpd_check: reject: MAIL from foo[123.123.123.123]: 550 match bad.domain
-550 match bad.domain
+./smtpd_check: reject: MAIL from foo[123.123.123.123]: 554 match bad.domain
+554 match bad.domain
 >>> mail foo@random.bad.domain
-./smtpd_check: reject: MAIL from foo[123.123.123.123]: 550 match bad.domain
-550 match bad.domain
+./smtpd_check: reject: MAIL from foo[123.123.123.123]: 554 match bad.domain
+554 match bad.domain
 >>> mail foo@friend.bad.domain
 OK
 >>> #
@@ -125,8 +125,8 @@ OK
 >>> client foo 123.123.123.123
 OK
 >>> rcpt foo@watson.ibm.com
-./smtpd_check: reject: RCPT from foo[123.123.123.123]: 550 <foo@watson.ibm.com>: Relay access denied
-550 <foo@watson.ibm.com>: Relay access denied
+./smtpd_check: reject: RCPT from foo[123.123.123.123]: 554 <foo@watson.ibm.com>: Relay access denied
+554 <foo@watson.ibm.com>: Relay access denied
 >>> rcpt foo@porcupine.org
 OK
 >>> recipient_restrictions check_relay_domains
@@ -140,26 +140,26 @@ OK
 >>> client foo 123.123.123.123
 OK
 >>> rcpt foo@watson.ibm.com
-./smtpd_check: reject: RCPT from foo[123.123.123.123]: 550 <foo@watson.ibm.com>: Relay access denied
-550 <foo@watson.ibm.com>: Relay access denied
+./smtpd_check: reject: RCPT from foo[123.123.123.123]: 554 <foo@watson.ibm.com>: Relay access denied
+554 <foo@watson.ibm.com>: Relay access denied
 >>> rcpt foo@porcupine.org
 OK
 >>> recipient_restrictions check_recipient_access,hash:./smtpd_check_access
 OK
 >>> mail bad-sender@any.domain
-./smtpd_check: reject: MAIL from foo[123.123.123.123]: 550 match bad-sender@
-550 match bad-sender@
+./smtpd_check: reject: MAIL from foo[123.123.123.123]: 554 match bad-sender@
+554 match bad-sender@
 >>> mail bad-sender@good.domain
 OK
 >>> mail reject@this.address
-./smtpd_check: reject: MAIL from foo[123.123.123.123]: 550 match reject@this.address
-550 match reject@this.address
+./smtpd_check: reject: MAIL from foo[123.123.123.123]: 554 match reject@this.address
+554 match reject@this.address
 >>> mail foo@bad.domain
-./smtpd_check: reject: MAIL from foo[123.123.123.123]: 550 match bad.domain
-550 match bad.domain
+./smtpd_check: reject: MAIL from foo[123.123.123.123]: 554 match bad.domain
+554 match bad.domain
 >>> mail foo@random.bad.domain
-./smtpd_check: reject: MAIL from foo[123.123.123.123]: 550 match bad.domain
-550 match bad.domain
+./smtpd_check: reject: MAIL from foo[123.123.123.123]: 554 match bad.domain
+554 match bad.domain
 >>> mail foo@friend.bad.domain
 OK
 >>> #
@@ -170,12 +170,12 @@ OK
 >>> client spike.porcupine.org 168.100.189.2
 OK
 >>> client foo 127.0.0.2
-./smtpd_check: reject: CONNECT from foo[127.0.0.2]: 550 Service unavailable; [127.0.0.2] blocked using rbl.maps.vix.com
-550 Service unavailable; [127.0.0.2] blocked using rbl.maps.vix.com
+./smtpd_check: reject: CONNECT from foo[127.0.0.2]: 554 Service unavailable; [127.0.0.2] blocked using rbl.maps.vix.com
+554 Service unavailable; [127.0.0.2] blocked using rbl.maps.vix.com
 >>> #
 >>> # unknown sender/recipient domain
 >>> #
->>> unknown_address_reject_code 550
+>>> unknown_address_reject_code 554
 OK
 >>> recipient_restrictions reject_unknown_recipient_domain,reject_unknown_sender_domain
 OK
@@ -184,10 +184,10 @@ OK
 >>> rcpt wietse@porcupine.org
 OK
 >>> rcpt wietse@no.recipient.domain
-./smtpd_check: reject: RCPT from foo[127.0.0.2]: 550 <no.recipient.domain>: Domain not found
-550 <no.recipient.domain>: Domain not found
+./smtpd_check: reject: RCPT from foo[127.0.0.2]: 554 <no.recipient.domain>: Domain not found
+554 <no.recipient.domain>: Domain not found
 >>> mail wietse@no.sender.domain
 OK
 >>> rcpt wietse@porcupine.org
-./smtpd_check: reject: RCPT from foo[127.0.0.2]: 550 <no.sender.domain>: Domain not found
-550 <no.sender.domain>: Domain not found
+./smtpd_check: reject: RCPT from foo[127.0.0.2]: 554 <no.sender.domain>: Domain not found
+554 <no.sender.domain>: Domain not found
index fddcd3ce1be43c6dd1189f65f55aae58d8837d99..b03f3a50d59438287ac78e4fab63c4328496b029 100644 (file)
@@ -1,7 +1,7 @@
-bad.domain             550 match bad.domain
+bad.domain             554 match bad.domain
 friend.bad.domain      OK
-bad-sender@            550 match bad-sender@
+bad-sender@            554 match bad-sender@
 bad-sender@good.domain OK
-131.155.210            550 match 131.155.210
+131.155.210            554 match 131.155.210
 131.155.210.17         OK
-reject@this.address    550 match reject@this.address
+reject@this.address    554 match reject@this.address
index fc9774ba8cf9e487205fe62983fb97c85c464288..ce21b568dc78716588719c44c5618d1dccb0827c 100644 (file)
@@ -43,7 +43,7 @@
 -TINET_ADDR_LIST
 -TINT_TABLE
 -TLOCAL_STATE
--TMAC_EXP_CONTEXT
+-TMAC_EXP
 -TMAC_HEAD
 -TMAC_PARSE
 -TMAIL_PRINT
index fc9774ba8cf9e487205fe62983fb97c85c464288..ce21b568dc78716588719c44c5618d1dccb0827c 100644 (file)
@@ -43,7 +43,7 @@
 -TINET_ADDR_LIST
 -TINT_TABLE
 -TLOCAL_STATE
--TMAC_EXP_CONTEXT
+-TMAC_EXP
 -TMAC_HEAD
 -TMAC_PARSE
 -TMAIL_PRINT
index fc9774ba8cf9e487205fe62983fb97c85c464288..ce21b568dc78716588719c44c5618d1dccb0827c 100644 (file)
@@ -43,7 +43,7 @@
 -TINET_ADDR_LIST
 -TINT_TABLE
 -TLOCAL_STATE
--TMAC_EXP_CONTEXT
+-TMAC_EXP
 -TMAC_HEAD
 -TMAC_PARSE
 -TMAIL_PRINT
index 8c5da1b87deaa90da0ecb68dc3ba2c2a5749ecd4..6ee96b07a60efd9e8120ec3d8727ea7f01db27ba 100644 (file)
@@ -6,31 +6,56 @@
 /* SYNOPSIS
 /*     #include <mac_expand.h>
 /*
+/*     MAC_EXP *mac_exp_update(handle, key, ...)
+/*     MAC_EXP *handle;
+/*     int     key;
+/*
+/*     int     mac_expand_use(handle, result, pattern, flags)
+/*     MAC_EXP *handle;
+/*     VSTRING *result;
+/*     const char *pattern;
+/*     int     flags;
+/*
+/*     void    mac_expand_free(handle)
+/*     MAC_EXP *handle;
+/*
 /*     int     mac_expand(result, pattern, flags, key, ...)
 /*     VSTRING *result;
 /*     const char *pattern;
 /*     int     flags;
 /*     int     key;
 /* DESCRIPTION
-/*     mac_expand() expands $name instances in \fBpattern\fR
-/*     and stores the result into \fBresult\fR.
-/*
-/*     The following expansions are done:
+/*     This module maintains a private attribute-value list and implements
+/*     the following expansions:
 /* .IP "$name, ${name}, $(name)"
-/*     The result is the value of the named parameter. Optionally, the
+/*     The result is the value of the named attribute. Optionally, the
 /*     result is subjected to further expansions.
 /* .IP "${name?text}, $(name?text)"
-/*     If the named parameter is defined, the result is the given text,
+/*     If the named attribute is defined, the result is the given text,
 /*     after another iteration of $name expansion. Otherwise, the result is
 /*     empty.
 /* .IP "${name:text}, $(name:text)"
-/*     If the named parameter is undefined, the result is the given text,
+/*     If the named attribute is undefined, the result is the given text,
 /*     after another iteration of $name expansion. Otherwise, the result is
 /*     empty.
 /* .PP
+/*     max_expand_update() updates an existing macro expansion context
+/*     or instantiates a new one when given a null handle.  The result
+/*     is a handle that can be used by other mac_expand_xxx() routines.
+/*
+/*     mac_expand_use() uses a macro expansion context to replace $name etc.
+/*     instances in \fBpattern\fR and stores the result into \fBresult\fR.
+/*
+/*     mac_expand_free() destroys a macro expansion context.
+/*
+/*     mac_expand() is a convenience routine that combines all of the
+/*     above in one function call.
+/*
 /*     Arguments:
+/* .IP mc
+/*     Macro expansion context created or update with mac_expand_update().
 /* .IP result
-/*     Storage for the result of expansion. The result is not truncated
+/*     Storage for the result of expansion. The result is truncated
 /*     upon entry.
 /* .IP pattern
 /*     The string to be expanded.
 /* .IP "MAC_EXP_ARG_ATTR (char *, char *)"
 /*     The next two arguments specify an attribute name and its attribute
 /*     string value.  Specify a null string value for an attribute that is
-/*     known but unset.
+/*     known but unset. Attribute string values are not copied.
 /* .IP "MAC_EXP_ARG_TABLE (HTABLE *)"
 /*     The next argument is a hash table with attribute names and values.
-/*     Specify a null string value for an attribute that is known but unset.
+/*     Specify a null string value for an attribute that is known but unset. 
+/*     Attribute string values are not copied.
 /* .IP "MAC_EXP_ARG_FILTER (char *)"
 /*     The next argument specifies a null-terminated list of characters
 /*     that are allowed to appear in $name expansions. By default, illegal
 /*     characters are replaced by underscore. Only the last specified
-/*     filter takes effect.
+/*     filter takes effect. Specify a null pointer to disable filtering.
 /* .IP "MAC_EXP_ARG_CLOBBER (int)"
 /*     Character value to be used when the result of expansion is not
 /*     allowed according to the MAC_EXP_ARG_FILTER argument. Only the
  /*
   * Little helper structure.
   */
-typedef struct {
+struct MAC_EXP {
     HTABLE *table;                     /* private symbol table */
     VSTRING *result;                   /* result buffer */
     const char *filter;                        /* safe character list */
@@ -116,22 +142,22 @@ typedef struct {
     int     flags;                     /* findings, features */
     int     level;                     /* nesting level */
     jmp_buf jbuf;                      /* escape */
-} MAC_EXP_CONTEXT;
+};
 
 /* mac_expand_callback - callback for mac_parse */
 
 static void mac_expand_callback(int type, VSTRING *buf, char *ptr)
 {
     char   *myname = "mac_expand_callback";
-    MAC_EXP_CONTEXT *context = (MAC_EXP_CONTEXT *) ptr;
+    MAC_EXP *mc = (MAC_EXP *) ptr;
     HTABLE_INFO *ht;
     char   *text;
     char   *cp;
     int     ch;
 
-    if (context->level++ > 100) {
+    if (mc->level++ > 100) {
        msg_warn("unreasonable macro call nesting: \"%s\"", vstring_str(buf));
-       longjmp(context->jbuf, 1);
+       longjmp(mc->jbuf, 1);
     }
 
     /*
@@ -151,14 +177,14 @@ static void mac_expand_callback(int type, VSTRING *buf, char *ptr)
            }
            if (!ISALNUM(ch) && ch != '_') {
                msg_warn("macro name syntax error: \"%s\"", vstring_str(buf));
-               longjmp(context->jbuf, 1);
+               longjmp(mc->jbuf, 1);
            }
        }
 
        /*
         * Look up the named parameter.
         */
-       text = (ht = htable_locate(context->table, vstring_str(buf))) == 0 ?
+       text = (ht = htable_locate(mc->table, vstring_str(buf))) == 0 ?
            0 : ht->value;
 
        /*
@@ -167,27 +193,27 @@ static void mac_expand_callback(int type, VSTRING *buf, char *ptr)
        switch (ch) {
        case '?':
            if (text != 0)
-               mac_parse(cp, mac_expand_callback, (char *) context);
+               mac_parse(cp, mac_expand_callback, (char *) mc);
            break;
        case ':':
            if (text == 0)
-               mac_parse(cp, mac_expand_callback, (char *) context);
+               mac_parse(cp, mac_expand_callback, (char *) mc);
            break;
        default:
            if (text == 0) {
-               context->flags |= MAC_EXP_FLAG_UNDEF;
+               mc->flags |= MAC_EXP_FLAG_UNDEF;
                break;
            }
-           if (context->filter) {
+           if (mc->filter) {
                vstring_strcpy(buf, text);
                text = vstring_str(buf);
-               for (cp = text; (cp += strspn(cp, context->filter))[0];)
-                   *cp++ = context->clobber;
+               for (cp = text; (cp += strspn(cp, mc->filter))[0];)
+                   *cp++ = mc->clobber;
            }
-           if (context->flags & MAC_EXP_FLAG_RECURSE)
-               mac_parse(text, mac_expand_callback, (char *) context);
+           if (mc->flags & MAC_EXP_FLAG_RECURSE)
+               mac_parse(text, mac_expand_callback, (char *) mc);
            else
-               vstring_strcat(context->result, text);
+               vstring_strcat(mc->result, text);
            break;
        }
     }
@@ -197,7 +223,7 @@ static void mac_expand_callback(int type, VSTRING *buf, char *ptr)
      */
     else {
        text = vstring_str(buf);
-       vstring_strcat(context->result, text);
+       vstring_strcat(mc->result, text);
     }
 
     /*
@@ -207,15 +233,13 @@ static void mac_expand_callback(int type, VSTRING *buf, char *ptr)
        msg_info("%s: %s = %s", myname, vstring_str(buf),
                 text ? text : "(undef)");
 
-    context->level--;
+    mc->level--;
 }
 
-/* mac_expand - expand $name instances */
+/* mac_expand_update_va - update engine */
 
-int     mac_expand(VSTRING *result, const char *pattern, int flags, int key,...)
+static MAC_EXP *mac_expand_update_va(MAC_EXP *mc, int key, va_list ap)
 {
-    MAC_EXP_CONTEXT context;
-    va_list ap;
     HTABLE_INFO **ht_info;
     HTABLE_INFO **ht;
     HTABLE *table;
@@ -231,54 +255,105 @@ int     mac_expand(VSTRING *result, const char *pattern, int flags, int key,...)
     } while(0);
 
     /*
-     * Inititalize.
+     * Optionally create expansion context.
      */
-    context.table = htable_create(0);
-    context.result = result;
-    context.flags = flags;
-    context.filter = 0;
-    context.clobber = '_';
-    context.level = 0;
+    if (mc == 0) {
+       mc = (MAC_EXP *) mymalloc(sizeof(*mc));
+       mc->table = htable_create(0);
+       mc->result = 0;
+       mc->flags = 0;
+       mc->filter = 0;
+       mc->clobber = '_';
+       mc->level = 0;
+    }
 
     /*
      * Stash away the attributes.
      */
-    for (va_start(ap, key); key != 0; key = va_arg(ap, int)) {
+    for ( /* void */ ; key != 0; key = va_arg(ap, int)) {
        switch (key) {
        case MAC_EXP_ARG_ATTR:
            name = va_arg(ap, char *);
            value = va_arg(ap, char *);
-           HTABLE_CLOBBER(context.table, name, value);
+           HTABLE_CLOBBER(mc->table, name, value);
            break;
        case MAC_EXP_ARG_TABLE:
            table = va_arg(ap, HTABLE *);
            ht_info = htable_list(table);
            for (ht = ht_info; *ht; ht++)
-               HTABLE_CLOBBER(context.table, ht[0]->key, ht[0]->value);
+               HTABLE_CLOBBER(mc->table, ht[0]->key, ht[0]->value);
            myfree((char *) ht_info);
            break;
        case MAC_EXP_ARG_FILTER:
-           context.filter = va_arg(ap, char *);
+           mc->filter = va_arg(ap, char *);
            break;
        case MAC_EXP_ARG_CLOBBER:
-           context.clobber = va_arg(ap, int);
+           mc->clobber = va_arg(ap, int);
            break;
        }
     }
+    return (mc);
+}
+
+/* mac_expand_update - update or create macro expansion context */
+
+MAC_EXP *mac_expand_update(MAC_EXP *mc, int key,...)
+{
+    va_list ap;
+
+    va_start(ap, key);
+    mc = mac_expand_update(mc, key, ap);
+    va_end(ap);
+    return (mc);
+}
+
+/* mac_expand_use - string expansion */
+
+int     mac_expand_use(MAC_EXP *mc, VSTRING *result, const char *pattern, int flags)
+{
+    VSTRING_RESET(result);
+    mc->result = result;
+    mc->level = 0;
+    mc->flags = flags;
+    if (setjmp(mc->jbuf) == 0)
+       mac_parse(pattern, mac_expand_callback, (char *) mc);
+    VSTRING_TERMINATE(result);
+    return (mc->flags & MAC_EXP_FLAG_UNDEF);
+}
+
+/* mac_expand_free - destroy macro expansion context */
+
+void    mac_expand_free(MAC_EXP *mc)
+{
+    htable_free(mc->table, (void (*) (char *)) 0);
+    myfree((char *) mc);
+}
+
+/* mac_expand - expand $name instances */
+
+int     mac_expand(VSTRING *result, const char *pattern, int flags, int key,...)
+{
+    MAC_EXP *mc = 0;
+    va_list ap;
+    int     status;
+
+    /*
+     * Stash away the attributes.
+     */
+    va_start(ap, key);
+    mc = mac_expand_update_va(mc, key, ap);
     va_end(ap);
 
     /*
      * Do the substitutions.
      */
-    if (setjmp(context.jbuf) == 0)
-       mac_parse(pattern, mac_expand_callback, (char *) &context);
-    VSTRING_TERMINATE(result);
+    status = mac_expand_use(mc, result, pattern, flags);
 
     /*
      * Clean up.
      */
-    htable_free(context.table, (void (*) (char *)) 0);
-    return (context.flags & MAC_EXP_FLAG_UNDEF);
+    mac_expand_free(mc);
+    return (status);
 }
 
 #ifdef TEST
index e6a47a1cd4a285a2e6f948bfd5ff45b04475cab8..9a3cce818a0ed8112c95e0df7f99c283d5d21eed 100644 (file)
@@ -19,6 +19,8 @@
  /*
   * External interface.
   */
+typedef struct MAC_EXP MAC_EXP;
+
 #define MAC_EXP_FLAG_NONE      (0)
 #define MAC_EXP_FLAG_UNDEF     (1<<0)
 #define MAC_EXP_FLAG_RECURSE   (1<<1)
 #define MAC_EXP_ARG_FILTER     3
 #define MAC_EXP_ARG_CLOBBER    4
 
+extern MAC_EXP *mac_expand_update(MAC_EXP *, int,...);
+extern int mac_expand_use(MAC_EXP *, VSTRING *, const char *, int);
+extern void mac_expand_free(MAC_EXP *);
+
 extern int mac_expand(VSTRING *, const char *, int, int,...);
 
 /* LICENSE