]> git.ipfire.org Git - thirdparty/postfix.git/commitdiff
snapshot-20011102
authorWietse Venema <wietse@porcupine.org>
Fri, 2 Nov 2001 05:00:00 +0000 (00:00 -0500)
committerViktor Dukhovni <viktor@dukhovni.org>
Tue, 5 Feb 2013 06:27:32 +0000 (06:27 +0000)
61 files changed:
postfix/HISTORY
postfix/PORTING
postfix/RELEASE_NOTES
postfix/html/postalias.1.html
postfix/html/postmap.1.html
postfix/man/man1/postalias.1
postfix/man/man1/postmap.1
postfix/src/bounce/Makefile.in
postfix/src/bounce/bounce.c
postfix/src/cleanup/Makefile.in
postfix/src/cleanup/cleanup.c
postfix/src/cleanup/cleanup_api.c
postfix/src/cleanup/cleanup_message.c
postfix/src/flush/flush.c
postfix/src/global/Makefile.in
postfix/src/global/abounce.c
postfix/src/global/deliver_pass.c
postfix/src/global/deliver_request.c
postfix/src/global/mail_command_client.c
postfix/src/global/mail_command_read.c [deleted file]
postfix/src/global/mail_command_write.c [deleted file]
postfix/src/global/mail_connect.c
postfix/src/global/mail_print.c [deleted file]
postfix/src/global/mail_proto.h
postfix/src/global/mail_scan.c [deleted file]
postfix/src/global/mail_stream.c
postfix/src/global/mail_version.h
postfix/src/global/post_mail.c
postfix/src/global/resolve_clnt.c
postfix/src/global/rewrite_clnt.c
postfix/src/lmtp/Makefile.in
postfix/src/local/Makefile.in
postfix/src/local/forward.c
postfix/src/master/Makefile.in
postfix/src/nqmgr/Makefile.in
postfix/src/nqmgr/qmgr_deliver.c
postfix/src/pickup/Makefile.in
postfix/src/pickup/pickup.c
postfix/src/postalias/postalias.c
postfix/src/postdrop/Makefile.in
postfix/src/postkick/Makefile.in
postfix/src/postmap/postmap.c
postfix/src/qmgr/Makefile.in
postfix/src/qmgr/qmgr_deliver.c
postfix/src/qmqpd/Makefile.in
postfix/src/qmqpd/qmqpd.c
postfix/src/sendmail/Makefile.in
postfix/src/smtp/Makefile.in
postfix/src/smtpd/Makefile.in
postfix/src/trivial-rewrite/Makefile.in
postfix/src/trivial-rewrite/resolve.c
postfix/src/trivial-rewrite/rewrite.c
postfix/src/trivial-rewrite/trivial-rewrite.c
postfix/src/util/Makefile.in
postfix/src/util/attr.h
postfix/src/util/attr_print.c
postfix/src/util/attr_scan.c
postfix/src/util/attr_scan.ref [new file with mode: 0644]
postfix/src/util/base64_code.c
postfix/src/util/dict.h
postfix/src/util/dict_open.c

