2
0
mirror of https://github.com/vdukhovni/postfix synced 2025-08-29 13:18:12 +00:00

snapshot-20011102

This commit is contained in:
Wietse Venema 2001-11-02 00:00:00 -05:00 committed by Viktor Dukhovni
parent 7b1a87549e
commit d28c0616eb
61 changed files with 318 additions and 1076 deletions

View File

@ -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.

View File

@ -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

View File

@ -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
====================================

View File

@ -6,7 +6,7 @@ POSTALIAS(1) POSTALIAS(1)
postalias - Postfix alias database maintenance
<b>SYNOPSIS</b>
<b>postalias</b> [<b>-Ninrvw</b>] [<b>-c</b> <i>config_dir</i>] [<b>-d</b> <i>key</i>] [<b>-q</b> <i>key</i>]
<b>postalias</b> [<b>-Nfinrvw</b>] [<b>-c</b> <i>config_dir</i>] [<b>-d</b> <i>key</i>] [<b>-q</b> <i>key</i>]
[<i>file_type</i>:]<i>file_name</i> ...
<b>DESCRIPTION</b>
@ -42,35 +42,38 @@ POSTALIAS(1) POSTALIAS(1)
status is zero when at least one of the requested
keys was found.
<b>-i</b> Incremental mode. Read entries from standard input
<b>-f</b> Do not fold the lookup key to lower case while cre-
ating a map.
<b>-i</b> Incremental mode. Read entries from standard input
and do not truncate an existing database. By
default, <b>postalias</b> creates a new database from the
default, <b>postalias</b> creates a new database from the
entries in <b>file</b><i>_</i><b>name</b>.
<b>-n</b> Don't include the terminating null character that
terminates lookup keys and values. By default,
Postfix does whatever is the default for the host
<b>-n</b> 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.
<b>-q</b> <i>key</i> Search the specified maps for <i>key</i> and print the
first value found on the standard output stream.
<b>-q</b> <i>key</i> Search the specified maps for <i>key</i> 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 <b>-</b> is specified, the program reads
key values from the standard input stream and
prints one line of <i>key:</i> <i>value</i> 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 <i>key:</i> <i>value</i> output for each key
that was found. The exit status is zero when at
least one of the requested keys was found.
<b>-r</b> When updating a table, do not warn about duplicate
<b>-r</b> When updating a table, do not warn about duplicate
entries; silently replace them.
<b>-v</b> Enable verbose logging for debugging purposes. Mul-
tiple <b>-v</b> options make the software increasingly
tiple <b>-v</b> options make the software increasingly
verbose.
<b>-w</b> When updating a table, do not warn about duplicate
<b>-w</b> When updating a table, do not warn about duplicate
entries; silently ignore them.
Arguments:
@ -78,35 +81,35 @@ POSTALIAS(1) POSTALIAS(1)
<i>file_type</i>
The type of database to be produced.
<b>btree</b> The output is a btree file, named
<i>file_name</i><b>.db</b>. This is available only on
systems with support for <b>db</b> databases.
<b>dbm</b> The output consists of two files, named
<i>file_name</i><b>.pag</b> and <i>file_name</i><b>.dir</b>. This is
available only on systems with support for
<b>dbm</b> databases.
<b>hash</b> The output is a hashed file, named
<b>btree</b> The output is a btree file, named
<i>file_name</i><b>.db</b>. This is available only on
systems with support for <b>db</b> databases.
When no <i>file_type</i> is specified, the software uses
the database type specified via the <b>database</b><i>_</i><b>type</b>
configuration parameter. The default value for
<b>dbm</b> The output consists of two files, named
<i>file_name</i><b>.pag</b> and <i>file_name</i><b>.dir</b>. This is
available only on systems with support for
<b>dbm</b> databases.
<b>hash</b> The output is a hashed file, named
<i>file_name</i><b>.db</b>. This is available only on
systems with support for <b>db</b> databases.
When no <i>file_type</i> is specified, the software uses
the database type specified via the <b>database</b><i>_</i><b>type</b>
configuration parameter. The default value for
this parameter depends on the host environment.
<i>file_name</i>
The name of the alias database source file when
The name of the alias database source file when
rebuilding a database.
<b>DIAGNOSTICS</b>
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.
<b>postalias</b> terminates with zero exit status in case of suc-
cess (including successful <b>postmap</b> <b>-q</b> lookup) and termi-
cess (including successful <b>postmap</b> <b>-q</b> lookup) and termi-
nates with non-zero exit status in case of failure.
<b>ENVIRONMENT</b>
@ -117,12 +120,12 @@ POSTALIAS(1) POSTALIAS(1)
Enable verbose logging for debugging purposes.
<b>CONFIGURATION</b> <b>PARAMETERS</b>
The following <b>main.cf</b> parameters are especially relevant
to this program. See the Postfix <b>main.cf</b> file for syntax
The following <b>main.cf</b> parameters are especially relevant
to this program. See the Postfix <b>main.cf</b> file for syntax
details and for default values.
<b>database</b><i>_</i><b>type</b>
Default alias database type. On many UNIX systems,
Default alias database type. On many UNIX systems,
the default type is either <b>dbm</b> or <b>hash</b>.
<b>STANDARDS</b>
@ -133,7 +136,7 @@ POSTALIAS(1) POSTALIAS(1)
<a href="sendmail.1.html">sendmail(1)</a> mail posting and compatibility interface.
<b>LICENSE</b>
The Secure Mailer license must be distributed with this
The Secure Mailer license must be distributed with this
software.
<b>AUTHOR(S)</b>

