From: Wietse Venema Date: Mon, 24 Mar 2008 05:00:00 +0000 (-0500) Subject: postfix-2.6-20080324 X-Git-Tag: v2.6.0-RC1~31 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=9bf0dc874135506265d5a8ebbe1dcb6b171c26fb;p=thirdparty%2Fpostfix.git postfix-2.6-20080324 --- diff --git a/postfix/.indent.pro b/postfix/.indent.pro index 73040aa46..4fad8789c 100644 --- a/postfix/.indent.pro +++ b/postfix/.indent.pro @@ -172,6 +172,7 @@ -TPIPE_STATE -TPLMYSQL -TPLPGSQL +-TPOSTMAP_KEY_STATE -TPOST_MAIL_STATE -TQMGR_ENTRY -TQMGR_FEEDBACK diff --git a/postfix/HISTORY b/postfix/HISTORY index b74f0828a..4f4b557c9 100644 --- a/postfix/HISTORY +++ b/postfix/HISTORY @@ -14383,3 +14383,23 @@ Apologies for any names omitted. 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. diff --git a/postfix/WISHLIST b/postfix/WISHLIST index 658a5c1ec..85633a603 100644 --- a/postfix/WISHLIST +++ b/postfix/WISHLIST @@ -39,9 +39,6 @@ Wish list: 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 @@ -106,10 +103,6 @@ Wish list: 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. diff --git a/postfix/html/postmap.1.html b/postfix/html/postmap.1.html index 0eafaf3d2..253bd7d69 100644 --- a/postfix/html/postmap.1.html +++ b/postfix/html/postmap.1.html @@ -10,23 +10,23 @@ POSTMAP(1) POSTMAP(1) postmap - Postfix lookup table management SYNOPSIS - postmap [-Nfinoprsvw] [-c config_dir] [-d key] [-q key] + postmap [-Nbfhimnoprsvw] [-c config_dir] [-d key] [-q key] [file_type:]file_name ... DESCRIPTION - The postmap(1) 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 postmap(1) 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: makemap file_type file_name < file_name 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. @@ -37,57 +37,98 @@ POSTMAP(1) POSTMAP(1) key whitespace value - o Empty lines and whitespace-only lines are ignored, - as are lines whose first non-whitespace character + o Empty lines and whitespace-only lines are ignored, + as are lines whose first non-whitespace character is a `#'. - o A logical line starts with non-whitespace text. A - line that starts with whitespace continues a logi- + o A logical line starts with non-whitespace text. A + line that starts with whitespace continues a logi- cal line. - The key and value 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 key and value 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 regexp: and pcre:. This resulted in + case text, such as regexp: and pcre:. This resulted in loss of information with $number substitutions. COMMAND-LINE ARGUMENTS + -b Enable message body query mode. When reading lookup + keys from standard input with "-q -", process the + input as if it is an email message in RFC 2822 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 body_checks(5) processing, enable MIME + parsing with -m. With this, the -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. + -c config_dir - Read the main.cf configuration file in the named + Read the main.cf configuration file in the named directory instead of the default configuration directory. - -d key Search the specified maps for key and remove one - entry per map. The exit status is zero when the + -d key Search the specified maps for key and remove one + entry per map. The exit status is zero when the requested information was found. If a key value of - 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. -f 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. - -i Incremental mode. Read entries from standard input + -h Enable message header query mode. When reading + lookup keys from standard input with "-q -", + 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. + + By default, this processing of header content ends + at the first non-header line. + + To simulate header_checks(5) processing, enable + MIME parsing with -m. With this, the -h 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. + + -i Incremental mode. Read entries from standard input and do not truncate an existing database. By default, postmap(1) creates a new database from the entries in file_name. + -m Enable MIME mode mode with "-b" and "-h". + + This feature is available in Postfix version 2.6 + and later. + -N Include the terminating null character that termi- nates lookup keys and values. By default, postmap(1) does whatever is the default for the @@ -126,66 +167,68 @@ POSTMAP(1) POSTMAP(1) -s Retrieve all database elements, and write one line of key value 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. -v Enable verbose logging for debugging purposes. Mul- - tiple -v options make the software increasingly + tiple -v options make the software increasingly verbose. -w 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: file_type - The database type. To find out what types are sup- + The database type. To find out what types are sup- ported, use the "postconf -m" command. The postmap(1) 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: - btree The output file is a btree file, named - file_name.db. This is available on systems + btree The output file is a btree file, named + file_name.db. This is available on systems with support for db databases. cdb The output consists of one file, named file_name.cdb. This is available on systems with support for cdb databases. - dbm The output consists of two files, named - file_name.pag and file_name.dir. This is - available on systems with support for dbm + dbm The output consists of two files, named + file_name.pag and file_name.dir. This is + available on systems with support for dbm databases. - hash The output file is a hashed file, named - file_name.db. This is available on systems + hash The output file is a hashed file, named + file_name.db. This is available on systems with support for db databases. - sdbm The output consists of two files, named - file_name.pag and file_name.dir. This is - available on systems with support for sdbm + sdbm The output consists of two files, named + file_name.pag and file_name.dir. This is + available on systems with support for sdbm databases. - When no file_type is specified, the software uses - the database type specified via the default_data- + When no file_type is specified, the software uses + the database type specified via the default_data- base_type configuration parameter. file_name - The name of the lookup table source file when + The name of the lookup table source file when rebuilding a database. DIAGNOSTICS - Problems are logged to the standard error stream and to - syslogd(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 + syslogd(8). No output means that no problems were + detected. Duplicate entries are skipped and are flagged with a warning. - postmap(1) terminates with zero exit status in case of - success (including successful "postmap -q" lookup) and + postmap(1) terminates with zero exit status in case of + success (including successful "postmap -q" lookup) and terminates with non-zero exit status in case of failure. ENVIRONMENT @@ -196,21 +239,21 @@ POSTMAP(1) POSTMAP(1) Enable verbose logging for debugging purposes. CONFIGURATION PARAMETERS - The following main.cf parameters are especially relevant + The following main.cf parameters are especially relevant to this program. The text below provides only a parameter - summary. See postconf(5) for more details including exam- + summary. See postconf(5) for more details including exam- ples. berkeley_db_create_buffer_size (16777216) - 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. berkeley_db_read_buffer_size (131072) - 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. config_directory (see 'postconf -d' output) - The default location of the Postfix main.cf and + The default location of the Postfix main.cf and master.cf configuration files. default_database_type (see 'postconf -d' output) @@ -221,8 +264,8 @@ POSTMAP(1) POSTMAP(1) The syslog facility of Postfix logging. syslog_name (postfix) - 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". SEE ALSO @@ -235,7 +278,7 @@ POSTMAP(1) POSTMAP(1) DATABASE_README, Postfix lookup table overview LICENSE - The Secure Mailer license must be distributed with this + The Secure Mailer license must be distributed with this software. AUTHOR(S) diff --git a/postfix/man/man1/postmap.1 b/postfix/man/man1/postmap.1 index cdc323138..dad48ab02 100644 --- a/postfix/man/man1/postmap.1 +++ b/postfix/man/man1/postmap.1 @@ -9,7 +9,7 @@ Postfix lookup table management .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 @@ -67,6 +67,22 @@ information with $\fInumber\fR substitutions. .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. @@ -84,10 +100,30 @@ a table. 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 @@ -123,6 +159,7 @@ Retrieve all database elements, and write one line of \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 diff --git a/postfix/proto/postconf.proto b/postfix/proto/postconf.proto index 1f66c1a47..012da4d88 100644 --- a/postfix/proto/postconf.proto +++ b/postfix/proto/postconf.proto @@ -9157,7 +9157,7 @@ server uses for TLS encrypted SMTP sessions.

This feature is available in Postfix 2.2 and later.

-%PARAM smtp_generic_maps empty +%PARAM smtp_generic_maps

Optional lookup tables that perform address rewriting in the SMTP client, typically to transform a locally valid address into @@ -9172,7 +9172,7 @@ STANDARD_CONFIGURATION_README documents.

This feature is available in Postfix 2.2 and later.

-%PARAM message_reject_characters empty +%PARAM message_reject_characters

The set of characters that Postfix will reject in message content. The usual C-like escape sequences are recognized: \a @@ -9187,7 +9187,7 @@ message_reject_characters = \0

This feature is available in Postfix 2.3 and later.

-%PARAM message_strip_characters empty +%PARAM message_strip_characters

The set of characters that Postfix will remove from message content. The usual C-like escape sequences are recognized: \a @@ -9252,7 +9252,7 @@ precision.

This feature is available in Postfix 2.3 and later.

-%PARAM bounce_template_file empty +%PARAM bounce_template_file

Pathname of a configuration file with bounce message templates. These override the built-in templates of delivery status notification @@ -9267,7 +9267,7 @@ is placed into the Postfix configuration directory.

This feature is available in Postfix 2.3 and later.

-%PARAM sender_dependent_relayhost_maps empty +%PARAM sender_dependent_relayhost_maps

A sender-dependent override for the global relayhost parameter setting. The tables are searched by the envelope sender address and @@ -10266,7 +10266,7 @@ smtp_tls_fingerprint_cert_match =

This feature is available in Postfix 2.3 and later.

-%PARAM smtpd_milters empty +%PARAM smtpd_milters

A list of Milter (mail filter) applications for new mail that arrives via the Postfix smtpd(8) server. See the MILTER_README @@ -10274,7 +10274,7 @@ document for details.

This feature is available in Postfix 2.3 and later.

-%PARAM non_smtpd_milters empty +%PARAM non_smtpd_milters

A list of Milter (mail filter) applications for new mail that does not arrive via the Postfix smtpd(8) server. This includes local diff --git a/postfix/src/global/mail_version.h b/postfix/src/global/mail_version.h index 8dc0f388b..2286261ab 100644 --- a/postfix/src/global/mail_version.h +++ b/postfix/src/global/mail_version.h @@ -20,7 +20,7 @@ * 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 diff --git a/postfix/src/postmap/Makefile.in b/postfix/src/postmap/Makefile.in index 3ff41f672..8d876df71 100644 --- a/postfix/src/postmap/Makefile.in +++ b/postfix/src/postmap/Makefile.in @@ -84,17 +84,20 @@ depend: $(MAKES) 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 diff --git a/postfix/src/postmap/postmap.c b/postfix/src/postmap/postmap.c index f2f28e0b5..3138c9942 100644 --- a/postfix/src/postmap/postmap.c +++ b/postfix/src/postmap/postmap.c @@ -5,7 +5,7 @@ /* 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 @@ -57,6 +57,22 @@ /* 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. @@ -74,10 +90,30 @@ /* 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 @@ -113,6 +149,7 @@ /* \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 @@ -251,13 +288,36 @@ #include #include #include +#include +#include /* 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 */ @@ -367,9 +427,71 @@ static void postmap(char *map_type, char *path_name, int postmap_flags, 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; @@ -396,24 +518,71 @@ static int postmap_queries(VSTREAM *in, char **maps, const int map_count, * 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); @@ -619,7 +788,7 @@ int main(int argc, char **argv) /* * 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]); @@ -628,6 +797,9 @@ int main(int argc, char **argv) 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"); @@ -640,9 +812,15 @@ int main(int argc, char **argv) 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; @@ -680,6 +858,9 @@ int main(int argc, char **argv) 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 @@ -708,7 +889,7 @@ int main(int argc, char **argv) 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, diff --git a/postfix/src/util/dict_pcre.c b/postfix/src/util/dict_pcre.c index 1ccb67706..2d6d018a2 100644 --- a/postfix/src/util/dict_pcre.c +++ b/postfix/src/util/dict_pcre.c @@ -722,9 +722,12 @@ static DICT_PCRE_RULE *dict_pcre_parse_rule(const char *mapname, int lineno, */ 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. diff --git a/postfix/src/util/dict_regexp.c b/postfix/src/util/dict_regexp.c index c1a27479a..f3cb1f9ba 100644 --- a/postfix/src/util/dict_regexp.c +++ b/postfix/src/util/dict_regexp.c @@ -683,9 +683,12 @@ static DICT_REGEXP_RULE *dict_regexp_parseline(const char *mapname, int lineno, 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 *) diff --git a/postfix/src/util/events.c b/postfix/src/util/events.c index 0aa9eee52..288ad695f 100644 --- a/postfix/src/util/events.c +++ b/postfix/src/util/events.c @@ -205,7 +205,8 @@ typedef struct { 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) @@ -633,8 +634,14 @@ void event_drain(int time_limit) 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 @@ -1133,9 +1140,13 @@ int main(int argc, char **argv) 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