-TPIPE_STATE
-TPLMYSQL
-TPLPGSQL
+-TPOSTMAP_KEY_STATE
-TPOST_MAIL_STATE
-TQMGR_ENTRY
-TQMGR_FEEDBACK
Bugfix (introduced 20080207): "cleanup -v" panic because
the new "SMTP reply" request flag did not have a printable
name. File: global/cleanup_strflags.c.
+
+20080318
+
+ Human factors: the PCRE and regexp maps now give more
+ comprehensible error messages when people make the common
+ mistake of indenting if/endif blocks. Files: util/dict_pcre.c,
+ util/dict_regexp.c.
+
+20030824
+
+ Cleanup: the event_drain() function is now a proper event
+ processing loop. File: util/events.c
+
+ Feature: when the "postmap -q -" command reads lookup keys
+ from standard input, it now understands RFC822 and MIME
+ message format. Specify -h or -b to use headers or body
+ lines as lookup keys, and specify -hm or -bm to simulate
+ header_checks or body_checks. The postmap -h option (without
+ -m) will be compatible with a future postmap -h option.
+ File: postmap/postmap.c.
the final state. But first we need to clean up the handling
of do/don't cache, expired, bad and dead sessions.
- Make event_drain() a proper event loop; update the zero mask,
- and don't ignore a non-empty timer queue.
-
Combine smtpd_peer.c and qmqpd_peer.c into a single function
that produces a client context object, and provide attribute
print/scan routines that pass these client context objects
What headers? primary, mime, nested? What body? Does it
include the mime and attached headers?
- Make postmap header/body aware so people can test multi-line
- header checks. What headers? primary, mime, nested? What
- body? Does it include the mime and attached headers?
-
REDIRECT should override original recipient info, and
probably override DSN as well.
postmap - Postfix lookup table management
<b>SYNOPSIS</b>
- <b>postmap</b> [<b>-Nfinoprsvw</b>] [<b>-c</b> <i>config</i><b>_</b><i>dir</i>] [<b>-d</b> <i>key</i>] [<b>-q</b> <i>key</i>]
+ <b>postmap</b> [<b>-Nbfhimnoprsvw</b>] [<b>-c</b> <i>config</i><b>_</b><i>dir</i>] [<b>-d</b> <i>key</i>] [<b>-q</b> <i>key</i>]
[<i>file</i><b>_</b><i>type</i>:]<i>file</i><b>_</b><i>name</i> ...
<b>DESCRIPTION</b>
- The <a href="postmap.1.html"><b>postmap</b>(1)</a> command creates or queries one or more
- Postfix lookup tables, or updates an existing one. The
- input and output file formats are expected to be compati-
+ The <a href="postmap.1.html"><b>postmap</b>(1)</a> command creates or queries one or more
+ Postfix lookup tables, or updates an existing one. The
+ input and output file formats are expected to be compati-
ble with:
<b>makemap</b> <i>file</i><b>_</b><i>type file</i><b>_</b><i>name</i> < <i>file</i><b>_</b><i>name</i>
If the result files do not exist they will be created with
- the same group and other read permissions as their source
+ the same group and other read permissions as their source
file.
- While the table update is in progress, signal delivery is
- postponed, and an exclusive, advisory, lock is placed on
+ While the table update is in progress, signal delivery is
+ postponed, and an exclusive, advisory, lock is placed on
the entire table, in order to avoid surprises in spectator
processes.
<i>key</i> whitespace <i>value</i>
- <b>o</b> Empty lines and whitespace-only lines are ignored,
- as are lines whose first non-whitespace character
+ <b>o</b> Empty lines and whitespace-only lines are ignored,
+ as are lines whose first non-whitespace character
is a `#'.
- <b>o</b> A logical line starts with non-whitespace text. A
- line that starts with whitespace continues a logi-
+ <b>o</b> A logical line starts with non-whitespace text. A
+ line that starts with whitespace continues a logi-
cal line.
- The <i>key</i> and <i>value</i> are processed as is, except that sur-
- rounding white space is stripped off. Unlike with Postfix
- alias databases, quotes cannot be used to protect lookup
+ The <i>key</i> and <i>value</i> are processed as is, except that sur-
+ rounding white space is stripped off. Unlike with Postfix
+ alias databases, quotes cannot be used to protect lookup
keys that contain special characters such as `#' or white-
space.
- By default the lookup key is mapped to lowercase to make
- the lookups case insensitive; as of Postfix 2.3 this case
- folding happens only with tables whose lookup keys are
- fixed-case strings such as btree:, dbm: or hash:. With
- earlier versions, the lookup key is folded even with
+ By default the lookup key is mapped to lowercase to make
+ the lookups case insensitive; as of Postfix 2.3 this case
+ folding happens only with tables whose lookup keys are
+ fixed-case strings such as btree:, dbm: or hash:. With
+ earlier versions, the lookup key is folded even with
tables where a lookup field can match both upper and lower
- case text, such as <a href="regexp_table.5.html">regexp</a>: and <a href="pcre_table.5.html">pcre</a>:. This resulted in
+ case text, such as <a href="regexp_table.5.html">regexp</a>: and <a href="pcre_table.5.html">pcre</a>:. This resulted in
loss of information with $<i>number</i> substitutions.
<b>COMMAND-LINE ARGUMENTS</b>
+ <b>-b</b> Enable message body query mode. When reading lookup
+ keys from standard input with "<b>-q -</b>", process the
+ input as if it is an email message in <a href="http://tools.ietf.org/html/rfc2822">RFC 2822</a> for-
+ mat. Each line of body content becomes one lookup
+ key.
+
+ By default, this processing of body content starts
+ at the first non-header line, and continues until
+ the end of the message is reached.
+
+ To simulate <a href="header_checks.5.html"><b>body_checks</b>(5)</a> processing, enable MIME
+ parsing with <b>-m</b>. With this, the <b>-b</b> option generates
+ no body-style lookup keys from attachment MIME
+ headers and from attached message/* headers.
+
+ This feature is available in Postfix version 2.6
+ and later.
+
<b>-c</b> <i>config</i><b>_</b><i>dir</i>
- Read the <a href="postconf.5.html"><b>main.cf</b></a> configuration file in the named
+ Read the <a href="postconf.5.html"><b>main.cf</b></a> configuration file in the named
directory instead of the default configuration
directory.
- <b>-d</b> <i>key</i> Search the specified maps for <i>key</i> and remove one
- entry per map. The exit status is zero when the
+ <b>-d</b> <i>key</i> Search the specified maps for <i>key</i> and remove one
+ entry per map. The exit status is zero when the
requested information was found.
If a key value of <b>-</b> is specified, the program reads
key values from the standard input stream. The exit
- status is zero when at least one of the requested
+ status is zero when at least one of the requested
keys was found.
<b>-f</b> Do not fold the lookup key to lower case while cre-
ating or querying a table.
With Postfix version 2.3 and later, this option has
- no effect for regular expression tables. There,
+ no effect for regular expression tables. There,
case folding is controlled by appending a flag to a
pattern.
- <b>-i</b> Incremental mode. Read entries from standard input
+ <b>-h</b> Enable message header query mode. When reading
+ lookup keys from standard input with "<b>-q -</b>",
+ process the input as if it is an email message in
+ <a href="http://tools.ietf.org/html/rfc2822">RFC 2822</a> format. Each logical header line becomes
+ one lookup key. A multi-line header becomes one
+ string with embedded newline characters.
+
+ By default, this processing of header content ends
+ at the first non-header line.
+
+ To simulate <a href="header_checks.5.html"><b>header_checks</b>(5)</a> processing, enable
+ MIME parsing with <b>-m</b>. With this, the <b>-h</b> option also
+ generates header-style lookup keys from attachment
+ MIME headers and from attached message/* headers.
+
+ This feature is available in Postfix version 2.6
+ and later.
+
+ <b>-i</b> Incremental mode. Read entries from standard input
and do not truncate an existing database. By
default, <a href="postmap.1.html"><b>postmap</b>(1)</a> creates a new database from the
entries in <b>file_name</b>.
+ <b>-m</b> Enable MIME mode mode with "<b>-b</b>" and "<b>-h</b>".
+
+ This feature is available in Postfix version 2.6
+ and later.
+
<b>-N</b> Include the terminating null character that termi-
nates lookup keys and values. By default,
<a href="postmap.1.html"><b>postmap</b>(1)</a> does whatever is the default for the
<b>-s</b> Retrieve all database elements, and write one line
of <i>key value</i> output for each element. The elements
are printed in database order, which is not neces-
- sarily the same as the original input order. This
- feature is available in Postfix version 2.2 and
- later, and is not available for all database types.
+ sarily the same as the original input order.
+
+ This feature is available in Postfix version 2.2
+ and later, and is not available for all database
+ types.
<b>-v</b> Enable verbose logging for debugging purposes. Mul-
- tiple <b>-v</b> options make the software increasingly
+ tiple <b>-v</b> options make the software increasingly
verbose.
<b>-w</b> When updating a table, do not complain about
- attempts to update existing entries, and ignore
+ attempts to update existing entries, and ignore
those attempts.
Arguments:
<i>file</i><b>_</b><i>type</i>
- The database type. To find out what types are sup-
+ The database type. To find out what types are sup-
ported, use the "<b>postconf -m</b>" command.
The <a href="postmap.1.html"><b>postmap</b>(1)</a> command can query any supported file
- type, but it can create only the following file
+ type, but it can create only the following file
types:
- <b>btree</b> The output file is a btree file, named
- <i>file</i><b>_</b><i>name</i><b>.db</b>. This is available on systems
+ <b>btree</b> The output file is a btree file, named
+ <i>file</i><b>_</b><i>name</i><b>.db</b>. This is available on systems
with support for <b>db</b> databases.
<b>cdb</b> The output consists of one file, named
<i>file</i><b>_</b><i>name</i><b>.cdb</b>. This is available on systems
with support for <b>cdb</b> databases.
- <b>dbm</b> The output consists of two files, named
- <i>file</i><b>_</b><i>name</i><b>.pag</b> and <i>file</i><b>_</b><i>name</i><b>.dir</b>. This is
- available on systems with support for <b>dbm</b>
+ <b>dbm</b> The output consists of two files, named
+ <i>file</i><b>_</b><i>name</i><b>.pag</b> and <i>file</i><b>_</b><i>name</i><b>.dir</b>. This is
+ available on systems with support for <b>dbm</b>
databases.
- <b>hash</b> The output file is a hashed file, named
- <i>file</i><b>_</b><i>name</i><b>.db</b>. This is available on systems
+ <b>hash</b> The output file is a hashed file, named
+ <i>file</i><b>_</b><i>name</i><b>.db</b>. This is available on systems
with support for <b>db</b> databases.
- <b>sdbm</b> The output consists of two files, named
- <i>file</i><b>_</b><i>name</i><b>.pag</b> and <i>file</i><b>_</b><i>name</i><b>.dir</b>. This is
- available on systems with support for <b>sdbm</b>
+ <b>sdbm</b> The output consists of two files, named
+ <i>file</i><b>_</b><i>name</i><b>.pag</b> and <i>file</i><b>_</b><i>name</i><b>.dir</b>. This is
+ available on systems with support for <b>sdbm</b>
databases.
- When no <i>file</i><b>_</b><i>type</i> is specified, the software uses
- the database type specified via the <b><a href="postconf.5.html#default_database_type">default_data</a>-</b>
+ When no <i>file</i><b>_</b><i>type</i> is specified, the software uses
+ the database type specified via the <b><a href="postconf.5.html#default_database_type">default_data</a>-</b>
<b><a href="postconf.5.html#default_database_type">base_type</a></b> configuration parameter.
<i>file</i><b>_</b><i>name</i>
- The name of the lookup table source file when
+ The name of the lookup table source file when
rebuilding a database.
<b>DIAGNOSTICS</b>
- Problems are logged to the standard error stream and to
- <b>syslogd</b>(8). No output means that no problems were
- detected. Duplicate entries are skipped and are flagged
+ Problems are logged to the standard error stream and to
+ <b>syslogd</b>(8). No output means that no problems were
+ detected. Duplicate entries are skipped and are flagged
with a warning.
- <a href="postmap.1.html"><b>postmap</b>(1)</a> terminates with zero exit status in case of
- success (including successful "<b>postmap -q</b>" lookup) and
+ <a href="postmap.1.html"><b>postmap</b>(1)</a> terminates with zero exit status in case of
+ success (including successful "<b>postmap -q</b>" lookup) and
terminates with non-zero exit status in case of failure.
<b>ENVIRONMENT</b>
Enable verbose logging for debugging purposes.
<b>CONFIGURATION PARAMETERS</b>
- The following <a href="postconf.5.html"><b>main.cf</b></a> parameters are especially relevant
+ The following <a href="postconf.5.html"><b>main.cf</b></a> parameters are especially relevant
to this program. The text below provides only a parameter
- summary. See <a href="postconf.5.html"><b>postconf</b>(5)</a> for more details including exam-
+ summary. See <a href="postconf.5.html"><b>postconf</b>(5)</a> for more details including exam-
ples.
<b><a href="postconf.5.html#berkeley_db_create_buffer_size">berkeley_db_create_buffer_size</a> (16777216)</b>
- The per-table I/O buffer size for programs that
+ The per-table I/O buffer size for programs that
create Berkeley DB hash or btree tables.
<b><a href="postconf.5.html#berkeley_db_read_buffer_size">berkeley_db_read_buffer_size</a> (131072)</b>
- The per-table I/O buffer size for programs that
+ The per-table I/O buffer size for programs that
read Berkeley DB hash or btree tables.
<b><a href="postconf.5.html#config_directory">config_directory</a> (see 'postconf -d' output)</b>
- The default location of the Postfix <a href="postconf.5.html">main.cf</a> and
+ The default location of the Postfix <a href="postconf.5.html">main.cf</a> and
<a href="master.5.html">master.cf</a> configuration files.
<b><a href="postconf.5.html#default_database_type">default_database_type</a> (see 'postconf -d' output)</b>
The syslog facility of Postfix logging.
<b><a href="postconf.5.html#syslog_name">syslog_name</a> (postfix)</b>
- The mail system name that is prepended to the
- process name in syslog records, so that "smtpd"
+ The mail system name that is prepended to the
+ process name in syslog records, so that "smtpd"
becomes, for example, "postfix/smtpd".
<b>SEE ALSO</b>
<a href="DATABASE_README.html">DATABASE_README</a>, Postfix lookup table overview
<b>LICENSE</b>
- The Secure Mailer license must be distributed with this
+ The Secure Mailer license must be distributed with this
software.
<b>AUTHOR(S)</b>
.na
.nf
.fi
-\fBpostmap\fR [\fB-Nfinoprsvw\fR] [\fB-c \fIconfig_dir\fR]
+\fBpostmap\fR [\fB-Nbfhimnoprsvw\fR] [\fB-c \fIconfig_dir\fR]
[\fB-d \fIkey\fR] [\fB-q \fIkey\fR]
[\fIfile_type\fR:]\fIfile_name\fR ...
.SH DESCRIPTION
.nf
.ad
.fi
+.IP \fB-b\fR
+Enable message body query mode. When reading lookup keys
+from standard input with "\fB-q -\fR", process the input
+as if it is an email message in RFC 2822 format. Each line
+of body content becomes one lookup key.
+.sp
+By default, this processing of body content starts at the
+first non-header line, and continues until the end of the
+message is reached.
+.sp
+To simulate \fBbody_checks\fR(5) processing, enable MIME
+parsing with \fB-m\fR. With this, the \fB-b\fR option
+generates no body-style lookup keys from attachment MIME
+headers and from attached message/* headers.
+.sp
+This feature is available in Postfix version 2.6 and later.
.IP "\fB-c \fIconfig_dir\fR"
Read the \fBmain.cf\fR configuration file in the named directory
instead of the default configuration directory.
With Postfix version 2.3 and later, this option has no
effect for regular expression tables. There, case folding
is controlled by appending a flag to a pattern.
+.IP \fB-h\fR
+Enable message header query mode. When reading lookup keys
+from standard input with "\fB-q -\fR", process the input
+as if it is an email message in RFC 2822 format. Each
+logical header line becomes one lookup key. A multi-line
+header becomes one string with embedded newline characters.
+.sp
+By default, this processing of header content ends at the
+first non-header line.
+.sp
+To simulate \fBheader_checks\fR(5) processing, enable MIME
+parsing with \fB-m\fR. With this, the \fB-h\fR option also
+generates header-style lookup keys from attachment MIME
+headers and from attached message/* headers.
+.sp
+This feature is available in Postfix version 2.6 and later.
.IP \fB-i\fR
Incremental mode. Read entries from standard input and do not
truncate an existing database. By default, \fBpostmap\fR(1) creates
a new database from the entries in \fBfile_name\fR.
+.IP \fB-m\fR
+Enable MIME mode mode with "\fB-b\fR" and "\fB-h\fR".
+.sp
+This feature is available in Postfix version 2.6 and later.
.IP \fB-N\fR
Include the terminating null character that terminates lookup keys
and values. By default, \fBpostmap\fR(1) does whatever is
\fIkey value\fR output for each element. The elements are
printed in database order, which is not necessarily the same
as the original input order.
+.sp
This feature is available in Postfix version 2.2 and later,
and is not available for all database types.
.IP \fB-v\fR
<p> This feature is available in Postfix 2.2 and later. </p>
-%PARAM smtp_generic_maps empty
+%PARAM smtp_generic_maps
<p> Optional lookup tables that perform address rewriting in the
SMTP client, typically to transform a locally valid address into
<p> This feature is available in Postfix 2.2 and later. </p>
-%PARAM message_reject_characters empty
+%PARAM message_reject_characters
<p> The set of characters that Postfix will reject in message
content. The usual C-like escape sequences are recognized: <tt>\a
<p> This feature is available in Postfix 2.3 and later. </p>
-%PARAM message_strip_characters empty
+%PARAM message_strip_characters
<p> The set of characters that Postfix will remove from message
content. The usual C-like escape sequences are recognized: <tt>\a
<p> This feature is available in Postfix 2.3 and later. </p>
-%PARAM bounce_template_file empty
+%PARAM bounce_template_file
<p> Pathname of a configuration file with bounce message templates.
These override the built-in templates of delivery status notification
<p> This feature is available in Postfix 2.3 and later. </p>
-%PARAM sender_dependent_relayhost_maps empty
+%PARAM sender_dependent_relayhost_maps
<p> A sender-dependent override for the global relayhost parameter
setting. The tables are searched by the envelope sender address and
<p> This feature is available in Postfix 2.3 and later. </p>
-%PARAM smtpd_milters empty
+%PARAM smtpd_milters
<p> A list of Milter (mail filter) applications for new mail that
arrives via the Postfix smtpd(8) server. See the MILTER_README
<p> This feature is available in Postfix 2.3 and later. </p>
-%PARAM non_smtpd_milters empty
+%PARAM non_smtpd_milters
<p> A list of Milter (mail filter) applications for new mail that
does not arrive via the Postfix smtpd(8) server. This includes local
* Patches change both the patchlevel and the release date. Snapshots have no
* patchlevel; they change the release date only.
*/
-#define MAIL_RELEASE_DATE "20080316"
+#define MAIL_RELEASE_DATE "20080324"
#define MAIL_VERSION_NUMBER "2.6"
#ifdef SNAPSHOT
postmap.o: ../../include/argv.h
postmap.o: ../../include/dict.h
postmap.o: ../../include/dict_proxy.h
+postmap.o: ../../include/header_opts.h
postmap.o: ../../include/mail_conf.h
postmap.o: ../../include/mail_dict.h
postmap.o: ../../include/mail_params.h
postmap.o: ../../include/mail_task.h
postmap.o: ../../include/mail_version.h
+postmap.o: ../../include/mime_state.h
postmap.o: ../../include/mkmap.h
postmap.o: ../../include/msg.h
postmap.o: ../../include/msg_syslog.h
postmap.o: ../../include/msg_vstream.h
postmap.o: ../../include/mymalloc.h
postmap.o: ../../include/readlline.h
+postmap.o: ../../include/rec_type.h
postmap.o: ../../include/set_eugid.h
postmap.o: ../../include/split_at.h
postmap.o: ../../include/stringops.h
/* Postfix lookup table management
/* SYNOPSIS
/* .fi
-/* \fBpostmap\fR [\fB-Nfinoprsvw\fR] [\fB-c \fIconfig_dir\fR]
+/* \fBpostmap\fR [\fB-Nbfhimnoprsvw\fR] [\fB-c \fIconfig_dir\fR]
/* [\fB-d \fIkey\fR] [\fB-q \fIkey\fR]
/* [\fIfile_type\fR:]\fIfile_name\fR ...
/* DESCRIPTION
/* COMMAND-LINE ARGUMENTS
/* .ad
/* .fi
+/* .IP \fB-b\fR
+/* Enable message body query mode. When reading lookup keys
+/* from standard input with "\fB-q -\fR", process the input
+/* as if it is an email message in RFC 2822 format. Each line
+/* of body content becomes one lookup key.
+/* .sp
+/* By default, this processing of body content starts at the
+/* first non-header line, and continues until the end of the
+/* message is reached.
+/* .sp
+/* To simulate \fBbody_checks\fR(5) processing, enable MIME
+/* parsing with \fB-m\fR. With this, the \fB-b\fR option
+/* generates no body-style lookup keys from attachment MIME
+/* headers and from attached message/* headers.
+/* .sp
+/* This feature is available in Postfix version 2.6 and later.
/* .IP "\fB-c \fIconfig_dir\fR"
/* Read the \fBmain.cf\fR configuration file in the named directory
/* instead of the default configuration directory.
/* With Postfix version 2.3 and later, this option has no
/* effect for regular expression tables. There, case folding
/* is controlled by appending a flag to a pattern.
+/* .IP \fB-h\fR
+/* Enable message header query mode. When reading lookup keys
+/* from standard input with "\fB-q -\fR", process the input
+/* as if it is an email message in RFC 2822 format. Each
+/* logical header line becomes one lookup key. A multi-line
+/* header becomes one string with embedded newline characters.
+/* .sp
+/* By default, this processing of header content ends at the
+/* first non-header line.
+/* .sp
+/* To simulate \fBheader_checks\fR(5) processing, enable MIME
+/* parsing with \fB-m\fR. With this, the \fB-h\fR option also
+/* generates header-style lookup keys from attachment MIME
+/* headers and from attached message/* headers.
+/* .sp
+/* This feature is available in Postfix version 2.6 and later.
/* .IP \fB-i\fR
/* Incremental mode. Read entries from standard input and do not
/* truncate an existing database. By default, \fBpostmap\fR(1) creates
/* a new database from the entries in \fBfile_name\fR.
+/* .IP \fB-m\fR
+/* Enable MIME mode mode with "\fB-b\fR" and "\fB-h\fR".
+/* .sp
+/* This feature is available in Postfix version 2.6 and later.
/* .IP \fB-N\fR
/* Include the terminating null character that terminates lookup keys
/* and values. By default, \fBpostmap\fR(1) does whatever is
/* \fIkey value\fR output for each element. The elements are
/* printed in database order, which is not necessarily the same
/* as the original input order.
+/* .sp
/* This feature is available in Postfix version 2.2 and later,
/* and is not available for all database types.
/* .IP \fB-v\fR
#include <mkmap.h>
#include <mail_task.h>
#include <dict_proxy.h>
+#include <mime_state.h>
+#include <rec_type.h>
/* Application-specific. */
#define STR vstring_str
+#define LEN VSTRING_LEN
#define POSTMAP_FLAG_AS_OWNER (1<<0) /* open dest as owner of source */
#define POSTMAP_FLAG_SAVE_PERM (1<<1) /* copy access permission from source */
+#define POSTMAP_FLAG_HEADER_KEY (1<<2) /* apply to header text */
+#define POSTMAP_FLAG_BODY_KEY (1<<3) /* apply to body text */
+#define POSTMAP_FLAG_MIME_KEY (1<<4) /* enable MIME parsing */
+
+#define POSTMAP_FLAG_HB_KEY (POSTMAP_FLAG_HEADER_KEY | POSTMAP_FLAG_BODY_KEY)
+#define POSTMAP_FLAG_FULL_KEY (POSTMAP_FLAG_BODY_KEY | POSTMAP_FLAG_MIME_KEY)
+#define POSTMAP_FLAG_ANY_KEY (POSTMAP_FLAG_HB_KEY | POSTMAP_FLAG_MIME_KEY)
+
+ /*
+ * MIME Engine call-back state for generating lookup keys from an email
+ * message read from standard input.
+ */
+typedef struct {
+ DICT **dicts; /* map handles */
+ char **maps; /* map names */
+ int map_count; /* yes, indeed */
+ int dict_flags; /* query flags */
+ int header_done; /* past primary header */
+ int found; /* result */
+} POSTMAP_KEY_STATE;
/* postmap - create or update mapping database */
vstream_fclose(source_fp);
}
+/* postmap_body - MIME engine body call-back routine */
+
+static void postmap_body(void *ptr, int unused_rec_type,
+ const char *keybuf,
+ ssize_t unused_len,
+ off_t unused_offset)
+{
+ POSTMAP_KEY_STATE *state = (POSTMAP_KEY_STATE *) ptr;
+ DICT **dicts = state->dicts;
+ char **maps = state->maps;
+ int map_count = state->map_count;
+ int dict_flags = state->dict_flags;
+ const char *map_name;
+ const char *value;
+ int n;
+
+ for (n = 0; n < map_count; n++) {
+ if (dicts[n] == 0)
+ dicts[n] = ((map_name = split_at(maps[n], ':')) != 0 ?
+ dict_open3(maps[n], map_name, O_RDONLY, dict_flags) :
+ dict_open3(var_db_type, maps[n], O_RDONLY, dict_flags));
+ if ((value = dict_get(dicts[n], keybuf)) != 0) {
+ if (*value == 0) {
+ msg_warn("table %s:%s: key %s: empty string result is not allowed",
+ dicts[n]->type, dicts[n]->name, keybuf);
+ msg_warn("table %s:%s should return NO RESULT in case of NOT FOUND",
+ dicts[n]->type, dicts[n]->name);
+ }
+ vstream_printf("%s %s\n", keybuf, value);
+ state->found = 1;
+ break;
+ }
+ }
+}
+
+/* postmap_header - MIME engine header call-back routine */
+
+static void postmap_header(void *ptr, int unused_header_class,
+ const HEADER_OPTS *unused_header_info,
+ VSTRING *header_buf,
+ off_t offset)
+{
+
+ /*
+ * Don't re-invent an already working wheel.
+ */
+ postmap_body(ptr, 0, STR(header_buf), LEN(header_buf), offset);
+}
+
+/* postmap_head_end - MIME engine end-of-header call-back routine */
+
+static void postmap_head_end(void *ptr)
+{
+ POSTMAP_KEY_STATE *state = (POSTMAP_KEY_STATE *) ptr;
+
+ /*
+ * Don't process the message body when we only examine primary headers.
+ */
+ state->header_done = 1;
+}
+
/* postmap_queries - apply multiple requests from stdin */
static int postmap_queries(VSTREAM *in, char **maps, const int map_count,
+ const int postmap_flags,
const int dict_flags)
{
int found = 0;
* Perform all queries. Open maps on the fly, to avoid opening unecessary
* maps.
*/
- while (vstring_get_nonl(keybuf, in) != VSTREAM_EOF) {
- for (n = 0; n < map_count; n++) {
- if (dicts[n] == 0)
- dicts[n] = ((map_name = split_at(maps[n], ':')) != 0 ?
+ if ((postmap_flags & POSTMAP_FLAG_HB_KEY) == 0) {
+ while (vstring_get_nonl(keybuf, in) != VSTREAM_EOF) {
+ for (n = 0; n < map_count; n++) {
+ if (dicts[n] == 0)
+ dicts[n] = ((map_name = split_at(maps[n], ':')) != 0 ?
dict_open3(maps[n], map_name, O_RDONLY, dict_flags) :
dict_open3(var_db_type, maps[n], O_RDONLY, dict_flags));
- if ((value = dict_get(dicts[n], STR(keybuf))) != 0) {
- if (*value == 0) {
- msg_warn("table %s:%s: key %s: empty string result is not allowed",
- dicts[n]->type, dicts[n]->name, STR(keybuf));
- msg_warn("table %s:%s should return NO RESULT in case of NOT FOUND",
- dicts[n]->type, dicts[n]->name);
+ if ((value = dict_get(dicts[n], STR(keybuf))) != 0) {
+ if (*value == 0) {
+ msg_warn("table %s:%s: key %s: empty string result is not allowed",
+ dicts[n]->type, dicts[n]->name, STR(keybuf));
+ msg_warn("table %s:%s should return NO RESULT in case of NOT FOUND",
+ dicts[n]->type, dicts[n]->name);
+ }
+ vstream_printf("%s %s\n", STR(keybuf), value);
+ found = 1;
+ break;
}
- vstream_printf("%s %s\n", STR(keybuf), value);
- found = 1;
- break;
}
}
+ } else {
+ POSTMAP_KEY_STATE key_state;
+ MIME_STATE *mime_state;
+ int mime_errs = 0;
+
+ /*
+ * Bundle up the request and instantiate a MIME parsing engine.
+ */
+ key_state.dicts = dicts;
+ key_state.maps = maps;
+ key_state.map_count = map_count;
+ key_state.dict_flags = dict_flags;
+ key_state.header_done = 0;
+ key_state.found = 0;
+ mime_state =
+ mime_state_alloc((postmap_flags & POSTMAP_FLAG_MIME_KEY) ?
+ 0 : MIME_OPT_DISABLE_MIME,
+ (postmap_flags & POSTMAP_FLAG_HEADER_KEY) ?
+ postmap_header : (MIME_STATE_HEAD_OUT) 0,
+ (postmap_flags & POSTMAP_FLAG_FULL_KEY) ?
+ (MIME_STATE_ANY_END) 0 : postmap_head_end,
+ (postmap_flags & POSTMAP_FLAG_BODY_KEY) ?
+ postmap_body : (MIME_STATE_BODY_OUT) 0,
+ (MIME_STATE_ANY_END) 0,
+ (MIME_STATE_ERR_PRINT) 0,
+ (void *) &key_state);
+
+ /*
+ * Process the input message.
+ */
+ while (vstring_get_nonl(keybuf, in) != VSTREAM_EOF
+ && key_state.header_done == 0 && mime_errs == 0)
+ mime_errs = mime_state_update(mime_state, REC_TYPE_NORM,
+ STR(keybuf), LEN(keybuf));
+
+ /*
+ * Flush the MIME engine output buffer and tidy up loose ends.
+ */
+ if (mime_errs == 0)
+ mime_errs = mime_state_update(mime_state, REC_TYPE_END, "", 0);
+ if (mime_errs)
+ msg_fatal("message format error: %s",
+ mime_state_detail(mime_errs)->text);
+ mime_state_free(mime_state);
+ found = key_state.found;
}
if (found)
vstream_fflush(VSTREAM_OUT);
/*
* Parse JCL.
*/
- while ((ch = GETOPT(argc, argv, "Nc:d:finopq:rsvw")) > 0) {
+ while ((ch = GETOPT(argc, argv, "Nbc:d:fhimnopq:rsvw")) > 0) {
switch (ch) {
default:
usage(argv[0]);
dict_flags |= DICT_FLAG_TRY1NULL;
dict_flags &= ~DICT_FLAG_TRY0NULL;
break;
+ case 'b':
+ postmap_flags |= POSTMAP_FLAG_BODY_KEY;
+ break;
case 'c':
if (setenv(CONF_ENV_PATH, optarg, 1) < 0)
msg_fatal("out of memory");
case 'f':
dict_flags &= ~DICT_FLAG_FOLD_FIX;
break;
+ case 'h':
+ postmap_flags |= POSTMAP_FLAG_HEADER_KEY;
+ break;
case 'i':
open_flags &= ~O_TRUNC;
break;
+ case 'm':
+ postmap_flags |= POSTMAP_FLAG_MIME_KEY;
+ break;
case 'n':
dict_flags |= DICT_FLAG_TRY0NULL;
dict_flags &= ~DICT_FLAG_TRY1NULL;
if (strcmp(var_syslog_name, DEF_SYSLOG_NAME) != 0)
msg_syslog_init(mail_task(argv[0]), LOG_PID, LOG_FACILITY);
mail_dict_init();
+ if ((query == 0 || strcmp(query, "-") != 0)
+ && (postmap_flags & POSTMAP_FLAG_ANY_KEY))
+ msg_fatal("specify -b -h or -m only with \"-q -\"");
/*
* Use the map type specified by the user, or fall back to a default
usage(argv[0]);
if (strcmp(query, "-") == 0)
exit(postmap_queries(VSTREAM_IN, argv + optind, argc - optind,
- dict_flags | DICT_FLAG_LOCK) == 0);
+ postmap_flags, dict_flags | DICT_FLAG_LOCK) == 0);
while (optind < argc) {
if ((path_name = split_at(argv[optind], ':')) != 0) {
found = postmap_query(argv[optind], path_name, query,
*/
while (*p && ISSPACE(*p))
++p;
- if (*p)
- msg_warn("pcre map %s, line %d: ignoring extra text after IF",
- mapname, lineno);
+ if (*p) {
+ msg_warn("pcre map %s, line %d: ignoring extra text after "
+ "IF statement: \"%s\"", mapname, lineno, p);
+ msg_warn("pcre map %s, line %d: do not prepend whitespace"
+ " to statements between IF and ENDIF", mapname, lineno);
+ }
/*
* Compile the pattern.
return (0);
while (*p && ISSPACE(*p))
++p;
- if (*p)
- msg_warn("regexp map %s, line %d: ignoring extra text after IF",
- mapname, lineno);
+ if (*p) {
+ msg_warn("regexp map %s, line %d: ignoring extra text after"
+ " IF statement: \"%s\"", mapname, lineno, p);
+ msg_warn("regexp map %s, line %d: do not prepend whitespace"
+ " to statements between IF and ENDIF", mapname, lineno);
+ }
if ((expr = dict_regexp_compile_pat(mapname, lineno, &pattern)) == 0)
return (0);
if_rule = (DICT_REGEXP_IF_RULE *)
size_t _byte_len = EVENT_MASK_BYTES_NEEDED(bit_len); \
size_t _old_len = (mask)->data_len; \
(mask)->data = myrealloc((mask)->data, _byte_len); \
- memset((mask)->data + _old_len, 0, _byte_len - _old_len); \
+ if (_byte_len > _old_len) \
+ memset((mask)->data + _old_len, 0, _byte_len - _old_len); \
(mask)->data_len = _byte_len; \
} while (0)
#define EVENT_MASK_FREE(mask) myfree((mask)->data)
while (event_present < max_time
&& (event_timer_head.pred != &event_timer_head
|| memcmp(&zero_mask, &event_xmask,
- EVENT_MASK_BYTE_COUNT(&zero_mask)) != 0))
+ EVENT_MASK_BYTE_COUNT(&zero_mask)) != 0)) {
event_loop(1);
+#if (EVENTS_STYLE != EVENTS_STYLE_SELECT)
+ if (EVENT_MASK_BYTE_COUNT(&zero_mask)
+ != EVENT_MASK_BYTES_NEEDED(event_fdslots))
+ EVENT_MASK_REALLOC(&zero_mask, event_fdslots);
+#endif
+ }
#if (EVENTS_STYLE != EVENTS_STYLE_SELECT)
EVENT_MASK_FREE(&zero_mask);
#endif
event_request_timer(timer_event, "4 second", 4);
event_request_timer(timer_event, "2 first", 2);
event_request_timer(timer_event, "2 second", 2);
+ event_request_timer(timer_event, "1 first", 1);
+ event_request_timer(timer_event, "1 second", 1);
+ event_request_timer(timer_event, "0 first", 0);
+ event_request_timer(timer_event, "0 second", 0);
event_enable_read(fileno(stdin), echo, (char *) 0);
- for (;;)
- event_loop(-1);
+ event_drain(10);
+ exit(0);
}
#endif