index 3bfe829449af4d62c1dd27153eff413f40fdddb5..b7972bc4950ad7bedc9c1c81f42a112895ef3bef 100644 (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.
index 2a494420bde4b6aa598c0c8cf50aa2fb249cc71a..672eff62e3e50478cf3798e8cc6f6a0bd0528d6b 100644 (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
index e7a70b177085db0acbb8490c4ffdabf008481e49..d28737876c2427a7a633e052a5fe4c8a62f000d9 100644 (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
 ====================================
index 8fbe2ce8c2953cd1d72eef33abdd40c4e64ea5c2..b1d6cf7d3acd7f7f5fbb598ebf995921d35004fa 100644 (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
+              <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>    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
+              <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
+              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>
index 9a43c2bbe668a75090f6216895709bf9969d007b..711f5d38b95c51d1b0965ec62c2e2b02bb0409cf 100644 (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
+              <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>    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
+              <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>
+              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>
index ac7da6d2e6befae9a32c918b86bc9b1877edf732..c7ec54dd6d6c3de9b39e6aa26a5bcf108f0e89c3 100644 (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
index 83f8cd4248f42ed1069573b9a833c0f202b7e626..b3d1e791f8f22d0299d4d8aca6ba4871414df63f 100644 (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
index e3769be8432878ad1a2f8d44727b6df1f89af8e2..66066c2330fbb7c4ad25c13c0727c9056addb332 100644 (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
index 03a137dadc4c84aa85bec5513ea7baf4bfd44e5f..3cb98cc00282241a32097f9e8e0244fafd365099 100644 (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;
index 46cb770ca4e53eb35d35bd649695efadfbdb7bc3..cec834caa001549902af7f788eb5984b7362adcf 100644 (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
index acdde16fdf16582918ea519c05c54099c8228b9d..28185986f94efd6ff0b0c02f39d566aaf067ba1f 100644 (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;
index f361f16e1b170287991702750bedc473a0bba459..b2e88eb2a447a2d4473567658f67b755df8a1385 100644 (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;
index e1742a760839ba0e3e67496b3ee953c342973e31..875ebb16ba22316a5538744ab437d86cc18d1b7d 100644 (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 {
index cf365545fe80253fe47449fc48914397261f22a3..9e3499cd005fbecc7c0baf5ff2658690255d4a40 100644 (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)));
index 0e0da10bfa0c7dd91e8bd3459bcb0dc102728fb5..c7548ebd17945b803f3ae62aa414b76fe379d14e 100644 (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
index f688864fa123b68783516dadb566be43b1fcde03..5cacccf5e8c7f83b6c7fb6adda45afb43cde15d7 100644 (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);
 }
index cd2d7e72a4ff400323c5863f813925855fb09504..cf4a614c2b44dcce6959653687e75a8ee44bff03 100644 (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) {
index fecf7e4ba61c22669e627d4f9d68efbc14a26d63..344276a1d4c0ac621378f66ef2cfa0aa2c98231f 100644 (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);
index cdb1422d0107a69f06658411c6b8420d1e3321e0..fc1c56c9efe8aab7b5bfb9d86c0b155dbbf33fba 100644 (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);
diff --git a/postfix/src/global/mail_command_read.c b/postfix/src/global/mail_command_read.c
deleted file mode 100644 (file)
index 74c7def..0000000
+++ /dev/null
@@ -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);
-}
diff --git a/postfix/src/global/mail_command_write.c b/postfix/src/global/mail_command_write.c
deleted file mode 100644 (file)
index e6e8557..0000000
+++ /dev/null
@@ -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);
-}
index 3e00d98387f6d3de61d0b356a2dd759e184e7258..a8ef96d1364785fd7fb590013163c3ada126c610 100644 (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);
diff --git a/postfix/src/global/mail_print.c b/postfix/src/global/mail_print.c
deleted file mode 100644 (file)
index 9dddc25..0000000
+++ /dev/null
@@ -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);
-}
index fe09056ad9445c5633219d1a574684c6bbdab182..adadcda60c98a956fd66558c2cdb1df462a5d48a 100644 (file)
 #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.
   */
  /*
   * 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.
   */
diff --git a/postfix/src/global/mail_scan.c b/postfix/src/global/mail_scan.c
deleted file mode 100644 (file)
index cc3de3f..0000000
+++ /dev/null
@@ -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);
-}
index 41ae0d38f8867685f17b24cde5f24bb8d7646109..ed58493da5c1bd801af9dab158bfd61bd7953837 100644 (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)
index 09831453a4cdc5231a07aa85db065dca39e657ec..34e4646f8f858e2e90df783619237d3827a17d97 100644 (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
index 122df98734c0b5ea7550014e4224bda43fcc547c..363195f728d3617df1c38677fdc59962d888cd2d 100644 (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,
index 112e2866a5f04808a657522b7b8ae7670bde6a3e..5638287654152057a7213c36ca4b5a47fd579f92 100644 (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,
 
index 9c32c84f657bbfd399ea19eec86c87b0baaf6a28..886dc4922ebc197bb7d0f8586192f18d8169ad5b 100644 (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))
index c10125b2a45050c6b6166619303267a3202e935e..29c313c244e09a6651298a4655114acf25ccce8e 100644 (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
index 5aa5fec5c108883b3e802d62fef9c720ccd91506..fc6a4ae2d766bcbb280d0c6d7dd60002ba4b6a2a 100644 (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
index e90b38edac8dced7ef901fa9b8e6c55ad5e042bf..fb40ec12cc27c91ab794a6f7608b81e2bade753b 100644 (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);
index 729a06b2d26136d89dc715e6c8500be9946c62f1..a883505843ae68f6668abf280c350ddaa7f45b12 100644 (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
index 4ead1237cb7b9a3dc86e92d3d91d41578dcbc488..7396348c878ea9dd62860154ed8b920aea3f3423 100644 (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
index 4060799f14227d1dc0880ec69cd743ff7472d8ad..7dbe299e6e11861c3a823d11508a7fb32d64f1d8 100644 (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) {
index 144288104fa23e198bf4f16582e0e367aeb24609..3820f34a425dddca55462f21e0587051959b1a18 100644 (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
index c21c9b8867b63ba4263e1aef5558dbc583e10fd8..2bdaa205f6683e0dc00a155027c310b32347743a 100644 (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,
index c2bbbbde6e37019f0e768a5ad560941427d9881d..d4429958c80c2f3433c81d67e8fa8895147b7cc0 100644 (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;
index 21f69e983e43492420e501c4189e89617452e93e..249fac4348b333742c76195897c65d9e7fa7f321 100644 (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
index d028e21e6e5b0066b7a95f0d534f9ae33c8cc4bc..d4cf100f460ca00d06027953c970807e90d309e1 100644 (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
index a22ea3321caea05a0e1597c3119924276e19aeed..70ee670aab18a0605c457e7e7ab0c7f05321844d 100644 (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;
index 2b04de679b2c20511462b3f5556b8dc026fc37bc..19f24d7e67e02966b2ff2336e9e5671d412f6013 100644 (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
index efcd96b74d3ad0f2ed8440d8f289bee4cd37b373..403cc8ec5e88894859b94b8a8f4eb9243e78f9ef 100644 (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) {
index 8eb77b61297b568c354185293fb7a62b562062a9..b5fa478cc7ff22c2f96855661bfcf871f246ec41 100644 (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
index 40ea8083997c70764681b6af79bdb7f3ea39c376..5b1d1d1b0d0d6ed85a50c4e2fe7b4b83e797f324 100644 (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
index 13bbb4370179e76a7de98c30ae91c650e8c86639..306960fd1345bee76103d7938b8d5e9469205874 100644 (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
index 5f749ea5f3ff910913726096b32d47eea04000f4..87ba5ac14eb67689e62a76ee56a27f650be99532 100644 (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
index 33c3d96bacb9438d2d16c1f5b471dc8b7fa9a788..e8181359bf9db1e45b30ec4a0e883191a2a13d03 100644 (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
index 6e97b0ba92140c43150ff88035706e42ab443e8e..8890cdadc7fff77d92ec37d33315d15bfd486889 100644 (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
index 0ad2931b91b9a33638ab42013461d5396f37ea36..ba4463019342f609d1f98bd6589309aa5646c508 100644 (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);
index 1e165b7b77252cb9c20d7a2266d1c4600dd3dd2c..e1ae59cf7516e0e7a505707fb7a42e3e24b6e43f 100644 (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)
index c753c00e8e40398fbc1d9940cbcc2cd9dca61804..3ed42dbfcab94313949946639228340609b102fa 100644 (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) {
index 07ceade690d68b1a90eb4abed81e388aaeb8010e..b31dc93aa3c2a3de26e17d4f0e3b96b1ef94acf0 100644 (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
index 534f98314259444ca58a97077c4e8148169c9c5c..1033b53b318e32fe34d0e517657aa6c8158b9fa2 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _ATTR_PRINT_H_INCLUDED_
-#define _ATTR_PRINT_H_INCLUDED_
+#ifndef _ATTR_H_INCLUDED_
+#define _ATTR_H_INCLUDED_
 
 /*++
 /* NAME
   * 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
index 8d5e511126ac20709f862b24065a0a082b70e62c..fe38ea6fd96fbfe8f10dd425ff84515e0a972ca6 100644 (file)
 /* .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");
index 4098cfb44822150f742ff9cb860b7b610b3591dd..2f6267b99dd99f2fcea9e77fae96c976a138ecc3 100644 (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.
 /*     (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
 /*     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
 /*     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
 /* .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.
 /*     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
 #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>
 
 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 (file)
index 0000000..fb02bd5
--- /dev/null
@@ -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
index 443bf43c636e41ef248f5983010fb4b6d81ca8a5..469b1c0fae67f05f56bfe74747ceaec74f5c2e56 100644 (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) \
index 5a669aa096dca5a9039528b49510cad8147ca49f..1d9d8c4a129f1273635da0e46ae3c1dd621cc280 100644 (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;
index 2c15ac897ef86d3d554f3ae75a4841fb42d36199..a13806f7f71f27a9d3b964c68895173efdac6f46 100644 (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