View File

@ -6,7 +6,7 @@ POSTMAP(1) POSTMAP(1)
postmap - Postfix lookup table management
<b>SYNOPSIS</b>
<b>postmap</b> [<b>-Ninrvw</b>] [<b>-c</b> <i>config_dir</i>] [<b>-d</b> <i>key</i>] [<b>-q</b> <i>key</i>]
<b>postmap</b> [<b>-Nfinrvw</b>] [<b>-c</b> <i>config_dir</i>] [<b>-d</b> <i>key</i>] [<b>-q</b> <i>key</i>]
[<i>file_type</i>:]<i>file_name</i> ...
<b>DESCRIPTION</b>
@ -61,35 +61,38 @@ POSTMAP(1) POSTMAP(1)
status is zero when at least one of the requested
keys was found.
<b>-i</b> Incremental mode. Read entries from standard input
<b>-f</b> Do not fold the lookup key to lower case while cre-
ating a map.
<b>-i</b> Incremental mode. Read entries from standard input
and do not truncate an existing database. By
default, <b>postmap</b> creates a new database from the
default, <b>postmap</b> creates a new database from the
entries in <b>file</b><i>_</i><b>name</b>.
<b>-n</b> Don't include the terminating null character that
terminates lookup keys and values. By default,
Postfix does whatever is the default for the host
<b>-n</b> 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.
<b>-q</b> <i>key</i> Search the specified maps for <i>key</i> and print the
first value found on the standard output stream.
<b>-q</b> <i>key</i> Search the specified maps for <i>key</i> 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 <b>-</b> is specified, the program reads
key values from the standard input stream and
prints one line of <i>key</i> <i>value</i> 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 <i>key</i> <i>value</i> output for each key
that was found. The exit status is zero when at
least one of the requested keys was found.
<b>-r</b> When updating a table, do not warn about duplicate
<b>-r</b> When updating a table, do not warn about duplicate
entries; silently replace them.
<b>-v</b> Enable verbose logging for debugging purposes. Mul-
tiple <b>-v</b> options make the software increasingly
tiple <b>-v</b> options make the software increasingly
verbose.
<b>-w</b> When updating a table, do not warn about duplicate
<b>-w</b> When updating a table, do not warn about duplicate
entries; silently ignore them.
Arguments:
@ -97,25 +100,25 @@ POSTMAP(1) POSTMAP(1)
<i>file_type</i>
The type of database to be produced.
<b>btree</b> The output file is a btree file, named
<i>file_name</i><b>.db</b>. This is available only on
systems with support for <b>db</b> databases.
<b>dbm</b> The output consists of two files, named
<i>file_name</i><b>.pag</b> and <i>file_name</i><b>.dir</b>. This is
available only on systems with support for
<b>dbm</b> databases.
<b>hash</b> The output file is a hashed file, named
<b>btree</b> The output file is a btree file, named
<i>file_name</i><b>.db</b>. This is available only on
systems with support for <b>db</b> databases.
When no <i>file_type</i> is specified, the software uses
the database type specified via the <b>database</b><i>_</i><b>type</b>
<b>dbm</b> The output consists of two files, named
<i>file_name</i><b>.pag</b> and <i>file_name</i><b>.dir</b>. This is
available only on systems with support for
<b>dbm</b> databases.
<b>hash</b> The output file is a hashed file, named
<i>file_name</i><b>.db</b>. This is available only on
systems with support for <b>db</b> databases.
When no <i>file_type</i> is specified, the software uses
the database type specified via the <b>database</b><i>_</i><b>type</b>
configuration parameter.
<i>file_name</i>
The name of the lookup table source file when
The name of the lookup table source file when
rebuilding a database.
<b>DIAGNOSTICS</b>
@ -123,8 +126,8 @@ POSTMAP(1) POSTMAP(1)
stream. No output means no problems. Duplicate entries are
skipped and are flagged with a warning.
<b>postmap</b> terminates with zero exit status in case of suc-
cess (including successful <b>postmap</b> <b>-q</b> lookup) and termi-
<b>postmap</b> terminates with zero exit status in case of suc-
cess (including successful <b>postmap</b> <b>-q</b> lookup) and termi-
nates with non-zero exit status in case of failure.
<b>ENVIRONMENT</b>
@ -136,12 +139,12 @@ POSTMAP(1) POSTMAP(1)
<b>CONFIGURATION</b> <b>PARAMETERS</b>
<b>database</b><i>_</i><b>type</b>
Default output database type. On many UNIX sys-
tems, the default database type is either <b>hash</b> or
Default output database type. On many UNIX sys-
tems, the default database type is either <b>hash</b> or
<b>dbm</b>.
<b>LICENSE</b>
The Secure Mailer license must be distributed with this
The Secure Mailer license must be distributed with this
software.
<b>AUTHOR(S)</b>

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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

