diff --git a/postfix/HISTORY b/postfix/HISTORY
index 3bfe82944..b7972bc49 100644
--- a/postfix/HISTORY
+++ b/postfix/HISTORY
@@ -5495,10 +5495,11 @@ Apologies for any names omitted.
20011010-14
- Replaced the internal protocols by (name,value) attribute
- lists. This gives better error detection when we start
- making changes to internal protocols, and allows new
- attributes to be introduced without breaking protocols.
+ Replaced the ugly mail_print() and mail-scan() protocols
+ by (name,value) attribute lists. This gives better error
+ detection when we start making changes to internal protocols,
+ and allows new attributes to be introduced without breaking
+ everything immediately.
20011015
@@ -5529,17 +5530,32 @@ Apologies for any names omitted.
with fractional hours (-03-30 instead of -0330). Fix by
Chad House, greyfirst.ca.
+20011102
+
+ Feature: new -f option to postmap and postalias (do not
+ lowercase the lookup key while creating a table). Files:
+ util/dict.h postmap/postmap.c postalias/postalias.c.
+
+ Code cleanup: simplified the attribute print/scan routines,
+ and removed the never-used support for sending and receiving
+ integer arrays and string arrays. Files: util/attr_print.c,
+ util/attr_scan.c.
+
+ Bugfix: qmqpd could read past the end of a string while
+ looking for the VERP magic token in the envelope sender
+ address. File: qmqpd/qmqpd.c.
+
Open problems:
Medium: need in-process caching for map lookups.
- Minor: The $process_id_directory setting is not used anywhere
+ Low: The $process_id_directory setting is not used anywhere
in Postfix. Problem reported by Michael Smith, texas.net.
This should either be documented, or better, the code should
warn about attempts to set a read-only parameter.
- Medium: address rewriting should be on/off configurable
- for envelopes and/or headers.
+ Medium: make address rewriting on/off configurable for
+ envelopes and/or headers.
Medium: smtpd access maps don't understand the recipient
delimiter setting.
diff --git a/postfix/PORTING b/postfix/PORTING
index 2a494420b..672eff62e 100644
--- a/postfix/PORTING
+++ b/postfix/PORTING
@@ -1,9 +1,10 @@
In order to port software to a new platform:
-- Choose a SYSTEMTYPE name for the new system. Please use a name
-that includes the major version of the operating system (such as
-SUNOS4 or LINUX2), so that different releases of the same system
-can be supported without confusion.
+- Each system type needs to be identified by a unique name. Examples:
+SUNOS5, FREEBSD4, and so on. Choose a SYSTEMTYPE name for the new
+system. You must use a name that includes at least the major version
+of the operating system (such as SUNOS4 or LINUX2), so that different
+releases of the same system can be supported without confusion.
- Add a case statement to the "makedefs" shell script in the
top-level directory that recognizes the new system reliably, and
diff --git a/postfix/RELEASE_NOTES b/postfix/RELEASE_NOTES
index e7a70b177..d28737876 100644
--- a/postfix/RELEASE_NOTES
+++ b/postfix/RELEASE_NOTES
@@ -1,3 +1,20 @@
+This release introduces a negligible amount of features and is all
+about revision of Postfix internals. With more than 70 pages of
+context diffs compared to the previous snapshot, this release is
+a baseline for upcoming feature changes.
+
+Major changes with snapshot-20011102
+====================================
+
+The protocol between Postfix daemons was replaced by something that
+can be extended without breaking everything after each change, and
+that can also be used to talk to non-Postfix programs. The format
+of the protocols is described in src/util/attr_scan.c.
+
+In header/body_check files, REJECT can now be followed by text that
+is sent to the originator. That feature was stuck waiting for the
+internal protocol revision.
+
Incompatible changes with snapshot-20011008
===========================================
@@ -34,9 +51,9 @@ parameter. Postfix refuses to accept mail when permit_mx_backup
is used while auth_mx_backup_networks is not configured. [This
change was undone with a later release].
-The protocol between Postfix master and child processes has changed.
You must stop and start Postfix in order to switch between Snapshot
-20010808 and releases that implement the older protocol.
+20010808 and earlier releases. The protocol between Postfix master
+and child processes has changed.
Major changes with snapshot-20010808
====================================
diff --git a/postfix/html/postalias.1.html b/postfix/html/postalias.1.html
index 8fbe2ce8c..b1d6cf7d3 100644
--- a/postfix/html/postalias.1.html
+++ b/postfix/html/postalias.1.html
@@ -6,7 +6,7 @@ POSTALIAS(1) POSTALIAS(1)
postalias - Postfix alias database maintenance
SYNOPSIS
- postalias [-Ninrvw] [-c config_dir] [-d key] [-q key]
+ postalias [-Nfinrvw] [-c config_dir] [-d key] [-q key]
[file_type:]file_name ...
DESCRIPTION
@@ -42,35 +42,38 @@ POSTALIAS(1) POSTALIAS(1)
status is zero when at least one of the requested
keys was found.
- -i Incremental mode. Read entries from standard input
+ -f Do not fold the lookup key to lower case while cre-
+ ating a map.
+
+ -i Incremental mode. Read entries from standard input
and do not truncate an existing database. By
- default, postalias creates a new database from the
+ default, postalias creates a new database from the
entries in file_name.
- -n Don't include the terminating null character that
- terminates lookup keys and values. By default,
- Postfix does whatever is the default for the host
+ -n Don't include the terminating null character that
+ terminates lookup keys and values. By default,
+ Postfix does whatever is the default for the host
operating system.
- -q key Search the specified maps for key and print the
- first value found on the standard output stream.
+ -q key Search the specified maps for key and print the
+ first value found on the standard output stream.
The exit status is zero when the requested informa-
tion was found.
If a key value of - is specified, the program reads
- key values from the standard input stream and
- prints one line of key: value output for each key
- that was found. The exit status is zero when at
+ key values from the standard input stream and
+ prints one line of key: value output for each key
+ that was found. The exit status is zero when at
least one of the requested keys was found.
- -r When updating a table, do not warn about duplicate
+ -r When updating a table, do not warn about duplicate
entries; silently replace them.
-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 warn about duplicate
+ -w When updating a table, do not warn about duplicate
entries; silently ignore them.
Arguments:
@@ -78,35 +81,35 @@ POSTALIAS(1) POSTALIAS(1)
file_type
The type of database to be produced.
- btree The output is a btree file, named
- file_name.db. This is available only on
- systems with support for db databases.
-
- dbm The output consists of two files, named
- file_name.pag and file_name.dir. This is
- available only on systems with support for
- dbm databases.
-
- hash The output is a hashed file, named
+ btree The output is a btree file, named
file_name.db. This is available only on
systems with support for db databases.
- When no file_type is specified, the software uses
- the database type specified via the database_type
- configuration parameter. The default value for
+ dbm The output consists of two files, named
+ file_name.pag and file_name.dir. This is
+ available only on systems with support for
+ dbm databases.
+
+ hash The output is a hashed file, named
+ file_name.db. This is available only on
+ systems with support for db databases.
+
+ When no file_type is specified, the software uses
+ the database type specified via the database_type
+ configuration parameter. The default value for
this parameter depends on the host environment.
file_name
- The name of the alias database source file when
+ The name of the alias database source file when
rebuilding a database.
DIAGNOSTICS
- Problems are logged to the standard error stream. No out-
+ Problems are logged to the standard error stream. No out-
put means no problems were detected. Duplicate entries are
skipped and are flagged with a warning.
postalias terminates with zero exit status in case of suc-
- cess (including successful postmap -q lookup) and termi-
+ cess (including successful postmap -q lookup) and termi-
nates with non-zero exit status in case of failure.
ENVIRONMENT
@@ -117,12 +120,12 @@ POSTALIAS(1) POSTALIAS(1)
Enable verbose logging for debugging purposes.
CONFIGURATION PARAMETERS
- The following main.cf parameters are especially relevant
- to this program. See the Postfix main.cf file for syntax
+ The following main.cf parameters are especially relevant
+ to this program. See the Postfix main.cf file for syntax
details and for default values.
database_type
- Default alias database type. On many UNIX systems,
+ Default alias database type. On many UNIX systems,
the default type is either dbm or hash.
STANDARDS
@@ -133,7 +136,7 @@ POSTALIAS(1) POSTALIAS(1)
sendmail(1) mail posting and compatibility interface.
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/html/postmap.1.html b/postfix/html/postmap.1.html
index 9a43c2bbe..711f5d38b 100644
--- a/postfix/html/postmap.1.html
+++ b/postfix/html/postmap.1.html
@@ -6,7 +6,7 @@ POSTMAP(1) POSTMAP(1)
postmap - Postfix lookup table management
SYNOPSIS
- postmap [-Ninrvw] [-c config_dir] [-d key] [-q key]
+ postmap [-Nfinrvw] [-c config_dir] [-d key] [-q key]
[file_type:]file_name ...
DESCRIPTION
@@ -61,35 +61,38 @@ POSTMAP(1) POSTMAP(1)
status is zero when at least one of the requested
keys was found.
- -i Incremental mode. Read entries from standard input
+ -f Do not fold the lookup key to lower case while cre-
+ ating a map.
+
+ -i Incremental mode. Read entries from standard input
and do not truncate an existing database. By
- default, postmap creates a new database from the
+ default, postmap creates a new database from the
entries in file_name.
- -n Don't include the terminating null character that
- terminates lookup keys and values. By default,
- Postfix does whatever is the default for the host
+ -n Don't include the terminating null character that
+ terminates lookup keys and values. By default,
+ Postfix does whatever is the default for the host
operating system.
- -q key Search the specified maps for key and print the
- first value found on the standard output stream.
+ -q key Search the specified maps for key and print the
+ first value found on the standard output stream.
The exit status is zero when the requested informa-
tion was found.
If a key value of - is specified, the program reads
- key values from the standard input stream and
- prints one line of key value output for each key
- that was found. The exit status is zero when at
+ key values from the standard input stream and
+ prints one line of key value output for each key
+ that was found. The exit status is zero when at
least one of the requested keys was found.
- -r When updating a table, do not warn about duplicate
+ -r When updating a table, do not warn about duplicate
entries; silently replace them.
-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 warn about duplicate
+ -w When updating a table, do not warn about duplicate
entries; silently ignore them.
Arguments:
@@ -97,25 +100,25 @@ POSTMAP(1) POSTMAP(1)
file_type
The type of database to be produced.
- btree The output file is a btree file, named
- file_name.db. This is available only on
- systems with support for db databases.
-
- dbm The output consists of two files, named
- file_name.pag and file_name.dir. This is
- available only on systems with support for
- dbm databases.
-
- hash The output file is a hashed file, named
+ btree The output file is a btree file, named
file_name.db. This is available only on
systems with support for db databases.
- When no file_type is specified, the software uses
- the database type specified via the database_type
+ dbm The output consists of two files, named
+ file_name.pag and file_name.dir. This is
+ available only on systems with support for
+ dbm databases.
+
+ hash The output file is a hashed file, named
+ file_name.db. This is available only on
+ systems with support for db databases.
+
+ When no file_type is specified, the software uses
+ the database type specified via the database_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
@@ -123,8 +126,8 @@ POSTMAP(1) POSTMAP(1)
stream. No output means no problems. Duplicate entries are
skipped and are flagged with a warning.
- postmap terminates with zero exit status in case of suc-
- cess (including successful postmap -q lookup) and termi-
+ postmap terminates with zero exit status in case of suc-
+ cess (including successful postmap -q lookup) and termi-
nates with non-zero exit status in case of failure.
ENVIRONMENT
@@ -136,12 +139,12 @@ POSTMAP(1) POSTMAP(1)
CONFIGURATION PARAMETERS
database_type
- Default output database type. On many UNIX sys-
- tems, the default database type is either hash or
+ Default output database type. On many UNIX sys-
+ tems, the default database type is either hash or
dbm.
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/postalias.1 b/postfix/man/man1/postalias.1
index ac7da6d2e..c7ec54dd6 100644
--- a/postfix/man/man1/postalias.1
+++ b/postfix/man/man1/postalias.1
@@ -9,7 +9,7 @@ Postfix alias database maintenance
.na
.nf
.fi
-\fBpostalias\fR [\fB-Ninrvw\fR] [\fB-c \fIconfig_dir\fR]
+\fBpostalias\fR [\fB-Nfinrvw\fR] [\fB-c \fIconfig_dir\fR]
[\fB-d \fIkey\fR] [\fB-q \fIkey\fR]
[\fIfile_type\fR:]\fIfile_name\fR ...
.SH DESCRIPTION
@@ -40,6 +40,8 @@ The exit status is zero when the requested information was found.
If a key value of \fB-\fR is specified, the program reads key
values from the standard input stream. The exit status is zero
when at least one of the requested keys was found.
+.IP \fB-f\fR
+Do not fold the lookup key to lower case while creating a map.
.IP \fB-i\fR
Incremental mode. Read entries from standard input and do not
truncate an existing database. By default, \fBpostalias\fR creates
diff --git a/postfix/man/man1/postmap.1 b/postfix/man/man1/postmap.1
index 83f8cd424..b3d1e791f 100644
--- a/postfix/man/man1/postmap.1
+++ b/postfix/man/man1/postmap.1
@@ -9,8 +9,9 @@ Postfix lookup table management
.na
.nf
.fi
-\fBpostmap\fR [\fB-Ninrvw\fR] [\fB-c \fIconfig_dir\fR] [\fB-d \fIkey\fR]
-[\fB-q \fIkey\fR] [\fIfile_type\fR:]\fIfile_name\fR ...
+\fBpostmap\fR [\fB-Nfinrvw\fR] [\fB-c \fIconfig_dir\fR]
+[\fB-d \fIkey\fR] [\fB-q \fIkey\fR]
+[\fIfile_type\fR:]\fIfile_name\fR ...
.SH DESCRIPTION
.ad
.fi
@@ -58,6 +59,8 @@ The exit status is zero when the requested information was found.
If a key value of \fB-\fR is specified, the program reads key
values from the standard input stream. The exit status is zero
when at least one of the requested keys was found.
+.IP \fB-f\fR
+Do not fold the lookup key to lower case while creating a map.
.IP \fB-i\fR
Incremental mode. Read entries from standard input and do not
truncate an existing database. By default, \fBpostmap\fR creates
diff --git a/postfix/src/bounce/Makefile.in b/postfix/src/bounce/Makefile.in
index e3769be84..66066c233 100644
--- a/postfix/src/bounce/Makefile.in
+++ b/postfix/src/bounce/Makefile.in
@@ -66,7 +66,6 @@ bounce.o: ../../include/stringops.h
bounce.o: ../../include/mail_proto.h
bounce.o: ../../include/iostuff.h
bounce.o: ../../include/attr.h
-bounce.o: ../../include/htable.h
bounce.o: ../../include/mail_queue.h
bounce.o: ../../include/mail_params.h
bounce.o: ../../include/mail_conf.h
diff --git a/postfix/src/bounce/bounce.c b/postfix/src/bounce/bounce.c
index 03a137dad..3cb98cc00 100644
--- a/postfix/src/bounce/bounce.c
+++ b/postfix/src/bounce/bounce.c
@@ -299,7 +299,7 @@ static void bounce_service(VSTREAM *client, char *service_name, char **argv)
#define REALLY_BOUNCE 1
#define JUST_WARN 0
- if (attr_scan(client, ATTR_FLAG_MISSING | ATTR_FLAG_EXTRA | ATTR_FLAG_MORE,
+ if (attr_scan(client, ATTR_FLAG_STRICT | ATTR_FLAG_MORE,
ATTR_TYPE_NUM, MAIL_ATTR_NREQ, &command, 0) != 1) {
msg_warn("malformed request");
status = -1;
diff --git a/postfix/src/cleanup/Makefile.in b/postfix/src/cleanup/Makefile.in
index 46cb770ca..cec834caa 100644
--- a/postfix/src/cleanup/Makefile.in
+++ b/postfix/src/cleanup/Makefile.in
@@ -73,7 +73,6 @@ cleanup.o: ../../include/cleanup_user.h
cleanup.o: ../../include/mail_proto.h
cleanup.o: ../../include/iostuff.h
cleanup.o: ../../include/attr.h
-cleanup.o: ../../include/htable.h
cleanup.o: ../../include/mail_params.h
cleanup.o: ../../include/record.h
cleanup.o: ../../include/rec_type.h
@@ -96,7 +95,6 @@ cleanup_api.o: ../../include/vstream.h
cleanup_api.o: ../../include/mail_proto.h
cleanup_api.o: ../../include/iostuff.h
cleanup_api.o: ../../include/attr.h
-cleanup_api.o: ../../include/htable.h
cleanup_api.o: ../../include/bounce.h
cleanup_api.o: ../../include/mail_params.h
cleanup_api.o: ../../include/mail_stream.h
diff --git a/postfix/src/cleanup/cleanup.c b/postfix/src/cleanup/cleanup.c
index acdde16fd..28185986f 100644
--- a/postfix/src/cleanup/cleanup.c
+++ b/postfix/src/cleanup/cleanup.c
@@ -194,7 +194,7 @@ static void cleanup_service(VSTREAM *src, char *unused_service, char **argv)
attr_print(src, ATTR_FLAG_NONE,
ATTR_TYPE_STR, MAIL_ATTR_QUEUEID, state->queue_id,
ATTR_TYPE_END);
- if (attr_scan(src, ATTR_FLAG_MISSING | ATTR_FLAG_EXTRA,
+ if (attr_scan(src, ATTR_FLAG_STRICT,
ATTR_TYPE_NUM, MAIL_ATTR_FLAGS, &flags) != 1) {
state->errs |= CLEANUP_STAT_BAD;
flags = 0;
diff --git a/postfix/src/cleanup/cleanup_api.c b/postfix/src/cleanup/cleanup_api.c
index f361f16e1..b2e88eb2a 100644
--- a/postfix/src/cleanup/cleanup_api.c
+++ b/postfix/src/cleanup/cleanup_api.c
@@ -232,8 +232,8 @@ int cleanup_flush(CLEANUP_STATE *state)
if (bounce_append(BOUNCE_FLAG_CLEAN, state->queue_id,
state->recip ? state->recip : "unknown",
"cleanup", state->time,
- "Message processing aborted: %s", state->reason ?
- state->reason : cleanup_strerror(state->errs)) == 0
+ "%s", state->reason ? state->reason :
+ cleanup_strerror(state->errs)) == 0
&& bounce_flush(BOUNCE_FLAG_CLEAN, MAIL_QUEUE_INCOMING,
state->queue_id, state->sender) == 0) {
state->errs = 0;
diff --git a/postfix/src/cleanup/cleanup_message.c b/postfix/src/cleanup/cleanup_message.c
index e1742a760..875ebb16b 100644
--- a/postfix/src/cleanup/cleanup_message.c
+++ b/postfix/src/cleanup/cleanup_message.c
@@ -268,9 +268,12 @@ static int cleanup_check_reject(CLEANUP_STATE *state, const char *value)
* routine that takes an error code and an optional text.
*/
if (strncasecmp(value, "REJECT", reason - value) == 0) {
- if (state->reason == 0)
+ if (state->reason == 0) {
+ while (*reason && ISSPACE(*reason))
+ reason++;
state->reason = mystrdup(*reason ? reason :
cleanup_strerror(CLEANUP_STAT_CONT));
+ }
state->errs |= CLEANUP_STAT_CONT;
return (1);
} else {
diff --git a/postfix/src/flush/flush.c b/postfix/src/flush/flush.c
index cf365545f..9e3499cd0 100644
--- a/postfix/src/flush/flush.c
+++ b/postfix/src/flush/flush.c
@@ -543,13 +543,13 @@ static void flush_service(VSTREAM *client_stream, char *unused_service,
if (peekfd(vstream_fileno(client_stream)) <= 2 ?
(vstring_get_null(request, client_stream) != VSTREAM_EOF) :
(attr_scan(client_stream,
- ATTR_FLAG_MORE | ATTR_FLAG_EXTRA | ATTR_FLAG_MISSING,
+ ATTR_FLAG_MORE | ATTR_FLAG_STRICT,
ATTR_TYPE_STR, MAIL_ATTR_REQ, request,
ATTR_TYPE_END) == 1)) {
if (STREQ(STR(request), FLUSH_REQ_ADD)) {
site = vstring_alloc(10);
queue_id = vstring_alloc(10);
- if (attr_scan(client_stream, ATTR_FLAG_MISSING | ATTR_FLAG_EXTRA,
+ if (attr_scan(client_stream, ATTR_FLAG_STRICT,
ATTR_TYPE_STR, MAIL_ATTR_SITE, site,
ATTR_TYPE_STR, MAIL_ATTR_QUEUEID, queue_id,
ATTR_TYPE_END) == 2
@@ -560,7 +560,7 @@ static void flush_service(VSTREAM *client_stream, char *unused_service,
ATTR_TYPE_END);
} else if (STREQ(STR(request), FLUSH_REQ_SEND)) {
site = vstring_alloc(10);
- if (attr_scan(client_stream, ATTR_FLAG_MISSING | ATTR_FLAG_EXTRA,
+ if (attr_scan(client_stream, ATTR_FLAG_STRICT,
ATTR_TYPE_STR, MAIL_ATTR_SITE, site,
ATTR_TYPE_END) == 1)
status = flush_send_service(lowercase(STR(site)));
diff --git a/postfix/src/global/Makefile.in b/postfix/src/global/Makefile.in
index 0e0da10bf..c7548ebd1 100644
--- a/postfix/src/global/Makefile.in
+++ b/postfix/src/global/Makefile.in
@@ -255,7 +255,6 @@ abounce.o: ../../include/vbuf.h
abounce.o: mail_proto.h
abounce.o: ../../include/iostuff.h
abounce.o: ../../include/attr.h
-abounce.o: ../../include/htable.h
abounce.o: abounce.h
abounce.o: bounce.h
been_here.o: been_here.c
@@ -267,15 +266,6 @@ been_here.o: ../../include/vstring.h
been_here.o: ../../include/vbuf.h
been_here.o: ../../include/stringops.h
been_here.o: been_here.h
-been_here_level.o: been_here_level.c
-been_here_level.o: ../../include/sys_defs.h
-been_here_level.o: ../../include/msg.h
-been_here_level.o: ../../include/mymalloc.h
-been_here_level.o: ../../include/htable.h
-been_here_level.o: ../../include/vstring.h
-been_here_level.o: ../../include/vbuf.h
-been_here_level.o: ../../include/stringops.h
-been_here_level.o: been_here.h
bounce.o: bounce.c
bounce.o: ../../include/sys_defs.h
bounce.o: ../../include/msg.h
@@ -286,7 +276,6 @@ bounce.o: mail_proto.h
bounce.o: ../../include/vstream.h
bounce.o: ../../include/iostuff.h
bounce.o: ../../include/attr.h
-bounce.o: ../../include/htable.h
bounce.o: defer.h
bounce.o: bounce.h
bounce_log.o: bounce_log.c
@@ -322,7 +311,6 @@ clnt_stream.o: ../../include/events.h
clnt_stream.o: ../../include/iostuff.h
clnt_stream.o: mail_proto.h
clnt_stream.o: ../../include/attr.h
-clnt_stream.o: ../../include/htable.h
clnt_stream.o: mail_params.h
clnt_stream.o: clnt_stream.h
debug_peer.o: debug_peer.c
@@ -347,7 +335,6 @@ defer.o: ../../include/vstream.h
defer.o: mail_proto.h
defer.o: ../../include/iostuff.h
defer.o: ../../include/attr.h
-defer.o: ../../include/htable.h
defer.o: flush_clnt.h
defer.o: bounce.h
defer.o: defer.h
@@ -383,7 +370,6 @@ deliver_pass.o: recipient_list.h
deliver_pass.o: mail_proto.h
deliver_pass.o: ../../include/iostuff.h
deliver_pass.o: ../../include/attr.h
-deliver_pass.o: ../../include/htable.h
deliver_request.o: deliver_request.c
deliver_request.o: ../../include/sys_defs.h
deliver_request.o: ../../include/msg.h
@@ -396,7 +382,6 @@ deliver_request.o: ../../include/myflock.h
deliver_request.o: mail_queue.h
deliver_request.o: mail_proto.h
deliver_request.o: ../../include/attr.h
-deliver_request.o: ../../include/htable.h
deliver_request.o: mail_open_ok.h
deliver_request.o: recipient_list.h
deliver_request.o: deliver_request.h
@@ -441,7 +426,6 @@ flush_clnt.o: ../../include/vbuf.h
flush_clnt.o: mail_proto.h
flush_clnt.o: ../../include/iostuff.h
flush_clnt.o: ../../include/attr.h
-flush_clnt.o: ../../include/htable.h
flush_clnt.o: mail_flush.h
flush_clnt.o: flush_clnt.h
flush_clnt.o: mail_params.h
@@ -507,16 +491,6 @@ mail_command_client.o: ../../include/vbuf.h
mail_command_client.o: mail_proto.h
mail_command_client.o: ../../include/iostuff.h
mail_command_client.o: ../../include/attr.h
-mail_command_client.o: ../../include/htable.h
-mail_command_read.o: mail_command_read.c
-mail_command_read.o: ../../include/sys_defs.h
-mail_command_read.o: ../../include/vstring.h
-mail_command_read.o: ../../include/vbuf.h
-mail_command_read.o: ../../include/vstream.h
-mail_command_read.o: mail_proto.h
-mail_command_read.o: ../../include/iostuff.h
-mail_command_read.o: ../../include/attr.h
-mail_command_read.o: ../../include/htable.h
mail_command_server.o: mail_command_server.c
mail_command_server.o: ../../include/sys_defs.h
mail_command_server.o: ../../include/vstream.h
@@ -524,15 +498,6 @@ mail_command_server.o: ../../include/vbuf.h
mail_command_server.o: mail_proto.h
mail_command_server.o: ../../include/iostuff.h
mail_command_server.o: ../../include/attr.h
-mail_command_server.o: ../../include/htable.h
-mail_command_write.o: mail_command_write.c
-mail_command_write.o: ../../include/sys_defs.h
-mail_command_write.o: ../../include/vstream.h
-mail_command_write.o: ../../include/vbuf.h
-mail_command_write.o: mail_proto.h
-mail_command_write.o: ../../include/iostuff.h
-mail_command_write.o: ../../include/attr.h
-mail_command_write.o: ../../include/htable.h
mail_conf.o: mail_conf.c
mail_conf.o: ../../include/sys_defs.h
mail_conf.o: ../../include/msg.h
@@ -599,7 +564,6 @@ mail_connect.o: ../../include/vstring.h
mail_connect.o: timed_ipc.h
mail_connect.o: mail_proto.h
mail_connect.o: ../../include/attr.h
-mail_connect.o: ../../include/htable.h
mail_copy.o: mail_copy.c
mail_copy.o: ../../include/sys_defs.h
mail_copy.o: ../../include/msg.h
@@ -633,7 +597,6 @@ mail_flush.o: ../../include/vstream.h
mail_flush.o: ../../include/vbuf.h
mail_flush.o: ../../include/iostuff.h
mail_flush.o: ../../include/attr.h
-mail_flush.o: ../../include/htable.h
mail_flush.o: mail_flush.h
mail_open_ok.o: mail_open_ok.c
mail_open_ok.o: ../../include/sys_defs.h
@@ -660,7 +623,6 @@ mail_params.o: mail_proto.h
mail_params.o: ../../include/vstream.h
mail_params.o: ../../include/iostuff.h
mail_params.o: ../../include/attr.h
-mail_params.o: ../../include/htable.h
mail_params.o: verp_sender.h
mail_params.o: mail_params.h
mail_pathname.o: mail_pathname.c
@@ -672,17 +634,6 @@ mail_pathname.o: mail_proto.h
mail_pathname.o: ../../include/vstream.h
mail_pathname.o: ../../include/iostuff.h
mail_pathname.o: ../../include/attr.h
-mail_pathname.o: ../../include/htable.h
-mail_print.o: mail_print.c
-mail_print.o: ../../include/sys_defs.h
-mail_print.o: ../../include/msg.h
-mail_print.o: ../../include/mymalloc.h
-mail_print.o: ../../include/vstream.h
-mail_print.o: ../../include/vbuf.h
-mail_print.o: mail_proto.h
-mail_print.o: ../../include/iostuff.h
-mail_print.o: ../../include/attr.h
-mail_print.o: ../../include/htable.h
mail_queue.o: mail_queue.c
mail_queue.o: ../../include/sys_defs.h
mail_queue.o: ../../include/msg.h
@@ -708,18 +659,6 @@ mail_run.o: ../../include/vbuf.h
mail_run.o: ../../include/mymalloc.h
mail_run.o: mail_params.h
mail_run.o: mail_run.h
-mail_scan.o: mail_scan.c
-mail_scan.o: ../../include/sys_defs.h
-mail_scan.o: ../../include/msg.h
-mail_scan.o: ../../include/vstring.h
-mail_scan.o: ../../include/vbuf.h
-mail_scan.o: ../../include/vstream.h
-mail_scan.o: ../../include/vstring_vstream.h
-mail_scan.o: ../../include/mymalloc.h
-mail_scan.o: mail_proto.h
-mail_scan.o: ../../include/iostuff.h
-mail_scan.o: ../../include/attr.h
-mail_scan.o: ../../include/htable.h
mail_scan_dir.o: mail_scan_dir.c
mail_scan_dir.o: ../../include/sys_defs.h
mail_scan_dir.o: ../../include/scan_dir.h
@@ -737,7 +676,6 @@ mail_stream.o: cleanup_user.h
mail_stream.o: mail_proto.h
mail_stream.o: ../../include/iostuff.h
mail_stream.o: ../../include/attr.h
-mail_stream.o: ../../include/htable.h
mail_stream.o: mail_queue.h
mail_stream.o: opened.h
mail_stream.o: mail_params.h
@@ -761,7 +699,6 @@ mail_trigger.o: mail_proto.h
mail_trigger.o: ../../include/vstream.h
mail_trigger.o: ../../include/vbuf.h
mail_trigger.o: ../../include/attr.h
-mail_trigger.o: ../../include/htable.h
mail_version.o: mail_version.c
maps.o: maps.c
maps.o: ../../include/sys_defs.h
@@ -922,7 +859,6 @@ post_mail.o: rec_type.h
post_mail.o: mail_proto.h
post_mail.o: ../../include/iostuff.h
post_mail.o: ../../include/attr.h
-post_mail.o: ../../include/htable.h
post_mail.o: cleanup_user.h
post_mail.o: post_mail.h
post_mail.o: mail_date.h
@@ -991,7 +927,6 @@ resolve_clnt.o: ../../include/events.h
resolve_clnt.o: ../../include/iostuff.h
resolve_clnt.o: mail_proto.h
resolve_clnt.o: ../../include/attr.h
-resolve_clnt.o: ../../include/htable.h
resolve_clnt.o: mail_params.h
resolve_clnt.o: clnt_stream.h
resolve_clnt.o: resolve_clnt.h
@@ -1015,7 +950,6 @@ rewrite_clnt.o: ../../include/iostuff.h
rewrite_clnt.o: quote_822_local.h
rewrite_clnt.o: mail_proto.h
rewrite_clnt.o: ../../include/attr.h
-rewrite_clnt.o: ../../include/htable.h
rewrite_clnt.o: mail_params.h
rewrite_clnt.o: clnt_stream.h
rewrite_clnt.o: rewrite_clnt.h
diff --git a/postfix/src/global/abounce.c b/postfix/src/global/abounce.c
index f688864fa..5cacccf5e 100644
--- a/postfix/src/global/abounce.c
+++ b/postfix/src/global/abounce.c
@@ -171,7 +171,7 @@ static void abounce_event(int unused_event, char *context)
int status;
event_disable_readwrite(vstream_fileno(ap->fp));
- abounce_done(ap, attr_scan(ap->fp, ATTR_FLAG_MISSING | ATTR_FLAG_EXTRA,
+ abounce_done(ap, attr_scan(ap->fp, ATTR_FLAG_STRICT,
ATTR_TYPE_NUM, MAIL_ATTR_STATUS, &status,
ATTR_TYPE_END) == 1 ? status : -1);
}
diff --git a/postfix/src/global/deliver_pass.c b/postfix/src/global/deliver_pass.c
index cd2d7e72a..cf4a614c2 100644
--- a/postfix/src/global/deliver_pass.c
+++ b/postfix/src/global/deliver_pass.c
@@ -77,7 +77,7 @@ static int deliver_pass_initial_reply(VSTREAM *stream)
{
int stat;
- if (attr_scan(stream, ATTR_FLAG_MISSING | ATTR_FLAG_EXTRA,
+ if (attr_scan(stream, ATTR_FLAG_STRICT,
ATTR_TYPE_NUM, MAIL_ATTR_STATUS, &stat,
ATTR_TYPE_END) != 1) {
msg_warn("%s: malformed response", VSTREAM_PATH(stream));
@@ -124,7 +124,7 @@ static int deliver_pass_final_reply(VSTREAM *stream, VSTRING *reason)
{
int stat;
- if (attr_scan(stream, ATTR_FLAG_MISSING | ATTR_FLAG_EXTRA,
+ if (attr_scan(stream, ATTR_FLAG_STRICT,
ATTR_TYPE_STR, MAIL_ATTR_WHY, reason,
ATTR_TYPE_NUM, MAIL_ATTR_STATUS, &stat,
ATTR_TYPE_END) != 2) {
diff --git a/postfix/src/global/deliver_request.c b/postfix/src/global/deliver_request.c
index fecf7e4ba..344276a1d 100644
--- a/postfix/src/global/deliver_request.c
+++ b/postfix/src/global/deliver_request.c
@@ -192,7 +192,7 @@ static int deliver_request_get(VSTREAM *stream, DELIVER_REQUEST *request)
* Extract the queue file name, data offset, and sender address. Abort
* the conversation when they send bad information.
*/
- if (attr_scan(stream, ATTR_FLAG_MISSING | ATTR_FLAG_EXTRA | ATTR_FLAG_MORE,
+ if (attr_scan(stream, ATTR_FLAG_STRICT | ATTR_FLAG_MORE,
ATTR_TYPE_NUM, MAIL_ATTR_FLAGS, &request->flags,
ATTR_TYPE_STR, MAIL_ATTR_QUEUE, queue_name,
ATTR_TYPE_STR, MAIL_ATTR_QUEUEID, queue_id,
@@ -221,13 +221,13 @@ static int deliver_request_get(VSTREAM *stream, DELIVER_REQUEST *request)
* attributes from the sender that we do not understand.
*/
for (;;) {
- if (attr_scan(stream, ATTR_FLAG_MORE | ATTR_FLAG_EXTRA,
+ if (attr_scan(stream, ATTR_FLAG_MORE | ATTR_FLAG_STRICT,
ATTR_TYPE_NUM, MAIL_ATTR_OFFSET, &offset,
ATTR_TYPE_END) != 1)
return (-1);
if (offset == 0)
break;
- if (attr_scan(stream, ATTR_FLAG_MORE | ATTR_FLAG_EXTRA,
+ if (attr_scan(stream, ATTR_FLAG_MORE | ATTR_FLAG_STRICT,
ATTR_TYPE_STR, MAIL_ATTR_RECIP, address,
ATTR_TYPE_END) != 1)
return (-1);
diff --git a/postfix/src/global/mail_command_client.c b/postfix/src/global/mail_command_client.c
index cdb1422d0..fc1c56c9e 100644
--- a/postfix/src/global/mail_command_client.c
+++ b/postfix/src/global/mail_command_client.c
@@ -74,7 +74,7 @@ int mail_command_client(const char *class, const char *name,...)
status = attr_vprint(stream, ATTR_FLAG_NONE, ap);
va_end(ap);
if (status != 0
- || attr_scan(stream, ATTR_FLAG_MISSING | ATTR_FLAG_EXTRA,
+ || attr_scan(stream, ATTR_FLAG_STRICT,
ATTR_TYPE_NUM, MAIL_ATTR_STATUS, &status, 0) != 1)
status = -1;
(void) vstream_fclose(stream);
diff --git a/postfix/src/global/mail_command_read.c b/postfix/src/global/mail_command_read.c
deleted file mode 100644
index 74c7def61..000000000
--- a/postfix/src/global/mail_command_read.c
+++ /dev/null
@@ -1,69 +0,0 @@
-/*++
-/* NAME
-/* mail_command_read 3
-/* SUMMARY
-/* single-command server
-/* SYNOPSIS
-/* #include
-/*
-/* int mail_command_read(stream, format, ...)
-/* VSTREAM *stream;
-/* char *format;
-/* DESCRIPTION
-/* This module implements the server interface for single-command
-/* requests: a clients sends a single command and expects a single
-/* completion status code.
-/*
-/* Arguments:
-/* .IP stream
-/* Server endpoint.
-/* .IP format
-/* Format string understood by mail_print(3) and mail_scan(3).
-/* DIAGNOSTICS
-/* Fatal: out of memory.
-/* SEE ALSO
-/* mail_scan(3)
-/* mail_command_write(3) client interface
-/* LICENSE
-/* .ad
-/* .fi
-/* The Secure Mailer license must be distributed with this software.
-/* AUTHOR(S)
-/* Wietse Venema
-/* IBM T.J. Watson Research
-/* P.O. Box 704
-/* Yorktown Heights, NY 10598, USA
-/*--*/
-
-/* System library. */
-
-#include
-#include /* 44BSD stdarg.h uses abort() */
-#include
-#include
-
-/* Utility library. */
-
-#include
-#include
-
-/* Global library. */
-
-#include "mail_proto.h"
-
-/* mail_command_read - read single-command request */
-
-int mail_command_read(VSTREAM *stream, char *fmt,...)
-{
- VSTRING *eof = vstring_alloc(10);
- va_list ap;
- int count;
-
- va_start(ap, fmt);
- count = mail_vscan(stream, fmt, ap);
- va_end(ap);
- if (mail_scan(stream, "%s", eof) != 1 || strcmp(vstring_str(eof), MAIL_EOF))
- count = -1;
- vstring_free(eof);
- return (count);
-}
diff --git a/postfix/src/global/mail_command_write.c b/postfix/src/global/mail_command_write.c
deleted file mode 100644
index e6e855788..000000000
--- a/postfix/src/global/mail_command_write.c
+++ /dev/null
@@ -1,82 +0,0 @@
-/*++
-/* NAME
-/* mail_command_write 3
-/* SUMMARY
-/* single-command client
-/* SYNOPSIS
-/* #include
-/*
-/* int mail_command_write(class, name, format, ...)
-/* const char *class;
-/* const char *name;
-/* const char *format;
-/* DESCRIPTION
-/* This module implements a client interface for single-command
-/* clients: a client that sends a single command and expects
-/* a single completion status code.
-/*
-/* Arguments:
-/* .IP class
-/* Service type: MAIL_CLASS_PUBLIC or MAIL_CLASS_PRIVATE
-/* .IP name
-/* Service name (master.cf).
-/* .IP format
-/* Format string understood by mail_print(3).
-/* DIAGNOSTICS
-/* The result is -1 if the request could not be sent, otherwise
-/* the result is the status reported by the server.
-/* Warnings: problems connecting to the requested service.
-/* Fatal: out of memory.
-/* SEE ALSO
-/* mail_command_read(3), server interface
-/* mail_proto(5h), client-server protocol
-/* LICENSE
-/* .ad
-/* .fi
-/* The Secure Mailer license must be distributed with this software.
-/* AUTHOR(S)
-/* Wietse Venema
-/* IBM T.J. Watson Research
-/* P.O. Box 704
-/* Yorktown Heights, NY 10598, USA
-/*--*/
-
-/* System library. */
-
-#include
-#include /* 44BSD stdarg.h uses abort() */
-#include
-
-/* Utility library. */
-
-#include
-
-/* Global library. */
-
-#include "mail_proto.h"
-
-/* mail_command_write - single-command transaction with completion status */
-
-int mail_command_write(const char *class, const char *name,
- const char *fmt,...)
-{
- va_list ap;
- VSTREAM *stream;
- int status;
-
- /*
- * Talk a little protocol with the specified service.
- */
- if ((stream = mail_connect(class, name, BLOCKING)) == 0)
- return (-1);
- va_start(ap, fmt);
- status = mail_vprint(stream, fmt, ap);
- va_end(ap);
- if (status != 0
- || mail_print(stream, "%s", MAIL_EOF) != 0
- || vstream_fflush(stream) != 0
- || mail_scan(stream, "%d", &status) != 1)
- status = -1;
- (void) vstream_fclose(stream);
- return (status);
-}
diff --git a/postfix/src/global/mail_connect.c b/postfix/src/global/mail_connect.c
index 3e00d9838..a8ef96d13 100644
--- a/postfix/src/global/mail_connect.c
+++ b/postfix/src/global/mail_connect.c
@@ -92,7 +92,7 @@ VSTREAM *mail_connect(const char *class, const char *name, int block_mode)
msg_info("connect to subsystem %s", path);
stream = vstream_fdopen(fd, O_RDWR);
timed_ipc_setup(stream);
- sock_name = concatenate("socket ", path, (char *) 0);
+ sock_name = concatenate(path, " socket", (char *) 0);
vstream_control(stream,
VSTREAM_CTL_PATH, sock_name,
VSTREAM_CTL_END);
diff --git a/postfix/src/global/mail_print.c b/postfix/src/global/mail_print.c
deleted file mode 100644
index 9dddc2592..000000000
--- a/postfix/src/global/mail_print.c
+++ /dev/null
@@ -1,206 +0,0 @@
-/*++
-/* NAME
-/* mail_print 3
-/* SUMMARY
-/* intra-mail system write routine
-/* SYNOPSIS
-/* #include
-/*
-/* int mail_print(stream, format, ...)
-/* VSTREAM *stream;
-/* const char *format;
-/*
-/* int mail_vprint(stream, format, ap)
-/* VSTREAM *stream;
-/* const char *format;
-/* va_list ap;
-/*
-/* void mail_print_register(letter, name, print_fn)
-/* int letter;
-/* const char *name;
-/* void (*print_fn)(VSTREAM *stream, const char *data);
-/* DESCRIPTION
-/* mail_print() prints one or more null-delimited strings to
-/* the named stream, each string being converted according to the
-/* contents of the \fIformat\fR argument.
-/*
-/* mail_vprint() provides an alternative interface.
-/*
-/* mail_print_register() registers the named print function for
-/* the specified letter, for the named type.
-/*
-/* Arguments:
-/* .IP stream
-/* The stream to print to.
-/* .IP format
-/* Format string, which is interpreted as follows:
-/* .RS
-/* .IP "white space"
-/* White space in the format string is ignored.
-/* .IP %s
-/* The corresponding argument has type (char *).
-/* .IP %d
-/* The corresponding argument has type (int).
-/* .IP %ld
-/* The corresponding argument has type (long).
-/* .IP %letter
-/* Call the print routine that was registered for the specified letter.
-/* .PP
-/* Anything else in a format string is a fatal error.
-/* .RE
-/* .IP letter
-/* Format letter that is bound to the \fIprint_fn\fR print function.
-/* .IP name
-/* Descriptive string for verbose logging.
-/* .IP print_fn
-/* A print function. It takes as arguments:
-/* .RS
-/* .IP stream
-/* The stream to print to.
-/* .IP data
-/* A generic data pointer. It is up to the function
-/* to do any necessary casts to the data-specific type.
-/* .RE
-/* LICENSE
-/* .ad
-/* .fi
-/* The Secure Mailer license must be distributed with this software.
-/* AUTHOR(S)
-/* Wietse Venema
-/* IBM T.J. Watson Research
-/* P.O. Box 704
-/* Yorktown Heights, NY 10598, USA
-/*--*/
-
-/* System library. */
-
-#include
-#include
-#include
-#include
-#include
-#include
-
-/* Utility library. */
-
-#include
-#include
-#include
-
-/* Global library. */
-
-#include "mail_proto.h"
-
- /*
- * Provision for the user to register type-specific scanners for
- * applications with unusual requirements.
- */
-typedef struct {
- int letter;
- char *name;
- MAIL_PRINT_FN print_fn;
-} MAIL_PRINT;
-
-MAIL_PRINT *mail_print_tab = 0;
-int mail_print_tablen = 0;
-
-/* mail_print_register - register printer function */
-
-void mail_print_register(int letter, const char *name, MAIL_PRINT_FN print_fn)
-{
- MAIL_PRINT *tp;
-
- for (tp = 0; tp < mail_print_tab + mail_print_tablen; tp++)
- if (tp->letter == letter)
- msg_panic("mail_print_register: redefined letter: %c", letter);
-
- /*
- * Tight fit allocation. We're not registering lots of characters.
- */
- if (mail_print_tab == 0) {
- mail_print_tablen = 1;
- mail_print_tab = (MAIL_PRINT *)
- mymalloc(sizeof(*mail_print_tab) * mail_print_tablen);
- } else {
- mail_print_tablen++;
- mail_print_tab = (MAIL_PRINT *)
- myrealloc((char *) mail_print_tab,
- sizeof(*mail_print_tab) * mail_print_tablen);
- }
- tp = mail_print_tab + mail_print_tablen - 1;
- tp->letter = letter;
- tp->name = mystrdup(name);
- tp->print_fn = print_fn;
-}
-
-/* mail_vprint - print null-delimited data to stream */
-
-int mail_vprint(VSTREAM *stream, const char *fmt, va_list ap)
-{
- const char *cp;
- int lflag;
- char *sval;
- int ival;
- long lval;
- int error;
- MAIL_PRINT *tp;
-
- for (cp = fmt; (error = vstream_ferror(stream)) == 0 && *cp != 0; cp++) {
- if (ISSPACE(*cp))
- continue;
- if (*cp != '%')
- msg_fatal("mail_vprint: bad format: %.*s>%c<%s",
- (int) (cp - fmt), fmt, *cp, cp + 1);
- if ((lflag = (*++cp == 'l')) != 0)
- cp++;
-
- switch (*cp) {
- case 's':
- sval = va_arg(ap, char *);
- if (msg_verbose)
- msg_info("print string: %s", sval);
- vstream_fputs(sval, stream);
- VSTREAM_PUTC(0, stream);
- break;
- case 'd':
- if (lflag) {
- lval = va_arg(ap, long);
- if (msg_verbose)
- msg_info("print long: %ld", lval);
- vstream_fprintf(stream, "%ld", lval);
- } else {
- ival = va_arg(ap, int);
- if (msg_verbose)
- msg_info("print int: %d", ival);
- vstream_fprintf(stream, "%d", ival);
- }
- VSTREAM_PUTC(0, stream);
- break;
- default:
- for (tp = mail_print_tab; tp < mail_print_tab + mail_print_tablen; tp++)
- if (tp->letter == *cp) {
- if (msg_verbose)
- msg_info("print %s", tp->name);
- tp->print_fn(stream, va_arg(ap, char *));
- break;
- }
- if (tp >= mail_print_tab + mail_print_tablen)
- msg_fatal("mail_vprint: bad format: %.*s>%c<%s",
- (int) (cp - fmt), fmt, *cp, cp + 1);
- }
- }
- return (error);
-}
-
-/* mail_print - print null-delimited data to stream */
-
-int mail_print(VSTREAM *stream, const char *fmt,...)
-{
- int status;
- va_list ap;
-
- va_start(ap, fmt);
- status = mail_vprint(stream, fmt, ap);
- va_end(ap);
- return (status);
-}
diff --git a/postfix/src/global/mail_proto.h b/postfix/src/global/mail_proto.h
index fe09056ad..adadcda60 100644
--- a/postfix/src/global/mail_proto.h
+++ b/postfix/src/global/mail_proto.h
@@ -50,12 +50,6 @@
#define MAIL_CLASS_PUBLIC "public"
#define MAIL_CLASS_PRIVATE "private"
- /*
- * When sending across a list of objects, this is how we signal the list
- * end.
- */
-#define MAIL_EOF "@"
-
/*
* Generic triggers.
*/
@@ -72,29 +66,13 @@
/*
* Functional interface.
*/
-#define MAIL_SCAN_MORE 0
-#define MAIL_SCAN_DONE 1
-#define MAIL_SCAN_ERROR -1
-
-typedef int (*MAIL_SCAN_FN) (const char *, char *);
-typedef void (*MAIL_PRINT_FN) (VSTREAM *, const char *);
extern VSTREAM *mail_connect(const char *, const char *, int);
extern VSTREAM *mail_connect_wait(const char *, const char *);
-extern int mail_scan(VSTREAM *, const char *,...);
-extern void mail_scan_register(int, const char *, MAIL_SCAN_FN);
-extern void mail_print_register(int, const char *, MAIL_PRINT_FN);
-extern int PRINTFLIKE(2, 3) mail_print(VSTREAM *, const char *,...);
extern int mail_command_client(const char *, const char *,...);
extern int mail_command_server(VSTREAM *,...);
extern int mail_trigger(const char *, const char *, const char *, int);
extern char *mail_pathname(const char *, const char *);
- /*
- * Stuff that needs
- */
-extern int mail_vprint(VSTREAM *, const char *, va_list);
-extern int mail_vscan(VSTREAM *, const char *, va_list);
-
/*
* Attribute names.
*/
diff --git a/postfix/src/global/mail_scan.c b/postfix/src/global/mail_scan.c
deleted file mode 100644
index cc3de3f17..000000000
--- a/postfix/src/global/mail_scan.c
+++ /dev/null
@@ -1,272 +0,0 @@
-/*++
-/* NAME
-/* mail_scan 3
-/* SUMMARY
-/* intra-mail read routine
-/* SYNOPSIS
-/* #include
-/*
-/* int mail_scan(stream, format, ...)
-/* VSTREAM *stream;
-/* const char *format;
-/*
-/* void mail_scan_register(letter, name, scan_fn)
-/* int letter;
-/* const char *name;
-/* int (*scan_fn)(const char *string, char *result);
-/* DESCRIPTION
-/* mail_scan() reads one or more null-delimited strings from
-/* the named stream, each string being converted according to the
-/* contents of the \fIformat\fR argument.
-/* The result value is the number of successful conversions.
-/*
-/* mail_scan_register() registers an input conversion function
-/* for the specified letter.
-/*
-/* Arguments:
-/* .IP stream
-/* Stream to read from.
-/* .IP format
-/* Format string, which is interpreted as follows:
-/* .RS
-/* .IP "white space"
-/* White space in the format string is ignored.
-/* .IP %s
-/* The corresponding argument has type (VSTRING *).
-/* .IP %d
-/* The corresponding argument has type (int *).
-/* .IP %ld
-/* The corresponding argument has type (long *).
-/* .IP %letter
-/* Call the input conversion routine that was registered for
-/* the specified letter.
-/* .PP
-/* Anything else in a format string is a fatal error.
-/* .RE
-/* .IP letter
-/* Format letter that is bound to the \fIscan_fn\fR input
-/* conversion function.
-/* .IP name
-/* Descriptive string for verbose logging.
-/* .IP scan_fn
-/* An input conversion function. It takes as arguments:
-/* .RS
-/* .IP string
-/* The null-terminated string to be converted.
-/* .IP result
-/* A character pointer to the result. It is up to the function
-/* to do any necessary casts to the data-specific type.
-/* .RE
-/* .PP
-/* The function result values are as follows:
-/* .RS
-/* .IP MAIL_SCAN_ERROR
-/* The expected input could not be read.
-/* .IP MAIL_SCAN_DONE
-/* The operation completed successfully.
-/* .IP MAIL_SCAN_MORE
-/* More input is expected.
-/* .RE
-/* LICENSE
-/* .ad
-/* .fi
-/* The Secure Mailer license must be distributed with this software.
-/* AUTHOR(S)
-/* Wietse Venema
-/* IBM T.J. Watson Research
-/* P.O. Box 704
-/* Yorktown Heights, NY 10598, USA
-/*--*/
-
-/* System library. */
-
-#include
-#include
-#include
-#include
-#include
-#include
-
-/* Utility library. */
-
-#include
-#include
-#include
-#include
-#include
-
-/* Global library. */
-
-#include "mail_proto.h"
-
- /*
- * Provision for the user to register type-specific input conversion
- * routines for applications with unusual requirements.
- */
-typedef struct {
- int letter;
- char *name;
- MAIL_SCAN_FN scanner;
-} MAIL_SCAN;
-
-MAIL_SCAN *mail_scan_tab = 0;
-int mail_scan_tablen = 0;
-
-/* mail_scan_register - register scanner function */
-
-void mail_scan_register(int letter, const char *name, MAIL_SCAN_FN scanner)
-{
- MAIL_SCAN *tp;
-
- for (tp = 0; tp < mail_scan_tab + mail_scan_tablen; tp++)
- if (tp->letter == letter)
- msg_panic("mail_scan_register: redefined letter: %c", letter);
-
- /*
- * Tight fit allocation (as in: Robin Hood and the men that wear tights).
- */
- if (mail_scan_tab == 0) {
- mail_scan_tablen = 1;
- mail_scan_tab = (MAIL_SCAN *)
- mymalloc(sizeof(*mail_scan_tab) * mail_scan_tablen);
- } else {
- mail_scan_tablen++;
- mail_scan_tab = (MAIL_SCAN *)
- myrealloc((char *) mail_scan_tab,
- sizeof(*mail_scan_tab) * mail_scan_tablen);
- }
- tp = mail_scan_tab + mail_scan_tablen - 1;
- tp->letter = letter;
- tp->name = mystrdup(name);
- tp->scanner = scanner;
-}
-
-/* mail_scan_any - read one null-delimited string from stream */
-
-static int mail_scan_any(VSTREAM *stream, VSTRING *vp, char *what)
-{
- if (vstring_fgets_null(vp, stream) == 0) {
- msg_warn("end of input while receiving %s data from service %s",
- what, VSTREAM_PATH(stream));
- return (-1);
- }
- if (msg_verbose)
- msg_info("mail_scan_any: read %s: %s", what, vstring_str(vp));
- return (0);
-}
-
-/* mail_scan_other - read user-defined type from stream */
-
-static int mail_scan_other(VSTREAM *stream, VSTRING *vp,
- MAIL_SCAN *tp, char *result)
-{
- int ret;
-
- while ((ret = mail_scan_any(stream, vp, tp->name)) == 0) {
- switch (tp->scanner(vstring_str(vp), result)) {
- case MAIL_SCAN_MORE:
- break;
- case MAIL_SCAN_DONE:
- return (0);
- case MAIL_SCAN_ERROR:
- return (-1);
- }
- }
- return (ret);
-}
-
-/* mail_scan_long - read long integer from stream */
-
-static int mail_scan_long(VSTREAM *stream, VSTRING *vp, long *lp)
-{
- int ret;
- char junk;
-
- if ((ret = mail_scan_any(stream, vp, "long integer")) == 0) {
- if (sscanf(vstring_str(vp), "%ld%c", lp, &junk) != 1) {
- msg_warn("mail_scan_long: bad long long: %s", vstring_str(vp));
- ret = -1;
- }
- }
- return (ret);
-}
-
-/* mail_scan_int - read integer from stream */
-
-static int mail_scan_int(VSTREAM *stream, VSTRING *vp, int *lp)
-{
- int ret;
- char junk;
-
- if ((ret = mail_scan_any(stream, vp, "integer")) == 0) {
- if (sscanf(vstring_str(vp), "%d%c", lp, &junk) != 1) {
- msg_warn("mail_scan_int: bad integer: %s", vstring_str(vp));
- ret = -1;
- }
- }
- return (ret);
-}
-
-/* mail_scan - read null-delimited data from stream */
-
-int mail_scan(VSTREAM *stream, const char *fmt,...)
-{
- va_list ap;
- int count;
-
- va_start(ap, fmt);
- count = mail_vscan(stream, fmt, ap);
- va_end(ap);
- return (count);
-}
-
-/* mail_vscan - read null-delimited data from stream */
-
-int mail_vscan(VSTREAM *stream, const char *fmt, va_list ap)
-{
- const char *cp;
- int lflag;
- int count;
- int error;
- static VSTRING *tmp;
- MAIL_SCAN *tp;
-
- if (tmp == 0)
- tmp = vstring_alloc(100);
-
- for (count = 0, error = 0, cp = fmt; error == 0 && *cp != 0; cp++) {
- if (ISSPACE(*cp))
- continue;
- if (*cp != '%')
- msg_fatal("mail_scan: bad format: %.*s>%c<%s",
- (int) (cp - fmt), fmt, *cp, cp + 1);
- if ((lflag = (*++cp == 'l')) != 0)
- cp++;
-
- switch (*cp) {
- case 's':
- error = mail_scan_any(stream, va_arg(ap, VSTRING *), "string");
- break;
- case 'd':
- if (lflag)
- error = mail_scan_long(stream, tmp, va_arg(ap, long *));
- else
- error = mail_scan_int(stream, tmp, va_arg(ap, int *));
- break;
- default:
- for (tp = mail_scan_tab; tp < mail_scan_tab + mail_scan_tablen; tp++)
- if (tp->letter == *cp) {
- if (msg_verbose)
- msg_info("mail_scan: %s", tp->name);
- error = mail_scan_other(stream, tmp, tp, va_arg(ap, char *));
- break;
- }
- if (tp >= mail_scan_tab + mail_scan_tablen)
- msg_fatal("mail_scan: bad format: %.*s>%c<%s",
- (int) (cp - fmt), fmt, *cp, cp + 1);
- }
- if (error == 0)
- count++;
- }
- return (count);
-}
diff --git a/postfix/src/global/mail_stream.c b/postfix/src/global/mail_stream.c
index 41ae0d38f..ed58493da 100644
--- a/postfix/src/global/mail_stream.c
+++ b/postfix/src/global/mail_stream.c
@@ -178,7 +178,7 @@ static int mail_stream_finish_ipc(MAIL_STREAM * info, VSTRING *why)
/*
* Receive the peer's completion status.
*/
- if ((why && attr_scan(info->stream, ATTR_FLAG_MISSING | ATTR_FLAG_EXTRA,
+ if ((why && attr_scan(info->stream, ATTR_FLAG_STRICT,
ATTR_TYPE_NUM, MAIL_ATTR_STATUS, &status,
ATTR_TYPE_STR, MAIL_ATTR_WHY, why,
ATTR_TYPE_END) != 2)
diff --git a/postfix/src/global/mail_version.h b/postfix/src/global/mail_version.h
index 09831453a..34e4646f8 100644
--- a/postfix/src/global/mail_version.h
+++ b/postfix/src/global/mail_version.h
@@ -15,7 +15,7 @@
* Version of this program.
*/
#define VAR_MAIL_VERSION "mail_version"
-#define DEF_MAIL_VERSION "Snapshot-20011101"
+#define DEF_MAIL_VERSION "Snapshot-20011102"
extern char *var_mail_version;
/* LICENSE
diff --git a/postfix/src/global/post_mail.c b/postfix/src/global/post_mail.c
index 122df9873..363195f72 100644
--- a/postfix/src/global/post_mail.c
+++ b/postfix/src/global/post_mail.c
@@ -139,7 +139,7 @@ static void post_mail_init(VSTREAM *stream, const char *sender,
/*
* Negotiate with the cleanup service. Give up if we can't agree.
*/
- if (attr_scan(stream, ATTR_FLAG_MISSING | ATTR_FLAG_EXTRA,
+ if (attr_scan(stream, ATTR_FLAG_STRICT,
ATTR_TYPE_STR, MAIL_ATTR_QUEUEID, id,
ATTR_TYPE_END) != 1
|| attr_print(stream, ATTR_FLAG_NONE,
diff --git a/postfix/src/global/resolve_clnt.c b/postfix/src/global/resolve_clnt.c
index 112e2866a..563828765 100644
--- a/postfix/src/global/resolve_clnt.c
+++ b/postfix/src/global/resolve_clnt.c
@@ -163,7 +163,7 @@ void resolve_clnt_query(const char *addr, RESOLVE_REPLY *reply)
|| vstream_fflush(stream)) {
if (msg_verbose || (errno != EPIPE && errno != ENOENT))
msg_warn("%s: bad write: %m", myname);
- } else if (attr_scan(stream, ATTR_FLAG_MISSING | ATTR_FLAG_EXTRA,
+ } else if (attr_scan(stream, ATTR_FLAG_STRICT,
ATTR_TYPE_STR, MAIL_ATTR_TRANSPORT, reply->transport,
ATTR_TYPE_STR, MAIL_ATTR_NEXTHOP, reply->nexthop,
diff --git a/postfix/src/global/rewrite_clnt.c b/postfix/src/global/rewrite_clnt.c
index 9c32c84f6..886dc4922 100644
--- a/postfix/src/global/rewrite_clnt.c
+++ b/postfix/src/global/rewrite_clnt.c
@@ -131,7 +131,7 @@ VSTRING *rewrite_clnt(const char *rule, const char *addr, VSTRING *result)
vstream_fflush(stream)) {
if (msg_verbose || (errno != EPIPE && errno != ENOENT))
msg_warn("%s: bad write: %m", myname);
- } else if (attr_scan(stream, ATTR_FLAG_MISSING | ATTR_FLAG_EXTRA,
+ } else if (attr_scan(stream, ATTR_FLAG_STRICT,
ATTR_TYPE_STR, MAIL_ATTR_ADDR, result,
ATTR_TYPE_END) != 1) {
if (msg_verbose || (errno != EPIPE && errno != ENOENT))
diff --git a/postfix/src/lmtp/Makefile.in b/postfix/src/lmtp/Makefile.in
index c10125b2a..29c313c24 100644
--- a/postfix/src/lmtp/Makefile.in
+++ b/postfix/src/lmtp/Makefile.in
@@ -133,7 +133,6 @@ lmtp_connect.o: ../../include/stringops.h
lmtp_connect.o: ../../include/mail_params.h
lmtp_connect.o: ../../include/mail_proto.h
lmtp_connect.o: ../../include/attr.h
-lmtp_connect.o: ../../include/htable.h
lmtp_connect.o: ../../include/dns.h
lmtp_connect.o: lmtp.h
lmtp_connect.o: ../../include/argv.h
diff --git a/postfix/src/local/Makefile.in b/postfix/src/local/Makefile.in
index 5aa5fec5c..fc6a4ae2d 100644
--- a/postfix/src/local/Makefile.in
+++ b/postfix/src/local/Makefile.in
@@ -452,9 +452,9 @@ unknown.o: ../../include/mail_proto.h
unknown.o: ../../include/vstream.h
unknown.o: ../../include/iostuff.h
unknown.o: ../../include/attr.h
-unknown.o: ../../include/htable.h
unknown.o: ../../include/bounce.h
unknown.o: local.h
+unknown.o: ../../include/htable.h
unknown.o: ../../include/tok822.h
unknown.o: ../../include/resolve_clnt.h
unknown.o: ../../include/deliver_request.h
diff --git a/postfix/src/local/forward.c b/postfix/src/local/forward.c
index e90b38eda..fb40ec12c 100644
--- a/postfix/src/local/forward.c
+++ b/postfix/src/local/forward.c
@@ -129,7 +129,7 @@ static FORWARD_INFO *forward_open(char *sender)
if (cleanup == 0)
return (0);
close_on_exec(vstream_fileno(cleanup), CLOSE_ON_EXEC);
- if (attr_scan(cleanup, ATTR_FLAG_MISSING | ATTR_FLAG_EXTRA,
+ if (attr_scan(cleanup, ATTR_FLAG_STRICT,
ATTR_TYPE_STR, MAIL_ATTR_QUEUEID, buffer,
ATTR_TYPE_END) != 1) {
vstream_fclose(cleanup);
diff --git a/postfix/src/master/Makefile.in b/postfix/src/master/Makefile.in
index 729a06b2d..a88350584 100644
--- a/postfix/src/master/Makefile.in
+++ b/postfix/src/master/Makefile.in
@@ -132,7 +132,6 @@ master_ent.o: ../../include/inet_addr_host.h
master_ent.o: ../../include/mail_proto.h
master_ent.o: ../../include/iostuff.h
master_ent.o: ../../include/attr.h
-master_ent.o: ../../include/htable.h
master_ent.o: ../../include/mail_params.h
master_ent.o: ../../include/own_inet_addr.h
master_ent.o: master_proto.h
@@ -208,7 +207,6 @@ master_wakeup.o: ../../include/vstream.h
master_wakeup.o: ../../include/vbuf.h
master_wakeup.o: ../../include/iostuff.h
master_wakeup.o: ../../include/attr.h
-master_wakeup.o: ../../include/htable.h
master_wakeup.o: mail_server.h
master_wakeup.o: master.h
multi_server.o: multi_server.c
diff --git a/postfix/src/nqmgr/Makefile.in b/postfix/src/nqmgr/Makefile.in
index 4ead1237c..7396348c8 100644
--- a/postfix/src/nqmgr/Makefile.in
+++ b/postfix/src/nqmgr/Makefile.in
@@ -76,7 +76,6 @@ qmgr.o: ../../include/mail_params.h
qmgr.o: ../../include/mail_proto.h
qmgr.o: ../../include/iostuff.h
qmgr.o: ../../include/attr.h
-qmgr.o: ../../include/htable.h
qmgr.o: ../../include/mail_flow.h
qmgr.o: ../../include/master_proto.h
qmgr.o: ../../include/mail_server.h
@@ -139,7 +138,6 @@ qmgr_deliver.o: ../../include/iostuff.h
qmgr_deliver.o: ../../include/mail_queue.h
qmgr_deliver.o: ../../include/mail_proto.h
qmgr_deliver.o: ../../include/attr.h
-qmgr_deliver.o: ../../include/htable.h
qmgr_deliver.o: ../../include/recipient_list.h
qmgr_deliver.o: ../../include/mail_params.h
qmgr_deliver.o: ../../include/deliver_request.h
diff --git a/postfix/src/nqmgr/qmgr_deliver.c b/postfix/src/nqmgr/qmgr_deliver.c
index 4060799f1..7dbe299e6 100644
--- a/postfix/src/nqmgr/qmgr_deliver.c
+++ b/postfix/src/nqmgr/qmgr_deliver.c
@@ -92,7 +92,7 @@ static int qmgr_deliver_initial_reply(VSTREAM *stream)
if (peekfd(vstream_fileno(stream)) < 0) {
msg_warn("%s: premature disconnect", VSTREAM_PATH(stream));
return (DELIVER_STAT_CRASH);
- } else if (attr_scan(stream, ATTR_FLAG_MISSING | ATTR_FLAG_EXTRA,
+ } else if (attr_scan(stream, ATTR_FLAG_STRICT,
ATTR_TYPE_NUM, MAIL_ATTR_STATUS, &stat,
ATTR_TYPE_END) != 1) {
msg_warn("%s: malformed response", VSTREAM_PATH(stream));
@@ -111,7 +111,7 @@ static int qmgr_deliver_final_reply(VSTREAM *stream, VSTRING *reason)
if (peekfd(vstream_fileno(stream)) < 0) {
msg_warn("%s: premature disconnect", VSTREAM_PATH(stream));
return (DELIVER_STAT_CRASH);
- } else if (attr_scan(stream, ATTR_FLAG_MISSING | ATTR_FLAG_EXTRA,
+ } else if (attr_scan(stream, ATTR_FLAG_STRICT,
ATTR_TYPE_STR, MAIL_ATTR_WHY, reason,
ATTR_TYPE_NUM, MAIL_ATTR_STATUS, &stat,
ATTR_TYPE_END) != 2) {
diff --git a/postfix/src/pickup/Makefile.in b/postfix/src/pickup/Makefile.in
index 144288104..3820f34a4 100644
--- a/postfix/src/pickup/Makefile.in
+++ b/postfix/src/pickup/Makefile.in
@@ -68,7 +68,6 @@ pickup.o: ../../include/mymalloc.h
pickup.o: ../../include/mail_proto.h
pickup.o: ../../include/iostuff.h
pickup.o: ../../include/attr.h
-pickup.o: ../../include/htable.h
pickup.o: ../../include/cleanup_user.h
pickup.o: ../../include/mail_date.h
pickup.o: ../../include/mail_params.h
diff --git a/postfix/src/pickup/pickup.c b/postfix/src/pickup/pickup.c
index c21c9b886..2bdaa205f 100644
--- a/postfix/src/pickup/pickup.c
+++ b/postfix/src/pickup/pickup.c
@@ -367,7 +367,7 @@ static int pickup_file(PICKUP_INFO *info)
buf = vstring_alloc(100);
cleanup = mail_connect_wait(MAIL_CLASS_PRIVATE, MAIL_SERVICE_CLEANUP);
- if (attr_scan(cleanup, ATTR_FLAG_MISSING | ATTR_FLAG_EXTRA,
+ if (attr_scan(cleanup, ATTR_FLAG_STRICT,
ATTR_TYPE_STR, MAIL_ATTR_QUEUEID, buf,
ATTR_TYPE_END) != 1
|| attr_print(cleanup, ATTR_FLAG_NONE,
diff --git a/postfix/src/postalias/postalias.c b/postfix/src/postalias/postalias.c
index c2bbbbde6..d4429958c 100644
--- a/postfix/src/postalias/postalias.c
+++ b/postfix/src/postalias/postalias.c
@@ -5,7 +5,7 @@
/* Postfix alias database maintenance
/* SYNOPSIS
/* .fi
-/* \fBpostalias\fR [\fB-Ninrvw\fR] [\fB-c \fIconfig_dir\fR]
+/* \fBpostalias\fR [\fB-Nfinrvw\fR] [\fB-c \fIconfig_dir\fR]
/* [\fB-d \fIkey\fR] [\fB-q \fIkey\fR]
/* [\fIfile_type\fR:]\fIfile_name\fR ...
/* DESCRIPTION
@@ -34,6 +34,8 @@
/* If a key value of \fB-\fR is specified, the program reads key
/* values from the standard input stream. The exit status is zero
/* when at least one of the requested keys was found.
+/* .IP \fB-f\fR
+/* Do not fold the lookup key to lower case while creating a map.
/* .IP \fB-i\fR
/* Incremental mode. Read entries from standard input and do not
/* truncate an existing database. By default, \fBpostalias\fR creates
@@ -270,7 +272,8 @@ static void postalias(char *map_type, char *path_name,
/*
* Store the value under a case-insensitive key.
*/
- lowercase(STR(key_buffer));
+ if (dict_flags & DICT_FLAG_FOLD_KEY)
+ lowercase(STR(key_buffer));
mkmap_append(mkmap, STR(key_buffer), STR(value_buffer));
}
@@ -448,7 +451,7 @@ static int postalias_delete(const char *map_type, const char *map_name,
static NORETURN usage(char *myname)
{
- msg_fatal("usage: %s [-Ninrvw] [-c config_dir] [-d key] [-q key] [map_type:]file...",
+ msg_fatal("usage: %s [-Nfinrvw] [-c config_dir] [-d key] [-q key] [map_type:]file...",
myname);
}
@@ -460,7 +463,7 @@ int main(int argc, char **argv)
char *slash;
struct stat st;
int open_flags = O_RDWR | O_CREAT | O_TRUNC;
- int dict_flags = DICT_FLAG_DUP_WARN;
+ int dict_flags = DICT_FLAG_DUP_WARN | DICT_FLAG_FOLD_KEY;
char *query = 0;
char *delkey = 0;
int found;
@@ -498,7 +501,7 @@ int main(int argc, char **argv)
/*
* Parse JCL.
*/
- while ((ch = GETOPT(argc, argv, "Nc:d:inq:rvw")) > 0) {
+ while ((ch = GETOPT(argc, argv, "Nc:d:finq:rvw")) > 0) {
switch (ch) {
default:
usage(argv[0]);
@@ -516,6 +519,9 @@ int main(int argc, char **argv)
msg_fatal("specify only one of -q or -d");
delkey = optarg;
break;
+ case 'f':
+ dict_flags &= ~DICT_FLAG_FOLD_KEY;
+ break;
case 'i':
open_flags &= ~O_TRUNC;
break;
diff --git a/postfix/src/postdrop/Makefile.in b/postfix/src/postdrop/Makefile.in
index 21f69e983..249fac434 100644
--- a/postfix/src/postdrop/Makefile.in
+++ b/postfix/src/postdrop/Makefile.in
@@ -66,7 +66,6 @@ postdrop.o: ../../include/argv.h
postdrop.o: ../../include/mail_proto.h
postdrop.o: ../../include/iostuff.h
postdrop.o: ../../include/attr.h
-postdrop.o: ../../include/htable.h
postdrop.o: ../../include/mail_queue.h
postdrop.o: ../../include/mail_params.h
postdrop.o: ../../include/mail_conf.h
diff --git a/postfix/src/postkick/Makefile.in b/postfix/src/postkick/Makefile.in
index d028e21e6..d4cf100f4 100644
--- a/postfix/src/postkick/Makefile.in
+++ b/postfix/src/postkick/Makefile.in
@@ -65,6 +65,5 @@ postkick.o: ../../include/events.h
postkick.o: ../../include/mail_proto.h
postkick.o: ../../include/iostuff.h
postkick.o: ../../include/attr.h
-postkick.o: ../../include/htable.h
postkick.o: ../../include/mail_params.h
postkick.o: ../../include/mail_conf.h
diff --git a/postfix/src/postmap/postmap.c b/postfix/src/postmap/postmap.c
index a22ea3321..70ee670aa 100644
--- a/postfix/src/postmap/postmap.c
+++ b/postfix/src/postmap/postmap.c
@@ -5,8 +5,9 @@
/* Postfix lookup table management
/* SYNOPSIS
/* .fi
-/* \fBpostmap\fR [\fB-Ninrvw\fR] [\fB-c \fIconfig_dir\fR] [\fB-d \fIkey\fR]
-/* [\fB-q \fIkey\fR] [\fIfile_type\fR:]\fIfile_name\fR ...
+/* \fBpostmap\fR [\fB-Nfinrvw\fR] [\fB-c \fIconfig_dir\fR]
+/* [\fB-d \fIkey\fR] [\fB-q \fIkey\fR]
+/* [\fIfile_type\fR:]\fIfile_name\fR ...
/* DESCRIPTION
/* The \fBpostmap\fR command creates or queries one or more Postfix
/* lookup tables, or updates an existing one. The input and output
@@ -52,6 +53,8 @@
/* If a key value of \fB-\fR is specified, the program reads key
/* values from the standard input stream. The exit status is zero
/* when at least one of the requested keys was found.
+/* .IP \fB-f\fR
+/* Do not fold the lookup key to lower case while creating a map.
/* .IP \fB-i\fR
/* Incremental mode. Read entries from standard input and do not
/* truncate an existing database. By default, \fBpostmap\fR creates
@@ -243,7 +246,8 @@ static void postmap(char *map_type, char *path_name,
/*
* Store the value under a case-insensitive key.
*/
- lowercase(key);
+ if (dict_flags & DICT_FLAG_FOLD_KEY)
+ lowercase(key);
mkmap_append(mkmap, key, value);
}
@@ -395,7 +399,7 @@ static int postmap_delete(const char *map_type, const char *map_name,
static NORETURN usage(char *myname)
{
- msg_fatal("usage: %s [-Ninrvw] [-c config_dir] [-d key] [-q key] [map_type:]file...",
+ msg_fatal("usage: %s [-Nfinrvw] [-c config_dir] [-d key] [-q key] [map_type:]file...",
myname);
}
@@ -407,7 +411,7 @@ int main(int argc, char **argv)
char *slash;
struct stat st;
int open_flags = O_RDWR | O_CREAT | O_TRUNC;
- int dict_flags = DICT_FLAG_DUP_WARN;
+ int dict_flags = DICT_FLAG_DUP_WARN | DICT_FLAG_FOLD_KEY;
char *query = 0;
char *delkey = 0;
int found;
@@ -445,7 +449,7 @@ int main(int argc, char **argv)
/*
* Parse JCL.
*/
- while ((ch = GETOPT(argc, argv, "Nc:d:inq:rvw")) > 0) {
+ while ((ch = GETOPT(argc, argv, "Nc:d:finq:rvw")) > 0) {
switch (ch) {
default:
usage(argv[0]);
@@ -463,6 +467,9 @@ int main(int argc, char **argv)
msg_fatal("specify only one of -q or -d");
delkey = optarg;
break;
+ case 'f':
+ dict_flags &= ~DICT_FLAG_FOLD_KEY;
+ break;
case 'i':
open_flags &= ~O_TRUNC;
break;
diff --git a/postfix/src/qmgr/Makefile.in b/postfix/src/qmgr/Makefile.in
index 2b04de679..19f24d7e6 100644
--- a/postfix/src/qmgr/Makefile.in
+++ b/postfix/src/qmgr/Makefile.in
@@ -74,7 +74,6 @@ qmgr.o: ../../include/mail_params.h
qmgr.o: ../../include/mail_proto.h
qmgr.o: ../../include/iostuff.h
qmgr.o: ../../include/attr.h
-qmgr.o: ../../include/htable.h
qmgr.o: ../../include/mail_flow.h
qmgr.o: ../../include/master_proto.h
qmgr.o: ../../include/mail_server.h
@@ -137,7 +136,6 @@ qmgr_deliver.o: ../../include/iostuff.h
qmgr_deliver.o: ../../include/mail_queue.h
qmgr_deliver.o: ../../include/mail_proto.h
qmgr_deliver.o: ../../include/attr.h
-qmgr_deliver.o: ../../include/htable.h
qmgr_deliver.o: ../../include/recipient_list.h
qmgr_deliver.o: ../../include/mail_params.h
qmgr_deliver.o: ../../include/deliver_request.h
diff --git a/postfix/src/qmgr/qmgr_deliver.c b/postfix/src/qmgr/qmgr_deliver.c
index efcd96b74..403cc8ec5 100644
--- a/postfix/src/qmgr/qmgr_deliver.c
+++ b/postfix/src/qmgr/qmgr_deliver.c
@@ -87,7 +87,7 @@ static int qmgr_deliver_initial_reply(VSTREAM *stream)
if (peekfd(vstream_fileno(stream)) < 0) {
msg_warn("%s: premature disconnect", VSTREAM_PATH(stream));
return (DELIVER_STAT_CRASH);
- } else if (attr_scan(stream, ATTR_FLAG_MISSING | ATTR_FLAG_EXTRA,
+ } else if (attr_scan(stream, ATTR_FLAG_STRICT,
ATTR_TYPE_NUM, MAIL_ATTR_STATUS, &stat,
ATTR_TYPE_END) != 1) {
msg_warn("%s: malformed response", VSTREAM_PATH(stream));
@@ -106,7 +106,7 @@ static int qmgr_deliver_final_reply(VSTREAM *stream, VSTRING *reason)
if (peekfd(vstream_fileno(stream)) < 0) {
msg_warn("%s: premature disconnect", VSTREAM_PATH(stream));
return (DELIVER_STAT_CRASH);
- } else if (attr_scan(stream, ATTR_FLAG_MISSING | ATTR_FLAG_EXTRA,
+ } else if (attr_scan(stream, ATTR_FLAG_STRICT,
ATTR_TYPE_STR, MAIL_ATTR_WHY, reason,
ATTR_TYPE_NUM, MAIL_ATTR_STATUS, &stat,
ATTR_TYPE_END) != 2) {
diff --git a/postfix/src/qmqpd/Makefile.in b/postfix/src/qmqpd/Makefile.in
index 8eb77b612..b5fa478cc 100644
--- a/postfix/src/qmqpd/Makefile.in
+++ b/postfix/src/qmqpd/Makefile.in
@@ -83,7 +83,6 @@ qmqpd.o: ../../include/rec_type.h
qmqpd.o: ../../include/mail_proto.h
qmqpd.o: ../../include/iostuff.h
qmqpd.o: ../../include/attr.h
-qmqpd.o: ../../include/htable.h
qmqpd.o: ../../include/cleanup_user.h
qmqpd.o: ../../include/mail_date.h
qmqpd.o: ../../include/mail_conf.h
diff --git a/postfix/src/qmqpd/qmqpd.c b/postfix/src/qmqpd/qmqpd.c
index 40ea80839..5b1d1d1b0 100644
--- a/postfix/src/qmqpd/qmqpd.c
+++ b/postfix/src/qmqpd/qmqpd.c
@@ -225,6 +225,7 @@ static void qmqpd_copy_sender(QMQPD_STATE *state)
*/
state->where = "receiving sender address";
netstring_get(state->client, state->buf, var_line_limit);
+ VSTRING_TERMINATE(state->buf);
verp_requested = ((end_prefix = strstr(STR(state->buf), "-@")) != 0
&& (end_origin = strstr(end_prefix + 2, "-@")) != 0
&& strncmp(end_origin + 2, "[]", 2) == 0
diff --git a/postfix/src/sendmail/Makefile.in b/postfix/src/sendmail/Makefile.in
index 13bbb4370..306960fd1 100644
--- a/postfix/src/sendmail/Makefile.in
+++ b/postfix/src/sendmail/Makefile.in
@@ -74,7 +74,6 @@ sendmail.o: ../../include/connect.h
sendmail.o: ../../include/mail_queue.h
sendmail.o: ../../include/mail_proto.h
sendmail.o: ../../include/attr.h
-sendmail.o: ../../include/htable.h
sendmail.o: ../../include/mail_params.h
sendmail.o: ../../include/record.h
sendmail.o: ../../include/rec_type.h
diff --git a/postfix/src/smtp/Makefile.in b/postfix/src/smtp/Makefile.in
index 5f749ea5f..87ba5ac14 100644
--- a/postfix/src/smtp/Makefile.in
+++ b/postfix/src/smtp/Makefile.in
@@ -81,7 +81,6 @@ smtp.o: ../../include/deliver_pass.h
smtp.o: ../../include/mail_proto.h
smtp.o: ../../include/iostuff.h
smtp.o: ../../include/attr.h
-smtp.o: ../../include/htable.h
smtp.o: ../../include/mail_server.h
smtp.o: smtp.h
smtp.o: smtp_sasl.h
diff --git a/postfix/src/smtpd/Makefile.in b/postfix/src/smtpd/Makefile.in
index 33c3d96ba..e8181359b 100644
--- a/postfix/src/smtpd/Makefile.in
+++ b/postfix/src/smtpd/Makefile.in
@@ -114,7 +114,6 @@ smtpd.o: ../../include/rec_type.h
smtpd.o: ../../include/mail_proto.h
smtpd.o: ../../include/iostuff.h
smtpd.o: ../../include/attr.h
-smtpd.o: ../../include/htable.h
smtpd.o: ../../include/cleanup_user.h
smtpd.o: ../../include/mail_date.h
smtpd.o: ../../include/mail_conf.h
@@ -151,7 +150,6 @@ smtpd_chat.o: ../../include/rec_type.h
smtpd_chat.o: ../../include/mail_proto.h
smtpd_chat.o: ../../include/iostuff.h
smtpd_chat.o: ../../include/attr.h
-smtpd_chat.o: ../../include/htable.h
smtpd_chat.o: ../../include/mail_params.h
smtpd_chat.o: ../../include/mail_addr.h
smtpd_chat.o: ../../include/post_mail.h
@@ -231,7 +229,6 @@ smtpd_sasl_proto.o: ../../include/vstream.h
smtpd_sasl_proto.o: ../../include/vbuf.h
smtpd_sasl_proto.o: ../../include/iostuff.h
smtpd_sasl_proto.o: ../../include/attr.h
-smtpd_sasl_proto.o: ../../include/htable.h
smtpd_sasl_proto.o: ../../include/mail_error.h
smtpd_sasl_proto.o: ../../include/name_mask.h
smtpd_sasl_proto.o: smtpd.h
diff --git a/postfix/src/trivial-rewrite/Makefile.in b/postfix/src/trivial-rewrite/Makefile.in
index 6e97b0ba9..8890cdadc 100644
--- a/postfix/src/trivial-rewrite/Makefile.in
+++ b/postfix/src/trivial-rewrite/Makefile.in
@@ -71,7 +71,6 @@ resolve.o: ../../include/mail_params.h
resolve.o: ../../include/mail_proto.h
resolve.o: ../../include/iostuff.h
resolve.o: ../../include/attr.h
-resolve.o: ../../include/htable.h
resolve.o: ../../include/mail_addr.h
resolve.o: ../../include/rewrite_clnt.h
resolve.o: ../../include/resolve_local.h
@@ -93,7 +92,6 @@ rewrite.o: ../../include/mail_params.h
rewrite.o: ../../include/mail_proto.h
rewrite.o: ../../include/iostuff.h
rewrite.o: ../../include/attr.h
-rewrite.o: ../../include/htable.h
rewrite.o: ../../include/resolve_local.h
rewrite.o: ../../include/tok822.h
rewrite.o: ../../include/resolve_clnt.h
@@ -128,7 +126,6 @@ trivial-rewrite.o: ../../include/mail_params.h
trivial-rewrite.o: ../../include/mail_proto.h
trivial-rewrite.o: ../../include/iostuff.h
trivial-rewrite.o: ../../include/attr.h
-trivial-rewrite.o: ../../include/htable.h
trivial-rewrite.o: ../../include/resolve_local.h
trivial-rewrite.o: ../../include/mail_conf.h
trivial-rewrite.o: ../../include/resolve_clnt.h
diff --git a/postfix/src/trivial-rewrite/resolve.c b/postfix/src/trivial-rewrite/resolve.c
index 0ad2931b9..ba4463019 100644
--- a/postfix/src/trivial-rewrite/resolve.c
+++ b/postfix/src/trivial-rewrite/resolve.c
@@ -257,7 +257,7 @@ int resolve_proto(VSTREAM *stream)
{
int flags;
- if (attr_scan(stream, ATTR_FLAG_MISSING | ATTR_FLAG_EXTRA,
+ if (attr_scan(stream, ATTR_FLAG_STRICT,
ATTR_TYPE_STR, MAIL_ATTR_ADDR, query,
ATTR_TYPE_END) != 1)
return (-1);
diff --git a/postfix/src/trivial-rewrite/rewrite.c b/postfix/src/trivial-rewrite/rewrite.c
index 1e165b7b7..e1ae59cf7 100644
--- a/postfix/src/trivial-rewrite/rewrite.c
+++ b/postfix/src/trivial-rewrite/rewrite.c
@@ -203,7 +203,7 @@ void rewrite_addr(char *ruleset, char *addr, VSTRING *result)
int rewrite_proto(VSTREAM *stream)
{
- if (attr_scan(stream, ATTR_FLAG_MISSING | ATTR_FLAG_EXTRA,
+ if (attr_scan(stream, ATTR_FLAG_STRICT,
ATTR_TYPE_STR, MAIL_ATTR_RULE, ruleset,
ATTR_TYPE_STR, MAIL_ATTR_ADDR, address,
ATTR_TYPE_END) != 2)
diff --git a/postfix/src/trivial-rewrite/trivial-rewrite.c b/postfix/src/trivial-rewrite/trivial-rewrite.c
index c753c00e8..3ed42dbfc 100644
--- a/postfix/src/trivial-rewrite/trivial-rewrite.c
+++ b/postfix/src/trivial-rewrite/trivial-rewrite.c
@@ -181,7 +181,7 @@ static void rewrite_service(VSTREAM *stream, char *unused_service, char **argv)
* dedicated to address rewriting. All connection-management stuff is
* handled by the common code in multi_server.c.
*/
- if (attr_scan(stream, ATTR_FLAG_MISSING | ATTR_FLAG_EXTRA | ATTR_FLAG_MORE,
+ if (attr_scan(stream, ATTR_FLAG_STRICT | ATTR_FLAG_MORE,
ATTR_TYPE_STR, MAIL_ATTR_REQ, command,
ATTR_TYPE_END) == 1) {
if (strcmp(vstring_str(command), REWRITE_ADDR) == 0) {
diff --git a/postfix/src/util/Makefile.in b/postfix/src/util/Makefile.in
index 07ceade69..b31dc93aa 100644
--- a/postfix/src/util/Makefile.in
+++ b/postfix/src/util/Makefile.in
@@ -315,7 +315,8 @@ stream_test: stream_test.c $(LIB)
$(CC) $(CFLAGS) -o $@ $@.c $(LIB) $(SYSLIBS)
tests: valid_hostname_test mac_expand_test dict_test unescape_test \
- hex_quote_test ctable_test inet_addr_list_test base64_code_test
+ hex_quote_test ctable_test inet_addr_list_test base64_code_test \
+ attr_scan_test
valid_hostname_test: valid_hostname valid_hostname.in valid_hostname.ref
./valid_hostname valid_hostname.tmp
@@ -351,6 +352,11 @@ inet_addr_list_test: inet_addr_list
base64_code_test: base64_code
./base64_code
+attr_scan_test: attr_print attr_scan attr_scan.ref
+ (./attr_print 2>&3 | (sleep 1; ./attr_scan)) >attr_scan.tmp 2>&1 3>&1
+ diff attr_scan.ref attr_scan.tmp
+ rm -f attr_scan.tmp
+
DB_TYPE = `../postconf/postconf -h default_database_type`
dict_test: dict_open testdb dict_test.in dict_test.ref
@@ -375,14 +381,6 @@ argv_split.o: stringops.h
argv_split.o: vstring.h
argv_split.o: vbuf.h
argv_split.o: argv.h
-attr.o: attr.c
-attr.o: sys_defs.h
-attr.o: msg.h
-attr.o: mymalloc.h
-attr.o: htable.h
-attr.o: attr.h
-attr.o: vstream.h
-attr.o: vbuf.h
attr_print.o: attr_print.c
attr_print.o: sys_defs.h
attr_print.o: msg.h
@@ -400,23 +398,9 @@ attr_scan.o: mymalloc.h
attr_scan.o: vstream.h
attr_scan.o: vbuf.h
attr_scan.o: vstring.h
-attr_scan.o: argv.h
-attr_scan.o: intv.h
+attr_scan.o: htable.h
attr_scan.o: base64_code.h
attr_scan.o: attr.h
-attr_scan.o: htable.h
-attr_table.o: attr_table.c
-attr_table.o: sys_defs.h
-attr_table.o: msg.h
-attr_table.o: htable.h
-attr_table.o: mymalloc.h
-attr_table.o: vstring.h
-attr_table.o: vbuf.h
-attr_table.o: vstream.h
-attr_table.o: vstring_vstream.h
-attr_table.o: argv.h
-attr_table.o: intv.h
-attr_table.o: attr.h
base64_code.o: base64_code.c
base64_code.o: sys_defs.h
base64_code.o: msg.h
diff --git a/postfix/src/util/attr.h b/postfix/src/util/attr.h
index 534f98314..1033b53b3 100644
--- a/postfix/src/util/attr.h
+++ b/postfix/src/util/attr.h
@@ -1,5 +1,5 @@
-#ifndef _ATTR_PRINT_H_INCLUDED_
-#define _ATTR_PRINT_H_INCLUDED_
+#ifndef _ATTR_H_INCLUDED_
+#define _ATTR_H_INCLUDED_
/*++
/* NAME
@@ -20,22 +20,24 @@
* Utility library.
*/
#include
-#include
/*
- * External interface.
+ * Attribute types. See attr_scan(3) for documentation.
*/
#define ATTR_TYPE_END 0 /* end of data */
#define ATTR_TYPE_NUM 1 /* Unsigned integer */
#define ATTR_TYPE_STR 2 /* Character string */
-#define ATTR_TYPE_NUM_ARRAY 3 /* Unsigned integer sequence */
-#define ATTR_TYPE_STR_ARRAY 4 /* Character string sequence */
-#define ATTR_TYPE_HASH 5 /* Hash table */
+#define ATTR_TYPE_HASH 3 /* Hash table */
+ /*
+ * Flags that control processing. See attr_scan(3) for documentation.
+ */
#define ATTR_FLAG_NONE 0
#define ATTR_FLAG_MISSING (1<<0) /* Flag missing attribute */
#define ATTR_FLAG_EXTRA (1<<1) /* Flag spurious attribute */
#define ATTR_FLAG_MORE (1<<2) /* Don't skip or terminate */
+
+#define ATTR_FLAG_STRICT (ATTR_FLAG_MISSING | ATTR_FLAG_EXTRA)
#define ATTR_FLAG_ALL (07)
/*
@@ -57,8 +59,6 @@ extern int attr_vscan(VSTREAM *, int, va_list);
#ifdef TEST
#define ATTR_NAME_NUM "number"
#define ATTR_NAME_STR "string"
-#define ATTR_NAME_NUM_ARRAY "number_array"
-#define ATTR_NAME_STR_ARRAY "string_array"
#endif
/* LICENSE
diff --git a/postfix/src/util/attr_print.c b/postfix/src/util/attr_print.c
index 8d5e51112..fe38ea6fd 100644
--- a/postfix/src/util/attr_print.c
+++ b/postfix/src/util/attr_print.c
@@ -50,13 +50,6 @@
/* .IP "ATTR_TYPE_STR (char *, char *)"
/* This argument is followed by an attribute name and a null-terminated
/* string.
-/* .IP "ATTR_TYPE_NUM_ARRAY (char *, int, int *)"
-/* This argument is followed by an attribute name, an integer array
-/* element count, and a pointer to integer.
-/* .IP "ATTR_TYPE_NUM_ARRAY (char *, int, char **)"
-/* This argument is followed by an attribute name, an integer array
-/* element count, and a pointer to a null-terminated array of
-/* null-terminated strings.
/* .IP "ATTR_TYPE_HASH (HTABLE *)"
/* The content of the hash table is sent as a sequence of string-valued
/* attributes with names equal to the hash table lookup key.
@@ -131,10 +124,6 @@ int attr_vprint(VSTREAM *fp, int flags, va_list ap)
char *attr_name;
unsigned int_val;
char *str_val;
- char **cpp_val;
- unsigned *ip_val;
- int count_val;
- int i;
HTABLE_INFO **ht_info_list;
HTABLE_INFO **ht;
@@ -142,8 +131,7 @@ int attr_vprint(VSTREAM *fp, int flags, va_list ap)
* Sanity check.
*/
if (flags & ~ATTR_FLAG_ALL)
- msg_panic("%s: bad flags: 0x%x",
- myname, flags);
+ msg_panic("%s: bad flags: 0x%x", myname, flags);
/*
* Iterate over all (type, name, value) triples, and produce output on
@@ -169,30 +157,6 @@ int attr_vprint(VSTREAM *fp, int flags, va_list ap)
if (msg_verbose)
msg_info("send attr %s = %s", attr_name, str_val);
break;
- case ATTR_TYPE_NUM_ARRAY:
- attr_name = va_arg(ap, char *);
- attr_print_str(fp, attr_name, strlen(attr_name));
- ip_val = va_arg(ap, unsigned int *);
- count_val = va_arg(ap, int);
- for (i = 0; i < count_val; i++) {
- VSTREAM_PUTC(':', fp);
- attr_print_num(fp, (unsigned) *ip_val++);}
- if (msg_verbose)
- msg_info("send attr %s values %d", attr_name, count_val);
- break;
- case ATTR_TYPE_STR_ARRAY:
- attr_name = va_arg(ap, char *);
- attr_print_str(fp, attr_name, strlen(attr_name));
- cpp_val = va_arg(ap, char **);
- count_val = va_arg(ap, int);
- for (i = 0; i < count_val; i++) {
- str_val = *cpp_val++;
- VSTREAM_PUTC(':', fp);
- attr_print_str(fp, str_val, strlen(str_val));
- }
- if (msg_verbose)
- msg_info("send attr %s values %d", attr_name, count_val);
- break;
case ATTR_TYPE_HASH:
ht_info_list = htable_list(va_arg(ap, HTABLE *));
for (ht = ht_info_list; *ht; ht++) {
@@ -236,31 +200,22 @@ int attr_print(VSTREAM *fp, int flags,...)
*/
#include
-int main(int argc, char **argv)
+int main(int unused_argc, char **argv)
{
- static int int_array[] = {0, 1, 2, 3, 4, 5, 6, 7};
- static char *str_array[] = {"a", "b", "c", "d", "e", "f", "g", "h"};
HTABLE *table = htable_create(1);
msg_vstream_init(argv[0], VSTREAM_ERR);
+ msg_verbose = 1;
htable_enter(table, "foo-name", mystrdup("foo-value"));
htable_enter(table, "bar-name", mystrdup("bar-value"));
attr_print(VSTREAM_OUT, ATTR_FLAG_NONE,
ATTR_TYPE_NUM, ATTR_NAME_NUM, 4711,
ATTR_TYPE_STR, ATTR_NAME_STR, "whoopee",
- ATTR_TYPE_NUM_ARRAY, ATTR_NAME_NUM_ARRAY,
- int_array, sizeof(int_array) / sizeof(int_array[0]),
- ATTR_TYPE_STR_ARRAY, ATTR_NAME_STR_ARRAY,
- str_array, sizeof(str_array) / sizeof(str_array[0]),
ATTR_TYPE_HASH, table,
ATTR_TYPE_END);
attr_print(VSTREAM_OUT, ATTR_FLAG_NONE,
ATTR_TYPE_NUM, ATTR_NAME_NUM, 4711,
ATTR_TYPE_STR, ATTR_NAME_STR, "whoopee",
- ATTR_TYPE_NUM_ARRAY, ATTR_NAME_NUM_ARRAY,
- int_array, sizeof(int_array) / sizeof(int_array[0]),
- ATTR_TYPE_STR_ARRAY, ATTR_NAME_STR_ARRAY,
- str_array, sizeof(str_array) / sizeof(str_array[0]),
ATTR_TYPE_END);
if (vstream_fflush(VSTREAM_OUT) != 0)
msg_fatal("write error: %m");
diff --git a/postfix/src/util/attr_scan.c b/postfix/src/util/attr_scan.c
index 4098cfb44..2f6267b99 100644
--- a/postfix/src/util/attr_scan.c
+++ b/postfix/src/util/attr_scan.c
@@ -17,9 +17,9 @@
/* int flags;
/* va_list ap;
/* DESCRIPTION
-/* attr_scan() takes zero or more (name, value) scalar or array
-/* attribute arguments, and recovers the attribute values from the
-/* byte stream that was generated by attr_print().
+/* attr_scan() takes zero or more (name, value) request attributes
+/* and recovers the attribute values from the byte stream that was
+/* possibly generated by attr_print().
/*
/* attr_vscan() provides an alternative interface that is convenient
/* for calling from within a variadic function.
@@ -29,14 +29,10 @@
/* (item1 | item2) stands for choice:
/*
/* .in +5
-/* input :== attr-list
-/* .br
-/* attr-list :== (simple-attr | list-attr)* newline
+/* attr-list :== simple-attr* newline
/* .br
/* simple-attr :== attr-name colon attr-value newline
/* .br
-/* list-attr :== attr-name (colon attr-value)* newline
-/* .br
/* attr-name :== any base64 encoded string
/* .br
/* attr-value :== any base64 encoded string
@@ -46,24 +42,25 @@
/* newline :== the ASCII newline character
/* .in
/*
-/* All character values are 7-bit ASCII. All attribute names and
-/* attribute values are sent as base64-encoded strings. The
-/* formatting rules aim to make implementations in PERL and other
-/* non-C languages easy.
+/* All attribute names and attribute values are sent as base64-encoded
+/* strings. Each base64-encoded must be no longer than 2*var_line_limit
+/* characters. The formatting rules aim to make implementations in PERL
+/* and other languages easy.
/*
-/* Attributes must be sent in the requested order as specified with
-/* the attr_scan() argument list. The input stream may contain
-/* additional attributes at any point in the input stream, including
-/* additional instances of requested attributes.
+/* Normally, attributes must be received in the sequence as specified with
+/* the attr_scan() argument list. The input stream may contain additional
+/* attributes at any point in the input stream, including additional
+/* instances of requested attributes.
/*
-/* Additional attributes are silently skipped over, unless the
-/* ATTR_FLAG_EXTRA processing flag is specified (see below). This
-/* allows for some flexibility in the evolution of protocols while
-/* still providing the option of being strict where desirable.
+/* Additional input attributes or input attribute instances are silently
+/* skipped over, unless the ATTR_FLAG_EXTRA processing flag is specified
+/* (see below). This allows for some flexibility in the evolution of
+/* protocols while still providing the option of being strict where
+/* this is desirable.
/*
/* Arguments:
/* .IP fp
-/* Stream to recover the attributes from.
+/* Stream to recover the input attributes from.
/* .IP flags
/* The bit-wise OR of zero or more of the following.
/* .RS
@@ -73,14 +70,17 @@
/* input stream ends without the newline attribute list terminator.
/* .IP ATTR_FLAG_EXTRA
/* Log a warning and stop attribute recovery when the input stream
-/* contains an attribute that was not requested. This includes multiple
-/* instances of the same attribute when only one instance is requested.
+/* contains an attribute that was not requested. This includes the
+/* case of additional instances of a requested attribute.
/* .IP ATTR_FLAG_MORE
/* After recovering the requested attributes, leave the input stream
-/* in a state that is usable for more recovery operations on the
+/* in a state that is usable for more attr_scan() operations from the
/* same input attribute list.
-/* By default, attr_scan() skips forward past the attribute list
+/* By default, attr_scan() skips forward past the input attribute list
/* terminator.
+/* .IP ATTR_FLAG_STRICT
+/* For convenience, this value combines both ATTR_FLAG_MISSING and
+/* ATTR_FLAG_EXTRA.
/* .IP ATTR_FLAG_NONE
/* For convenience, this value requests none of the above.
/* .RE
@@ -89,24 +89,15 @@
/* .RS
/* .IP "ATTR_TYPE_NUM (char *, int *)"
/* This argument is followed by an attribute name and an integer pointer.
-/* This is used for recovering one simple integer attribute value.
/* .IP "ATTR_TYPE_STR (char *, VSTRING *)"
/* This argument is followed by an attribute name and a VSTRING pointer.
-/* This is used for recovering one simple string attribute value.
-/* .IP "ATTR_TYPE_NUM_ARRAY (char *, INTV *)"
-/* This argument is followed by an attribute name and an INTV pointer.
-/* This is used for recovering an integer array attribute value.
-/* Values from the input stream are appended to the array.
-/* .IP "ATTR_TYPE_NUM_ARRAY (char *, ARGV *)"
-/* This argument is followed by an attribute name and an ARGV pointer.
-/* This is used for recovering a string array attribute value.
-/* Values from the input stream are appended to the array.
/* .IP "ATTR_TYPE_HASH (HTABLE *)"
-/* All further input attributes are required to be simple string or
-/* integer attributes.
-/* Their string values are stored in the specified hash table under
+/* All further input attributes are processed as string attributes.
+/* In this case, no specific attribute sequence is enforced.
+/* .sp
+/* The attribute string values are stored in the hash table under
/* keys equal to the attribute name (obtained from the input stream).
-/* Values from the input stream are added to the hash table, but existing
+/* Values from the input stream are added to the hash table. Existing
/* hash table entries are not replaced.
/* .sp
/* N.B. This construct must be followed by an ATTR_TYPE_END argument.
@@ -114,14 +105,15 @@
/* This argument terminates the requested attribute list.
/* .RE
/* BUGS
-/* ATTR_TYPE_HASH accepts attributes with arbitrary names from an
+/* ATTR_TYPE_HASH accepts attributes with arbitrary names from an
/* untrusted source. This is safe only if the resulting table is
-/* queried for specific names.
+/* queried only with known to be good attribute names.
/* DIAGNOSTICS
-/* The result value is the number of attributes that were successfully
-/* recovered from the input stream (an array-valued attribute counts
-/* as one attribute; a hash table counts as the number of entries in
-/* the table).
+/* attr_scan() and attr_vscan() return -1 when malformed input is
+/* detected (string too long, incomplete line, missing end marker).
+/* Otherwise, the result value is the number of attributes that were
+/* successfully recovered from the input stream (a hash table counts
+/* as the number of entries stored into the table).
/*
/* Panic: interface violation. All system call errors are fatal.
/* SEE ALSO
@@ -149,8 +141,7 @@
#include
#include
#include
-#include
-#include
+#include
#include
#include
@@ -164,12 +155,8 @@
static int attr_scan_string(VSTREAM *fp, VSTRING *plain_buf, const char *context)
{
static VSTRING *base64_buf = 0;
-
-#if 0
extern int var_line_limit; /* XXX */
- int limit = var_line_limit * 5 / 4;
-
-#endif
+ int limit = var_line_limit * 2;
int ch;
if (base64_buf == 0)
@@ -183,13 +170,11 @@ static int attr_scan_string(VSTREAM *fp, VSTRING *plain_buf, const char *context
return (-1);
}
VSTRING_ADDCH(base64_buf, ch);
-#if 0
if (LEN(base64_buf) > limit) {
msg_warn("string length > %d characters from %s while reading %s",
limit, VSTREAM_PATH(fp), context);
return (-1);
}
-#endif
}
VSTRING_TERMINATE(base64_buf);
if (base64_decode(plain_buf, STR(base64_buf), LEN(base64_buf)) == 0) {
@@ -198,7 +183,7 @@ static int attr_scan_string(VSTREAM *fp, VSTRING *plain_buf, const char *context
return (-1);
}
if (msg_verbose)
- msg_info("%s: %s", context, STR(plain_buf));
+ msg_info("%s: %s", context, *STR(plain_buf) ? STR(plain_buf) : "(end)");
return (ch);
}
@@ -231,10 +216,7 @@ int attr_vscan(VSTREAM *fp, int flags, va_list ap)
char *wanted_name;
unsigned int *number;
VSTRING *string;
- INTV *number_array;
- ARGV *string_array;
HTABLE *hash_table;
- unsigned num_val;
int ch;
int conversions;
@@ -242,8 +224,7 @@ int attr_vscan(VSTREAM *fp, int flags, va_list ap)
* Sanity check.
*/
if (flags & ~ATTR_FLAG_ALL)
- msg_panic("%s: bad flags: 0x%x",
- myname, flags);
+ msg_panic("%s: bad flags: 0x%x", myname, flags);
/*
* Initialize.
@@ -265,16 +246,16 @@ int attr_vscan(VSTREAM *fp, int flags, va_list ap)
* If we're reading into a hash table, we already know that the
* attribute value is string-valued, and we get the attribute name
* from the input stream instead. This is secure only when the
- * resulting table is queried with explicitly named attributes.
+ * resulting table is queried with known to be good attribute names.
*/
if (wanted_type != ATTR_TYPE_HASH) {
wanted_type = va_arg(ap, int);
if (wanted_type == ATTR_TYPE_END) {
if ((flags & ATTR_FLAG_MORE) != 0)
return (conversions);
- wanted_name = "attribute list terminator";
+ wanted_name = "list terminator";
} else if (wanted_type == ATTR_TYPE_HASH) {
- wanted_name = "any attribute name";
+ wanted_name = "(any attribute name or list terminator)";
hash_table = va_arg(ap, HTABLE *);
if (va_arg(ap, int) !=ATTR_TYPE_END)
msg_panic("%s: ATTR_TYPE_HASH not followed by ATTR_TYPE_END",
@@ -290,13 +271,16 @@ int attr_vscan(VSTREAM *fp, int flags, va_list ap)
for (;;) {
/*
- * Get the name of the next attribute. Hitting the end-of-input
- * early is OK if the caller is prepared to deal with missing
- * inputs.
+ * Get the name of the next attribute. Hitting EOF is always bad.
+ * Hitting the end-of-input early is OK if the caller is prepared
+ * to deal with missing inputs.
*/
+ if (msg_verbose)
+ msg_info("%s: wanted attribute: %s",
+ VSTREAM_PATH(fp), wanted_name);
if ((ch = attr_scan_string(fp, name_buf,
- "attribute name")) == VSTREAM_EOF)
- return (conversions);
+ "input attribute name")) == VSTREAM_EOF)
+ return (-1);
if (ch == '\n' && LEN(name_buf) == 0) {
if (wanted_type == ATTR_TYPE_END
|| wanted_type == ATTR_TYPE_HASH)
@@ -306,9 +290,6 @@ int attr_vscan(VSTREAM *fp, int flags, va_list ap)
wanted_name, VSTREAM_PATH(fp));
return (conversions);
}
- if (msg_verbose)
- msg_info("want attribute %s, found attribute: %s",
- wanted_name, STR(name_buf));
/*
* See if the caller asks for this attribute.
@@ -343,45 +324,47 @@ int attr_vscan(VSTREAM *fp, int flags, va_list ap)
if (ch != ':') {
msg_warn("missing value for number attribute %s from %s",
STR(name_buf), VSTREAM_PATH(fp));
- return (conversions);
+ return (-1);
}
number = va_arg(ap, unsigned int *);
if ((ch = attr_scan_number(fp, number, str_buf,
- "attribute value")) < 0)
- return (conversions);
+ "input attribute value")) < 0)
+ return (-1);
if (ch != '\n') {
msg_warn("multiple values for attribute %s from %s",
STR(name_buf), VSTREAM_PATH(fp));
- return (conversions);
+ return (-1);
}
break;
case ATTR_TYPE_STR:
if (ch != ':') {
msg_warn("missing value for string attribute %s from %s",
STR(name_buf), VSTREAM_PATH(fp));
- return (conversions);
+ return (-1);
}
string = va_arg(ap, VSTRING *);
- if ((ch = attr_scan_string(fp, string, "attribute value")) < 0)
- return (conversions);
+ if ((ch = attr_scan_string(fp, string,
+ "input attribute value")) < 0)
+ return (-1);
if (ch != '\n') {
msg_warn("multiple values for attribute %s from %s",
STR(name_buf), VSTREAM_PATH(fp));
- return (conversions);
+ return (-1);
}
break;
case ATTR_TYPE_HASH:
if (ch != ':') {
msg_warn("missing value for string attribute %s from %s",
STR(name_buf), VSTREAM_PATH(fp));
- return (conversions);
+ return (-1);
}
- if ((ch = attr_scan_string(fp, str_buf, "attribute value")) < 0)
- return (conversions);
+ if ((ch = attr_scan_string(fp, str_buf,
+"input attribute value")) < 0)
+ return (-1);
if (ch != '\n') {
msg_warn("multiple values for attribute %s from %s",
STR(name_buf), VSTREAM_PATH(fp));
- return (conversions);
+ return (-1);
}
if (htable_locate(hash_table, STR(name_buf)) != 0) {
if ((flags & ATTR_FLAG_EXTRA) != 0) {
@@ -394,23 +377,6 @@ int attr_vscan(VSTREAM *fp, int flags, va_list ap)
mystrdup(STR(str_buf)));
}
break;
- case ATTR_TYPE_NUM_ARRAY:
- number_array = va_arg(ap, INTV *);
- while (ch != '\n') {
- if ((ch = attr_scan_number(fp, &num_val, str_buf,
- "attribute value")) < 0)
- return (conversions);
- intv_add(number_array, 1, num_val);
- }
- break;
- case ATTR_TYPE_STR_ARRAY:
- string_array = va_arg(ap, ARGV *);
- while (ch != '\n') {
- if ((ch = attr_scan_string(fp, str_buf, "attribute value")) < 0)
- return (conversions);
- argv_add(string_array, STR(str_buf), (char *) 0);
- }
- break;
default:
msg_panic("%s: unknown type code: %d", myname, wanted_type);
}
@@ -442,36 +408,23 @@ int var_line_limit = 2048;
int main(int unused_argc, char **used_argv)
{
- INTV *intv = intv_alloc(1);
- ARGV *argv = argv_alloc(1);
VSTRING *str_val = vstring_alloc(1);
HTABLE *table = htable_create(1);
HTABLE_INFO **ht_info_list;
HTABLE_INFO **ht;
int int_val;
int ret;
- int i;
msg_verbose = 1;
msg_vstream_init(used_argv[0], VSTREAM_ERR);
if ((ret = attr_scan(VSTREAM_IN,
- ATTR_FLAG_MISSING | ATTR_FLAG_EXTRA,
+ ATTR_FLAG_STRICT,
ATTR_TYPE_NUM, ATTR_NAME_NUM, &int_val,
ATTR_TYPE_STR, ATTR_NAME_STR, str_val,
- ATTR_TYPE_NUM_ARRAY, ATTR_NAME_NUM_ARRAY, intv,
- ATTR_TYPE_STR_ARRAY, ATTR_NAME_STR_ARRAY, argv,
ATTR_TYPE_HASH, table,
- ATTR_TYPE_END)) > 4) {
+ ATTR_TYPE_END)) > 2) {
vstream_printf("%s %d\n", ATTR_NAME_NUM, int_val);
vstream_printf("%s %s\n", ATTR_NAME_STR, STR(str_val));
- vstream_printf("%s", ATTR_NAME_NUM_ARRAY);
- for (i = 0; i < intv->intc; i++)
- vstream_printf(" %d", intv->intv[i]);
- vstream_printf("\n");
- vstream_printf("%s", ATTR_NAME_STR_ARRAY);
- for (i = 0; i < argv->argc; i++)
- vstream_printf(" %s", argv->argv[i]);
- vstream_printf("\n");
ht_info_list = htable_list(table);
for (ht = ht_info_list; *ht; ht++)
vstream_printf("(hash) %s %s\n", ht[0]->key, ht[0]->value);
@@ -480,22 +433,12 @@ int main(int unused_argc, char **used_argv)
vstream_printf("return: %d\n", ret);
}
if ((ret = attr_scan(VSTREAM_IN,
- ATTR_FLAG_MISSING | ATTR_FLAG_EXTRA,
+ ATTR_FLAG_STRICT,
ATTR_TYPE_NUM, ATTR_NAME_NUM, &int_val,
ATTR_TYPE_STR, ATTR_NAME_STR, str_val,
- ATTR_TYPE_NUM_ARRAY, ATTR_NAME_NUM_ARRAY, intv,
- ATTR_TYPE_STR_ARRAY, ATTR_NAME_STR_ARRAY, argv,
- ATTR_TYPE_END)) == 4) {
+ ATTR_TYPE_END)) == 2) {
vstream_printf("%s %d\n", ATTR_NAME_NUM, int_val);
vstream_printf("%s %s\n", ATTR_NAME_STR, STR(str_val));
- vstream_printf("%s", ATTR_NAME_NUM_ARRAY);
- for (i = 0; i < intv->intc; i++)
- vstream_printf(" %d", intv->intv[i]);
- vstream_printf("\n");
- vstream_printf("%s", ATTR_NAME_STR_ARRAY);
- for (i = 0; i < argv->argc; i++)
- vstream_printf(" %s", argv->argv[i]);
- vstream_printf("\n");
ht_info_list = htable_list(table);
for (ht = ht_info_list; *ht; ht++)
vstream_printf("(hash) %s %s\n", ht[0]->key, ht[0]->value);
@@ -506,8 +449,6 @@ int main(int unused_argc, char **used_argv)
if (vstream_fflush(VSTREAM_OUT) != 0)
msg_fatal("write error: %m");
- intv_free(intv);
- argv_free(argv);
vstring_free(str_val);
htable_free(table, myfree);
diff --git a/postfix/src/util/attr_scan.ref b/postfix/src/util/attr_scan.ref
new file mode 100644
index 000000000..fb02bd5e2
--- /dev/null
+++ b/postfix/src/util/attr_scan.ref
@@ -0,0 +1,36 @@
+./attr_print: send attr number = 4711
+./attr_print: send attr string = whoopee
+./attr_print: send attr name foo-name value foo-value
+./attr_print: send attr name bar-name value bar-value
+./attr_print: send attr number = 4711
+./attr_print: send attr string = whoopee
+./attr_scan: unknown_stream: wanted attribute: number
+./attr_scan: input attribute name: number
+./attr_scan: input attribute value: 4711
+./attr_scan: unknown_stream: wanted attribute: string
+./attr_scan: input attribute name: string
+./attr_scan: attribute value: whoopee
+./attr_scan: unknown_stream: wanted attribute: (any attribute name or list terminator)
+./attr_scan: input attribute name: foo-name
+./attr_scan: attribute value: foo-value
+./attr_scan: unknown_stream: wanted attribute: (any attribute name or list terminator)
+./attr_scan: input attribute name: bar-name
+./attr_scan: attribute value: bar-value
+./attr_scan: unknown_stream: wanted attribute: (any attribute name or list terminator)
+./attr_scan: input attribute name: (end)
+./attr_scan: unknown_stream: wanted attribute: number
+./attr_scan: input attribute name: number
+./attr_scan: input attribute value: 4711
+./attr_scan: unknown_stream: wanted attribute: string
+./attr_scan: input attribute name: string
+./attr_scan: attribute value: whoopee
+./attr_scan: unknown_stream: wanted attribute: list terminator
+./attr_scan: input attribute name: (end)
+number 4711
+string whoopee
+(hash) foo-name foo-value
+(hash) bar-name bar-value
+number 4711
+string whoopee
+(hash) foo-name foo-value
+(hash) bar-name bar-value
diff --git a/postfix/src/util/base64_code.c b/postfix/src/util/base64_code.c
index 443bf43c6..469b1c0fa 100644
--- a/postfix/src/util/base64_code.c
+++ b/postfix/src/util/base64_code.c
@@ -159,9 +159,9 @@ int main(int unused_argc, char **unused_argv)
VSTRING *b2 = vstring_alloc(1);
char *test = "this is a test";
-#define DECODE(b,s,l) { \
- if (base64_decode((b),(s),(l)) == 0) \
- msg_panic("bad base64: %s", (s)); \
+#define DECODE(b,x,l) { \
+ if (base64_decode((b),(x),(l)) == 0) \
+ msg_panic("bad base64: %s", (x)); \
}
#define VERIFY(b,t) { \
if (strcmp((b), (t)) != 0) \
diff --git a/postfix/src/util/dict.h b/postfix/src/util/dict.h
index 5a669aa09..1d9d8c4a1 100644
--- a/postfix/src/util/dict.h
+++ b/postfix/src/util/dict.h
@@ -55,6 +55,7 @@ extern DICT *dict_debug(DICT *);
#define DICT_FLAG_DUP_REPLACE (1<<7) /* if file, replace dups */
#define DICT_FLAG_SYNC_UPDATE (1<<8) /* if file, sync updates */
#define DICT_FLAG_DEBUG (1<<9) /* log access */
+#define DICT_FLAG_FOLD_KEY (1<<10) /* lowercase the lookup key */
extern int dict_unknown_allowed;
extern int dict_errno;
diff --git a/postfix/src/util/dict_open.c b/postfix/src/util/dict_open.c
index 2c15ac897..a13806f7f 100644
--- a/postfix/src/util/dict_open.c
+++ b/postfix/src/util/dict_open.c
@@ -81,6 +81,8 @@
/* .IP DICT_FLAG_SYNC_UPDATE
/* With file-based maps, flush I/O buffers to file after each update.
/* Thus feature is not supported with some file-based dictionaries.
+/* .IP DICT_FLAG_FOLD_KEY
+/* Fold the lookup key to lower case.
/* .PP
/* The dictionary types are as follows:
/* .IP environ