View File

@ -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;

View File

@ -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;

View File

@ -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 {

View File

@ -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)));

View File

@ -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

View File

@ -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);
}

View File

@ -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) {

View File

@ -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);

View File

@ -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);

View File

@ -1,69 +0,0 @@
/*++
/* NAME
/* mail_command_read 3
/* SUMMARY
/* single-command server
/* SYNOPSIS
/* #include <mail_proto.h>
/*
/* 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 <sys_defs.h>
#include <stdlib.h> /* 44BSD stdarg.h uses abort() */
#include <stdarg.h>
#include <string.h>
/* Utility library. */
#include <vstring.h>
#include <vstream.h>
/* 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);
}

View File

@ -1,82 +0,0 @@
/*++
/* NAME
/* mail_command_write 3
/* SUMMARY
/* single-command client
/* SYNOPSIS
/* #include <mail_proto.h>
/*
/* 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 <sys_defs.h>
#include <stdlib.h> /* 44BSD stdarg.h uses abort() */
#include <stdarg.h>
/* Utility library. */
#include <vstream.h>
/* 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);
}

View File

@ -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);

View File

@ -1,206 +0,0 @@
/*++
/* NAME
/* mail_print 3
/* SUMMARY
/* intra-mail system write routine
/* SYNOPSIS
/* #include <mail_proto.h>
/*
/* 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 <sys_defs.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdarg.h>
#include <ctype.h>
/* Utility library. */
#include <msg.h>
#include <mymalloc.h>
#include <vstream.h>
/* 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);
}

View File

@ -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 <stdarg.h>
*/
extern int mail_vprint(VSTREAM *, const char *, va_list);
extern int mail_vscan(VSTREAM *, const char *, va_list);
/*
* Attribute names.
*/

View File

@ -1,272 +0,0 @@
/*++
/* NAME
/* mail_scan 3
/* SUMMARY
/* intra-mail read routine
/* SYNOPSIS
/* #include <mail_proto.h>
/*
/* 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 <sys_defs.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdarg.h>
#include <ctype.h>
/* Utility library. */
#include <msg.h>
#include <vstring.h>
#include <vstream.h>
#include <vstring_vstream.h>
#include <mymalloc.h>
/* 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);
}

View File

@ -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)

View File

@ -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

View File

@ -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,

View File

@ -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,

View File

@ -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))

View File

@ -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

View File

@ -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

View File

@ -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);

View File

@ -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

View File

@ -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

View File

@ -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) {

View File

@ -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

View File

@ -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,

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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

View File

@ -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) {

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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);

View File

@ -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)

View File

@ -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) {

View File

@ -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.in 2>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

View File

@ -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 <vstream.h>
#include <htable.h>
/*
* 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

View File

@ -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 <msg_vstream.h>
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");

View File

@ -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 <mymalloc.h>
#include <vstream.h>
#include <vstring.h>
#include <argv.h>
#include <intv.h>
#include <htable.h>
#include <base64_code.h>
#include <attr.h>
@ -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);

View File

@ -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

View File

@ -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) \

View File

@ -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;

View File

@ -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