]> git.ipfire.org Git - thirdparty/postfix.git/commitdiff
postfix-1.1.9-20020512
authorWietse Venema <wietse@porcupine.org>
Sun, 12 May 2002 05:00:00 +0000 (00:00 -0500)
committerViktor Dukhovni <viktor@dukhovni.org>
Tue, 5 Feb 2013 06:27:56 +0000 (06:27 +0000)
64 files changed:
postfix/HISTORY
postfix/RELEASE_NOTES
postfix/html/bounce.8.html
postfix/html/lmtp.8.html
postfix/html/sendmail.1.html
postfix/html/smtp.8.html
postfix/man/man1/sendmail.1
postfix/man/man8/bounce.8
postfix/man/man8/lmtp.8
postfix/man/man8/smtp.8
postfix/src/bounce/Makefile.in
postfix/src/bounce/bounce.c
postfix/src/bounce/bounce_notify_service.c
postfix/src/bounce/bounce_notify_util.c
postfix/src/bounce/bounce_notify_verp.c
postfix/src/bounce/bounce_service.h
postfix/src/cleanup/Makefile.in
postfix/src/cleanup/cleanup.h
postfix/src/cleanup/cleanup_api.c
postfix/src/cleanup/cleanup_envelope.c
postfix/src/cleanup/cleanup_extracted.c
postfix/src/cleanup/cleanup_init.c
postfix/src/cleanup/cleanup_message.c
postfix/src/cleanup/cleanup_state.c
postfix/src/global/abounce.c
postfix/src/global/abounce.h
postfix/src/global/bounce.c
postfix/src/global/bounce.h
postfix/src/global/defer.c
postfix/src/global/defer.h
postfix/src/global/deliver_request.c
postfix/src/global/deliver_request.h
postfix/src/global/header_opts.c
postfix/src/global/mail_params.h
postfix/src/global/mail_proto.h
postfix/src/global/mail_version.h
postfix/src/global/post_mail.c
postfix/src/global/rec_type.h
postfix/src/lmtp/Makefile.in
postfix/src/lmtp/lmtp.c
postfix/src/lmtp/lmtp_proto.c
postfix/src/nqmgr/Makefile.in
postfix/src/nqmgr/qmgr.h
postfix/src/nqmgr/qmgr_active.c
postfix/src/nqmgr/qmgr_deliver.c
postfix/src/nqmgr/qmgr_message.c
postfix/src/pickup/Makefile.in
postfix/src/pickup/pickup.c
postfix/src/qmgr/Makefile.in
postfix/src/qmgr/qmgr.h
postfix/src/qmgr/qmgr_active.c
postfix/src/qmgr/qmgr_deliver.c
postfix/src/qmgr/qmgr_message.c
postfix/src/qmqpd/qmqpd.c
postfix/src/sendmail/sendmail.c
postfix/src/smtp/Makefile.in
postfix/src/smtp/smtp.c
postfix/src/smtp/smtp_proto.c
postfix/src/smtpd/Makefile.in
postfix/src/smtpd/smtpd.c
postfix/src/util/Makefile.in
postfix/src/util/dict.c
postfix/src/util/nvtable.c [new file with mode: 0644]
postfix/src/util/nvtable.h [new file with mode: 0644]

index 6f3bce6f15ba8ee2e6fc04d5733c58081c39c2c4..f34023646053f808ead6e53545d6cf36399bf96f 100644 (file)
@@ -6383,10 +6383,41 @@ Apologies for any names omitted.
        multiple Postfix instances.  Text by Victor Duchovny, Morgan
        Stanley. File:  README_FILES/FILTER_README.
 
-Open problems:
+20020510
+
+       Feature: header/body filters now log the origin of the
+       message that is being rejected. Files: smtpd/smtpd.c,
+       qmqpd/qmqpd.c, pickup/pickup.c, cleanup/cleanup_envelope.c,
+       cleanup/cleanup_message.c.  Requested by Craig Sanders, if
+       I remember correctly.
+
+       Feature: the Postfix SMTP client now passes on MIME body
+       type information (8bit, 7bit) received via SMTP, via MIME
+       headers, or via the sendmail command line. Files:
+       global/deliver_request.c, smtpd/smtpd.c, sendmail/sendmail.c,
+       cleanup/cleanup_envelope.c, cleanup/cleanup_message.c,
+       cleanup/cleanup_extracted.c, *qmgr/qmgr_message.c,
+       *qmgr/qmgr_deliver.c, smtp/smtp_proto.c, lmtp/lmtp_proto.c.
+
+20020511
+
+       Feature: bounces now specify the proper MIME encoding (8bit,
+       7bit), depending on the MIME body type information received
+       via SMTP, via MIME headers, or via the sendmail command
+       line. Files: global/bounce.c, global/defer.c, global/abounce.c,
+       bounce/bounce_service.c, bounce/bounce_notify_util.c.
 
-       Low: smtpd should reply with the original recipient address,
-       or it should at least externalize it.
+20020512
+
+       Cleanup: the SMTP client logged and bounced the CNAME
+       expanded recipient address, and thereby complicated trouble
+       shooting.  File:  src/smtp_proto.c.
+
+       Bugfix: the SMTP and LMTP clients bounced the quoted
+       recipient address, resulting in too much quoting in bounce
+       reports.  Files:  src/smtp_proto.c, lmtp/lmtp_proto.c.
+
+Open problems:
 
        Low: all table lookups should consistently use internalized
        (unquoted) or externalized (quoted) forms as lookup keys.
index 69e7921d246e096260b5fbd3fbcd16a8ce064796..7fbd39fa139722f3f0caa9893ff5b87e6ab67541 100644 (file)
@@ -12,6 +12,38 @@ snapshot release).  Patches change the patchlevel and the release
 date. Snapshots change only the release date, unless they include
 the same bugfixes as a patch release.
 
+Incompatible changes with Postfix snapshot 1.1.9-20020512
+=========================================================
+
+The Postfix SMTP client no longer uses the CNAME expanded recipient
+address when logging delivery or when bouncing mail. This makes
+trouble shooting somewhat easier.
+
+Postfix snapshot 1.1.9-20020512 queue files contain records that
+are incompatible with "postqueue -r" on all Postfix versions prior
+to 1.1 and release candidates. This happens whenever the sender
+specifies MIME body type information via the SMTP `MAIL FROM'
+command, via the `sendmail -B' command line option, or via the
+Content-Transfer-Encoding:  message header.
+
+Postfix snapshot 1.1.9-20020512 queue files may contain records
+that are incompatible with "postqueue -r" on previous 1.1 Postfix
+versions and release candidates. This happens whenever the sender
+specifies the MIME body type only via the Content-Transfer-Encoding:
+message header, and not via `MAIL FROM' or `sendmail -B'.
+
+Major changes with Postfix snapshot 1.1.9-20020512
+==================================================
+
+The Postfix SMTP and LMTP clients now properly pass on the MIME
+body type information (7BIT or 8BITMIME), provided that the sender
+properly specifies MIME body type information via the SMTP MAIL
+FROM command, via the sendmail -B command line option, or via MIME
+message headers. This includes mail that is returned as undeliverable.
+Implementing MIME body type propagation was a low priority because
+qmail didn't implement this, either. However, Postfix will not
+convert 8BITMIME content into 7BIT, and probably never will.
+
 Incompatible changes with Postfix snapshot 1.1.9-20020509
 =========================================================
 
@@ -22,11 +54,11 @@ catch-all patterns.
 
 The appearance of user@domain1@domain2 addresses has changed.  In
 mail headers, such addresses are now properly quoted as
-"user@domain1"@domain2. This quoted form is now also expected on
-the left-hand side of virtual and canonical lookup tables, but only
-by some of the Postfix components. For now, it is better not to
-use user@domain1@domain2 address forms on the left-hand side of
-lookup tables.
+"user@domain1"@domain2. As a side effect, this quoted form is now
+also expected on the left-hand side of virtual and canonical lookup
+tables, but only by some of the Postfix components.  For now, it
+is better not to use user@domain1@domain2 address forms on the
+left-hand side of lookup tables.
 
 Incompatible changes with Postfix snapshot 1.1.8-20020508
 =========================================================
index 76cde51963f997a35f3ad5b40ffd4a2cd7283dad..548369f71848fd943047288259ce537c9c766e3f 100644 (file)
@@ -1,5 +1,4 @@
 <html> <head> </head> <body> <pre>
-
 BOUNCE(8)                                               BOUNCE(8)
 
 <b>NAME</b>
@@ -38,6 +37,7 @@ BOUNCE(8)                                               BOUNCE(8)
 <b>STANDARDS</b>
        <a href="http://www.faqs.org/rfcs/rfc822.html">RFC 822</a> (ARPA Internet Text Messages)
        <a href="http://www.faqs.org/rfcs/rfc1894.html">RFC 1894</a> (Delivery Status Notifications)
+       <a href="http://www.faqs.org/rfcs/rfc2045.html">RFC 2045</a> (Format of Internet Message Bodies)
 
 <b>DIAGNOSTICS</b>
        Problems and transactions are logged to <b>syslogd</b>(8).
@@ -90,6 +90,5 @@ BOUNCE(8)                                               BOUNCE(8)
        P.O. Box 704
        Yorktown Heights, NY 10598, USA
 
-                                                                1
-
+                                                        BOUNCE(8)
 </pre> </body> </html>
index a4428fa0be6a4014746d130ee92b2a682af17420..08e1947523dba575123e8bfc9328639bce886e30 100644 (file)
@@ -1,5 +1,4 @@
 <html> <head> </head> <body> <pre>
-
 LMTP(8)                                                   LMTP(8)
 
 <b>NAME</b>
@@ -56,6 +55,7 @@ LMTP(8)                                                   LMTP(8)
 <b>STANDARDS</b>
        <a href="http://www.faqs.org/rfcs/rfc821.html">RFC 821</a> (SMTP protocol)
        <a href="http://www.faqs.org/rfcs/rfc1651.html">RFC 1651</a> (SMTP service extensions)
+       <a href="http://www.faqs.org/rfcs/rfc1652.html">RFC 1652</a> (8bit-MIME transport)
        <a href="http://www.faqs.org/rfcs/rfc1870.html">RFC 1870</a> (Message Size Declaration)
        <a href="http://www.faqs.org/rfcs/rfc2033.html">RFC 2033</a> (LMTP protocol)
        <a href="http://www.faqs.org/rfcs/rfc2197.html">RFC 2197</a> (Pipelining)
@@ -265,6 +265,5 @@ LMTP(8)                                                   LMTP(8)
        P.O. Box 830688, MC34
        Richardson, TX 75083, USA
 
-                                                                1
-
+                                                          LMTP(8)
 </pre> </body> </html>
index 9daf15bd54d877bbb80bac74581574e5d3491cac..3ace513a46cb0f733403a5b365a70ff0fcb81195 100644 (file)
@@ -57,92 +57,91 @@ SENDMAIL(1)                                           SENDMAIL(1)
 
        The following options are recognized:
 
-       <b>-B</b> <i>body_type</i> (ignored)
-              The  message  body  MIME  type.  Currently, Postfix
-              implements <b>just-send-eight</b>.
+       <b>-B</b> <i>body_type</i>
+              The message body MIME type: <b>7BIT</b> or <b>8BITMIME</b>.
 
        <b>-C</b> <i>config_file</i> (ignored :-)
               The path name of the <b>sendmail.cf</b> file. Postfix con-
               figuration files are kept in <b>/etc/postfix</b>.
 
        <b>-F</b> <i>full_name</i>
-              Set  the  sender  full name. This is used only with
+              Set the sender full name. This is  used  only  with
               messages that have no <b>From:</b> message header.
 
        <b>-G</b> (ignored)
-              Gateway (relay) submission, as opposed  to  initial
+              Gateway  (relay)  submission, as opposed to initial
               user submission.
 
-       <b>-I</b>     Initialize  alias database. See the <b>newaliases</b> com-
+       <b>-I</b>     Initialize alias database. See the <b>newaliases</b>  com-
               mand above.
 
        <b>-L</b> <i>label</i> (ignored)
-              The logging label. Use the  <b>syslog</b><i>_</i><b>name</b>  configura-
+              The  logging  label. Use the <b>syslog</b><i>_</i><b>name</b> configura-
               tion parameter instead.
 
        <b>-N</b> <i>dsn</i> (ignored)
-              Delivery  status  notification  control. Currently,
+              Delivery status  notification  control.  Currently,
               Postfix does not implement <b>DSN</b>.
 
        <b>-R</b> <i>return_limit</i> (ignored)
-              Limit  the  size   of   bounced   mail.   Use   the
-              <b>bounce</b><i>_</i><b>size</b><i>_</i><b>limit</b>  configuration parameter instead.
+              Limit   the   size   of   bounced   mail.  Use  the
+              <b>bounce</b><i>_</i><b>size</b><i>_</i><b>limit</b> configuration parameter  instead.
 
        <b>-X</b> <i>log_file</i> (ignored)
-              Log mailer traffic.  Use  the  <b>debug</b><i>_</i><b>peer</b><i>_</i><b>list</b>  and
-              <b>debug</b><i>_</i><b>peer</b><i>_</i><b>level</b>  configuration parameters instead.
+              Log  mailer  traffic.  Use  the <b>debug</b><i>_</i><b>peer</b><i>_</i><b>list</b> and
+              <b>debug</b><i>_</i><b>peer</b><i>_</i><b>level</b> configuration parameters  instead.
 
        <b>-U</b> (ignored)
               Initial user submission.
 
-       <b>-V</b>     Variable Envelope Return Path.  Given  an  envelope
-              sender  address  of the form <i>owner-listname</i>@<i>origin</i>,
-              each recipient <i>user</i>@<i>domain</i>  receives  mail  with  a
+       <b>-V</b>     Variable  Envelope  Return  Path. Given an envelope
+              sender address of the  form  <i>owner-listname</i>@<i>origin</i>,
+              each  recipient  <i>user</i>@<i>domain</i>  receives  mail with a
               personalized envelope sender address.
 
-              By   default,   the  personalized  envelope  sender
-              address is  <i>owner-listname</i><b>+</b><i>user</i><b>=</b><i>domain</i>@<i>origin</i>.  The
-              default  <b>+</b>  and  <b>=</b> characters are configurable with
-              the <b>default</b><i>_</i><b>verp</b><i>_</i><b>delimiters</b>  configuration  parame-
+              By  default,  the  personalized   envelope   sender
+              address  is  <i>owner-listname</i><b>+</b><i>user</i><b>=</b><i>domain</i>@<i>origin</i>. The
+              default <b>+</b> and <b>=</b> characters  are  configurable  with
+              the  <b>default</b><i>_</i><b>verp</b><i>_</i><b>delimiters</b>  configuration parame-
               ter.
 
        <b>-V</b><i>xy</i>   As <b>-V</b>, but uses <i>x</i> and <i>y</i> as the VERP delimiter char-
-              acters, instead of the  characters  specified  with
-              the  <b>default</b><i>_</i><b>verp</b><i>_</i><b>delimiters</b>  configuration parame-
+              acters,  instead  of  the characters specified with
+              the <b>default</b><i>_</i><b>verp</b><i>_</i><b>delimiters</b>  configuration  parame-
               ter.
 
-       <b>-bd</b>    Go into daemon mode.  This  mode  of  operation  is
+       <b>-bd</b>    Go  into  daemon  mode.  This  mode of operation is
               implemented by executing the <b>postfix</b> <b>start</b> command.
 
-       <b>-bi</b>    Initialize alias database. See the <b>newaliases</b>  com-
+       <b>-bi</b>    Initialize  alias database. See the <b>newaliases</b> com-
               mand above.
 
-       <b>-bm</b>    Read  mail  from  standard  input  and  arrange for
+       <b>-bm</b>    Read mail  from  standard  input  and  arrange  for
               delivery.  This is the default mode of operation.
 
        <b>-bp</b>    List the mail queue. See the <b>mailq</b> command above.
 
-       <b>-bs</b>    Stand-alone SMTP server mode.  Read  SMTP  commands
-              from  standard  input, and write responses to stan-
-              dard output.  In stand-alone SMTP server mode,  UCE
-              restrictions  and  access  controls are disabled by
-              default. To enable them, run  the  process  as  the
+       <b>-bs</b>    Stand-alone  SMTP  server  mode. Read SMTP commands
+              from standard input, and write responses  to  stan-
+              dard  output.  In stand-alone SMTP server mode, UCE
+              restrictions and access controls  are  disabled  by
+              default.  To  enable  them,  run the process as the
               <b>mail</b><i>_</i><b>owner</b> user.
 
-              This  mode  of  operation is implemented by running
+              This mode of operation is  implemented  by  running
               the <a href="smtpd.8.html"><b>smtpd</b>(8)</a> daemon.
 
        <b>-f</b> <i>sender</i>
               Set  the  envelope  sender  address.  This  is  the
               address where delivery problems are sent to, unless
-              the message contains an <b>Errors-To:</b> message  header.
+              the  message contains an <b>Errors-To:</b> message header.
 
        <b>-h</b> <i>hop_count</i> (ignored)
-              Hop  count limit. Use the <b>hopcount</b><i>_</i><b>limit</b> configura-
+              Hop count limit. Use the <b>hopcount</b><i>_</i><b>limit</b>  configura-
               tion parameter instead.
 
-       <b>-i</b>     When reading a message from standard  input,  don't
-              treat  a line with only a <b>.</b> character as the end of
+       <b>-i</b>     When  reading  a message from standard input, don't
+              treat a line with only a <b>.</b> character as the end  of
               input.
 
        <b>-m</b> (ignored)
@@ -152,67 +151,67 @@ SENDMAIL(1)                                           SENDMAIL(1)
               Backwards compatibility.
 
        <b>-oA</b><i>alias_database</i>
-              Non-default alias  database.  Specify  <i>pathname</i>  or
+              Non-default  alias  database.  Specify  <i>pathname</i> or
               <i>type</i>:<i>pathname</i>. See <a href="postalias.1.html"><b>postalias</b>(1)</a> for details.
 
        <b>-o7</b> (ignored)
 
        <b>-o8</b> (ignored)
-              The  message  body  type. Currently, Postfix imple-
+              The message body type.  Currently,  Postfix  imple-
               ments <b>just-send-eight</b>.
 
-       <b>-oi</b>    When reading a message from standard  input,  don't
-              treat  a line with only a <b>.</b> character as the end of
+       <b>-oi</b>    When  reading  a message from standard input, don't
+              treat a line with only a <b>.</b> character as the end  of
               input.
 
        <b>-om</b> (ignored)
-              The sender is  never  eliminated  from  alias  etc.
+              The  sender  is  never  eliminated  from alias etc.
               expansions.
 
        <b>-o</b> <i>x</i> <i>value</i> (ignored)
-              Set  option <i>x</i> to <i>value</i>. Use the equivalent configu-
+              Set option <i>x</i> to <i>value</i>. Use the equivalent  configu-
               ration parameter in <b>main.cf</b> instead.
 
        <b>-r</b> <i>sender</i>
               Set  the  envelope  sender  address.  This  is  the
               address where delivery problems are sent to, unless
-              the message contains an <b>Errors-To:</b> message  header.
+              the  message contains an <b>Errors-To:</b> message header.
 
-       <b>-q</b>     Attempt  to deliver all queued mail. This is imple-
+       <b>-q</b>     Attempt to deliver all queued mail. This is  imple-
               mented by executing the <a href="postqueue.1.html"><b>postqueue</b>(1)</a> command.
 
        <b>-q</b><i>interval</i> (ignored)
-              The  interval   between   queue   runs.   Use   the
+              The   interval   between   queue   runs.   Use  the
               <b>queue</b><i>_</i><b>run</b><i>_</i><b>delay</b> configuration parameter instead.
 
        <b>-qR</b><i>site</i>
-              Schedule  immediate  delivery  of  all mail that is
+              Schedule immediate delivery of  all  mail  that  is
               queued for the named <i>site</i>. This option accepts only
-              <i>site</i>  names  that are eligible for the "fast flush"
-              service,  and  is  implemented  by  executing   the
+              <i>site</i> names that are eligible for the  "fast  flush"
+              service,   and  is  implemented  by  executing  the
               <a href="postqueue.1.html"><b>postqueue</b>(1)</a> command.  See <a href="flushd.8.html"><b>flush</b>(8)</a> for more infor-
               mation about the "fast flush" service.
 
        <b>-qS</b><i>site</i>
-              This command is not  implemented.  Use  the  slower
+              This  command  is  not  implemented. Use the slower
               <b>sendmail</b> <b>-q</b> command instead.
 
-       <b>-t</b>     Extract   recipients  from  message  headers.  This
-              requires that no recipients  be  specified  on  the
+       <b>-t</b>     Extract  recipients  from  message  headers.   This
+              requires  that  no  recipients  be specified on the
               command line.
 
        <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>SECURITY</b>
-       By  design,  this  program  is not set-user (or group) id.
-       However, it must  handle  data  from  untrusted  users  or
-       untrusted  machines.   Thus, the usual precautions need to
+       By design, this program is not  set-user  (or  group)  id.
+       However,  it  must  handle  data  from  untrusted users or
+       untrusted machines.  Thus, the usual precautions  need  to
        be taken against malicious inputs.
 
 <b>DIAGNOSTICS</b>
-       Problems are logged to  <b>syslogd</b>(8)  and  to  the  standard
+       Problems  are  logged  to  <b>syslogd</b>(8)  and to the standard
        error stream.
 
 <b>ENVIRONMENT</b>
@@ -224,7 +223,7 @@ SENDMAIL(1)                                           SENDMAIL(1)
 
        <b>MAIL</b><i>_</i><b>DEBUG</b>
               Enable debugging with an external command, as spec-
-              ified  with  the   <b>debugger</b><i>_</i><b>command</b>   configuration
+              ified   with   the  <b>debugger</b><i>_</i><b>command</b>  configuration
               parameter.
 
 <b>FILES</b>
@@ -232,13 +231,13 @@ SENDMAIL(1)                                           SENDMAIL(1)
        /etc/postfix, configuration files
 
 <b>CONFIGURATION</b> <b>PARAMETERS</b>
-       See  the  Postfix  <b>main.cf</b> file for syntax details and for
-       default values. Use the <b>postfix</b>  <b>reload</b>  command  after  a
+       See the Postfix <b>main.cf</b> file for syntax  details  and  for
+       default  values.  Use  the  <b>postfix</b> <b>reload</b> command after a
        configuration change.
 
        <b>alias</b><i>_</i><b>database</b>
-              Default   alias  database(s)  for  <b>newaliases</b>.  The
-              default value for  this  parameter  is  system-spe-
+              Default  alias  database(s)  for  <b>newaliases</b>.   The
+              default  value  for  this  parameter is system-spe-
               cific.
 
        <b>bounce</b><i>_</i><b>size</b><i>_</i><b>limit</b>
@@ -254,62 +253,62 @@ SENDMAIL(1)                                           SENDMAIL(1)
               initialized.
 
        <b>debug</b><i>_</i><b>peer</b><i>_</i><b>level</b>
-              Increment in verbose logging level  when  a  remote
+              Increment  in  verbose  logging level when a remote
               host  matches  a  pattern  in  the  <b>debug</b><i>_</i><b>peer</b><i>_</i><b>list</b>
               parameter.
 
        <b>debug</b><i>_</i><b>peer</b><i>_</i><b>list</b>
-              List of domain or network patterns. When  a  remote
-              host  matches  a pattern, increase the verbose log-
-              ging  level  by  the  amount   specified   in   the
+              List  of  domain or network patterns. When a remote
+              host matches a pattern, increase the  verbose  log-
+              ging   level   by   the  amount  specified  in  the
               <b>debug</b><i>_</i><b>peer</b><i>_</i><b>level</b> parameter.
 
        <b>default</b><i>_</i><b>verp</b><i>_</i><b>delimiters</b>
-              The  VERP  delimiter  characters that are used when
-              the <b>-V</b> command line  option  is  specified  without
+              The VERP delimiter characters that  are  used  when
+              the  <b>-V</b>  command  line  option is specified without
               delimiter characters.
 
        <b>fast</b><i>_</i><b>flush</b><i>_</i><b>domains</b>
               List of domains that will receive "fast flush" ser-
-              vice (default: all  domains  that  this  system  is
-              willing  to relay mail to). This list specifies the
-              domains that  Postfix  accepts  in  the  SMTP  <b>ETRN</b>
+              vice  (default:  all  domains  that  this system is
+              willing to relay mail to). This list specifies  the
+              domains  that  Postfix  accepts  in  the  SMTP <b>ETRN</b>
               request and in the <b>sendmail</b> <b>-qR</b> command.
 
        <b>fork</b><i>_</i><b>attempts</b>
-              Number  of attempts to <b>fork</b>() a process before giv-
+              Number of attempts to <b>fork</b>() a process before  giv-
               ing up.
 
        <b>fork</b><i>_</i><b>delay</b>
-              Delay  in   seconds   between   successive   <b>fork</b>()
+              Delay   in   seconds   between   successive  <b>fork</b>()
               attempts.
 
        <b>hopcount</b><i>_</i><b>limit</b>
               Limit the number of <b>Received:</b> message headers.
 
        <b>mail</b><i>_</i><b>owner</b>
-              The  owner  of  the  mail queue and of most Postfix
+              The owner of the mail queue  and  of  most  Postfix
               processes.
 
        <b>command</b><i>_</i><b>directory</b>
-              Directory with Postfix support  commands  (default:
+              Directory  with  Postfix support commands (default:
               <b>$program</b><i>_</i><b>directory</b>).
 
        <b>daemon</b><i>_</i><b>directory</b>
-              Directory  with  Postfix  daemon programs (default:
+              Directory with Postfix  daemon  programs  (default:
               <b>$program</b><i>_</i><b>directory</b>).
 
        <b>queue</b><i>_</i><b>directory</b>
-              Top-level directory of the Postfix queue.  This  is
+              Top-level  directory  of the Postfix queue. This is
               also the root directory of Postfix daemons that run
               chrooted.
 
        <b>queue</b><i>_</i><b>run</b><i>_</i><b>delay</b>
-              The time between successive scans of  the  deferred
+              The  time  between successive scans of the deferred
               queue.
 
        <b>verp</b><i>_</i><b>delimiter</b><i>_</i><b>filter</b>
-              The  characters that Postfix accepts as VERP delim-
+              The characters that Postfix accepts as VERP  delim-
               iter characters.
 
 <b>SEE</b> <b>ALSO</b>
@@ -324,7 +323,7 @@ SENDMAIL(1)                                           SENDMAIL(1)
        syslogd(8) system logging
 
 <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 047b3ddc9767749bbbd38aa502a286226cb41a9a..ba92da53609562ebd4304a78c5d10e610fbf89ca 100644 (file)
@@ -43,6 +43,7 @@ SMTP(8)                                                   SMTP(8)
 <b>STANDARDS</b>
        <a href="http://www.faqs.org/rfcs/rfc821.html">RFC 821</a> (SMTP protocol)
        <a href="http://www.faqs.org/rfcs/rfc1651.html">RFC 1651</a> (SMTP service extensions)
+       <a href="http://www.faqs.org/rfcs/rfc1652.html">RFC 1652</a> (8bit-MIME transport)
        <a href="http://www.faqs.org/rfcs/rfc1870.html">RFC 1870</a> (Message Size Declaration)
        <a href="http://www.faqs.org/rfcs/rfc2197.html">RFC 2197</a> (Pipelining)
        <a href="http://www.faqs.org/rfcs/rfc2554.html">RFC 2554</a> (AUTH command)
index 10ca278c014449e9dcd047ef96d929d860e16881..d493c8a4d45fd926e74d8dd9ef559977a7fe6967 100644 (file)
@@ -55,9 +55,8 @@ appropriate combination of command-line options. Some features are
 controlled by parameters in the \fBmain.cf\fR configuration file.
 
 The following options are recognized:
-.IP "\fB-B \fIbody_type\fR (ignored)"
-The message body MIME type. Currently, Postfix implements
-\fBjust-send-eight\fR.
+.IP "\fB-B \fIbody_type\fR"
+The message body MIME type: \fB7BIT\fR or \fB8BITMIME\fR.
 .IP "\fB-C \fIconfig_file\fR (ignored :-)"
 The path name of the \fBsendmail.cf\fR file. Postfix configuration
 files are kept in \fB/etc/postfix\fR.
index 02dc4cee6a79630eea38c4c5f1e236a180d99a43..a1afc3faa09ab17800d024cec49319ccb9cb17b1 100644 (file)
@@ -41,6 +41,7 @@ themselves, and that depend on retry logic in their own client.
 .nf
 RFC 822 (ARPA Internet Text Messages)
 RFC 1894 (Delivery Status Notifications)
+RFC 2045 (Format of Internet Message Bodies)
 .SH DIAGNOSTICS
 .ad
 .fi
index b00dc9d3569d177570203dc21d602760fc055ece..c53e0033ce609499d94c222ad3926342038ef275 100644 (file)
@@ -56,6 +56,7 @@ run chrooted at fixed low privilege.
 .nf
 RFC 821 (SMTP protocol)
 RFC 1651 (SMTP service extensions)
+RFC 1652 (8bit-MIME transport)
 RFC 1870 (Message Size Declaration)
 RFC 2033 (LMTP protocol)
 RFC 2197 (Pipelining)
index 00f07b8fdc27d1a5b861a36c2e63017ec905bbe0..196c16c746f89e9b0fc4caacafcb3a7caaacba2f 100644 (file)
@@ -48,6 +48,7 @@ run chrooted at fixed low privilege.
 .nf
 RFC 821 (SMTP protocol)
 RFC 1651 (SMTP service extensions)
+RFC 1652 (8bit-MIME transport)
 RFC 1870 (Message Size Declaration)
 RFC 2197 (Pipelining)
 RFC 2554 (AUTH command)
index 99e6d1af457fe5446e558ebdde6ad4a977b0f996..3d2327f38ea0c8a36586d312d356e13bdd622bab 100644 (file)
@@ -136,6 +136,9 @@ bounce_notify_util.o: ../../include/mail_error.h
 bounce_notify_util.o: ../../include/name_mask.h
 bounce_notify_util.o: ../../include/bounce_log.h
 bounce_notify_util.o: ../../include/mail_date.h
+bounce_notify_util.o: ../../include/mail_proto.h
+bounce_notify_util.o: ../../include/iostuff.h
+bounce_notify_util.o: ../../include/attr.h
 bounce_notify_util.o: bounce_service.h
 bounce_notify_verp.o: bounce_notify_verp.c
 bounce_notify_verp.o: ../../include/sys_defs.h
index 3cb98cc00282241a32097f9e8e0244fafd365099..00c40cd2d14c5117e092b33d970ff6dca11965a1 100644 (file)
@@ -33,6 +33,7 @@
 /* STANDARDS
 /*     RFC 822 (ARPA Internet Text Messages)
 /*     RFC 1894 (Delivery Status Notifications)
+/*     RFC 2045 (Format of Internet Message Bodies)
 /* DIAGNOSTICS
 /*     Problems and transactions are logged to \fBsyslogd\fR(8).
 /* BUGS
@@ -127,6 +128,7 @@ char   *var_delay_rcpt;
 static VSTRING *queue_id;
 static VSTRING *queue_name;
 static VSTRING *recipient;
+static VSTRING *encoding;
 static VSTRING *sender;
 static VSTRING *verp_delims;
 static VSTRING *why;
@@ -186,8 +188,9 @@ static int bounce_notify_proto(char *service_name, VSTREAM *client, int flush)
                            ATTR_TYPE_NUM, MAIL_ATTR_FLAGS, &flags,
                            ATTR_TYPE_STR, MAIL_ATTR_QUEUE, queue_name,
                            ATTR_TYPE_STR, MAIL_ATTR_QUEUEID, queue_id,
+                           ATTR_TYPE_STR, MAIL_ATTR_ENCODING, encoding,
                            ATTR_TYPE_STR, MAIL_ATTR_SENDER, sender,
-                           ATTR_TYPE_END) != 4) {
+                           ATTR_TYPE_END) != 5) {
        msg_warn("malformed request");
        return (-1);
     }
@@ -200,8 +203,9 @@ static int bounce_notify_proto(char *service_name, VSTREAM *client, int flush)
        return (-1);
     }
     if (msg_verbose)
-       msg_info("bounce_notify_proto: service=%s queue=%s id=%s sender=%s",
-                service_name, STR(queue_name), STR(queue_id), STR(sender));
+       msg_info("bounce_notify_proto: service=%s queue=%s id=%s encoding=%s sender=%s",
+                service_name, STR(queue_name), STR(queue_id),
+                STR(encoding), STR(sender));
 
     /*
      * On request by the client, set up a trap to delete the log file in case
@@ -214,7 +218,8 @@ static int bounce_notify_proto(char *service_name, VSTREAM *client, int flush)
      * Execute the request.
      */
     return (bounce_notify_service(service_name, STR(queue_name),
-                                 STR(queue_id), STR(sender), flush));
+                                 STR(queue_id), STR(encoding),
+                                 STR(sender), flush));
 }
 
 /* bounce_verp_proto - bounce_notify server protocol, VERP style */
@@ -228,12 +233,13 @@ static int bounce_verp_proto(char *service_name, VSTREAM *client, int flush)
      * Read and validate the client request.
      */
     if (mail_command_server(client,
-                 ATTR_TYPE_NUM, MAIL_ATTR_FLAGS, &flags,
-                 ATTR_TYPE_STR, MAIL_ATTR_QUEUE, queue_name,
-                 ATTR_TYPE_STR, MAIL_ATTR_QUEUEID, queue_id,
-                 ATTR_TYPE_STR, MAIL_ATTR_SENDER, sender,
-                 ATTR_TYPE_STR, MAIL_ATTR_VERPDL, verp_delims,
-                 ATTR_TYPE_END) != 5) {
+                           ATTR_TYPE_NUM, MAIL_ATTR_FLAGS, &flags,
+                           ATTR_TYPE_STR, MAIL_ATTR_QUEUE, queue_name,
+                           ATTR_TYPE_STR, MAIL_ATTR_QUEUEID, queue_id,
+                           ATTR_TYPE_STR, MAIL_ATTR_ENCODING, encoding,
+                           ATTR_TYPE_STR, MAIL_ATTR_SENDER, sender,
+                           ATTR_TYPE_STR, MAIL_ATTR_VERPDL, verp_delims,
+                           ATTR_TYPE_END) != 6) {
        msg_warn("malformed request");
        return (-1);
     }
@@ -251,9 +257,9 @@ static int bounce_verp_proto(char *service_name, VSTREAM *client, int flush)
        return (-1);
     }
     if (msg_verbose)
-       msg_info("%s: service=%s queue=%s id=%s sender=%s delim=%s",
+       msg_info("%s: service=%s queue=%s id=%s encoding=%s sender=%s delim=%s",
                 myname, service_name, STR(queue_name), STR(queue_id),
-                STR(sender), STR(verp_delims));
+                STR(encoding), STR(sender), STR(verp_delims));
 
     /*
      * On request by the client, set up a trap to delete the log file in case
@@ -269,11 +275,12 @@ static int bounce_verp_proto(char *service_name, VSTREAM *client, int flush)
     if (!*STR(sender) || !strcasecmp(STR(sender), mail_addr_double_bounce())) {
        msg_warn("request to send VERP-style notification of bounced mail");
        return (bounce_notify_service(service_name, STR(queue_name),
-                                     STR(queue_id), STR(sender), flush));
+                                     STR(queue_id), STR(encoding),
+                                     STR(sender), flush));
     } else
        return (bounce_notify_verp(service_name, STR(queue_name),
-                                  STR(queue_id), STR(sender),
-                                  STR(verp_delims), flush));
+                                  STR(queue_id), STR(encoding),
+                                  STR(sender), STR(verp_delims), flush));
 }
 
 /* bounce_service - parse bounce command type and delegate */
@@ -349,6 +356,7 @@ static void post_jail_init(char *unused_name, char **unused_argv)
     queue_id = vstring_alloc(10);
     queue_name = vstring_alloc(10);
     recipient = vstring_alloc(10);
+    encoding = vstring_alloc(10);
     sender = vstring_alloc(10);
     verp_delims = vstring_alloc(10);
     why = vstring_alloc(10);
index 284b6468ee578248108a4c7a26cdda3336209de3..21652f6b0598a151f137e1c4c8f7e98e28b41b99 100644 (file)
@@ -6,9 +6,11 @@
 /* SYNOPSIS
 /*     #include "bounce_service.h"
 /*
-/*     int     bounce_notify_service(queue_name, queue_id, sender, flush)
+/*     int     bounce_notify_service(queue_name, queue_id, encoding,
+/*                                     sender, flush)
 /*     char    *queue_name;
 /*     char    *queue_id;
+/*     char    *encoding;
 /*     char    *sender;
 /*     int     flush;
 /* DESCRIPTION
@@ -78,7 +80,8 @@
 /* bounce_notify_service - send a bounce */
 
 int     bounce_notify_service(char *service, char *queue_name,
-                                char *queue_id, char *recipient, int flush)
+                                     char *queue_id, char *encoding,
+                                     char *recipient, int flush)
 {
     BOUNCE_INFO *bounce_info;
     int     bounce_status = 1;
@@ -91,7 +94,8 @@ int     bounce_notify_service(char *service, char *queue_name,
     /*
      * Initialize. Open queue file, bounce log, etc.
      */
-    bounce_info = bounce_mail_init(service, queue_name, queue_id, flush);
+    bounce_info = bounce_mail_init(service, queue_name, queue_id,
+                                  encoding, flush);
 
 #define NULL_SENDER            MAIL_ADDR_EMPTY /* special address */
 #define NULL_CLEANUP_FLAGS     0
index 926be473407b6c4164ecc76bd1c489ce23e53ce5..b6a919efd8e93a69d2785f15320ee0ef9d205046 100644 (file)
 /* .in -4
 /*     } BOUNCE_INFO;
 /*
-/*     BOUNCE_INFO *bounce_mail_init(service, queue_name, queue_id, flush)
+/*     BOUNCE_INFO *bounce_mail_init(service, queue_name, queue_id,
+/*                                     encoding, flush)
 /*     const char *service;
 /*     const char *queue_name;
 /*     const char *queue_id;
+/*     const char *encoding;
 /*     int     flush;
 /*
 /*     void    bounce_mail_free(bounce_info)
 #include <mail_error.h>
 #include <bounce_log.h>
 #include <mail_date.h>
+#include <mail_proto.h>
 
 /* Application-specific. */
 
 /* bounce_mail_init - initialize */
 
 BOUNCE_INFO *bounce_mail_init(const char *service, const char *queue_name,
-                                     const char *queue_id, int flush)
+                                     const char *queue_id,
+                                     const char *encoding, int flush)
 {
     BOUNCE_INFO *bounce_info;
     int     rec_type;
@@ -175,6 +179,16 @@ BOUNCE_INFO *bounce_mail_init(const char *service, const char *queue_name,
     bounce_info->service = service;
     bounce_info->queue_name = queue_name;
     bounce_info->queue_id = queue_id;
+    if (strcmp(encoding, MAIL_ATTR_ENC_8BIT) == 0) {
+       bounce_info->mime_encoding = "8bit";
+    } else if (strcmp(encoding, MAIL_ATTR_ENC_7BIT) == 0) {
+       bounce_info->mime_encoding = "7bit";
+    } else {
+       if (strcmp(encoding, MAIL_ATTR_ENC_NONE) != 0)
+           msg_warn("%s: unknown encoding: %.200s",
+                    bounce_info->queue_id, encoding);
+       bounce_info->mime_encoding = 0;
+    }
     bounce_info->flush = flush;
     bounce_info->buf = vstring_alloc(100);
     bounce_info->arrival_time = 0;
@@ -298,6 +312,9 @@ int     bounce_header(VSTREAM *bounce, BOUNCE_INFO *bounce_info,
     post_mail_fprintf(bounce, "Content-Type: %s; report-type=%s;",
                      "multipart/report", "delivery-status");
     post_mail_fprintf(bounce, "\tboundary=\"%s\"", bounce_info->mime_boundary);
+    if (bounce_info->mime_encoding)
+       post_mail_fprintf(bounce, "Content-Transfer-Encoding: %s",
+                         bounce_info->mime_encoding);
     post_mail_fputs(bounce, "");
     post_mail_fputs(bounce, "This is a MIME-encapsulated message.");
 
@@ -522,6 +539,9 @@ int     bounce_original(VSTREAM *bounce, BOUNCE_INFO *bounce_info,
                      "Undelivered Message Headers" : "Undelivered Message");
     post_mail_fprintf(bounce, "Content-Type: %s", headers_only ?
                      "text/rfc822-headers" : "message/rfc822");
+    if (bounce_info->mime_encoding)
+       post_mail_fprintf(bounce, "Content-Transfer-Encoding: %s",
+                         bounce_info->mime_encoding);
     post_mail_fputs(bounce, "");
 
     /*
index f1880bae00c572a8f4761d46491e7db72ad1b972..da4606397ff488db896d8f2657aae02394a53842 100644 (file)
@@ -80,7 +80,8 @@
 /* bounce_notify_verp - send a bounce */
 
 int     bounce_notify_verp(char *service, char *queue_name,
-                                  char *queue_id, char *recipient,
+                                  char *queue_id, char *encoding,
+                                  char *recipient,
                                   char *verp_delims, int flush)
 {
     char   *myname = "bounce_notify_verp";
@@ -105,7 +106,8 @@ int     bounce_notify_verp(char *service, char *queue_name,
     /*
      * Initialize. Open queue file, bounce log, etc.
      */
-    bounce_info = bounce_mail_init(service, queue_name, queue_id, flush);
+    bounce_info = bounce_mail_init(service, queue_name, queue_id,
+                                  encoding, flush);
 
 #define NULL_SENDER            MAIL_ADDR_EMPTY /* special address */
 #define NULL_CLEANUP_FLAGS     0
index 858609b7970aaa2ad245572f1c605d4c8f5babef..889e8e9d635a0c9982f9a6408fe2ab85a0494cf4 100644 (file)
@@ -26,12 +26,12 @@ extern int bounce_append_service(char *, char *, char *, char *);
  /*
   * bounce_notify_service.c
   */
-extern int bounce_notify_service(char *, char *, char *, char *, int);
+extern int bounce_notify_service(char *, char *, char *, char *, char *, int);
 
  /*
   * bounce_notify_verp.c
   */
-extern int bounce_notify_verp(char *, char *, char *, char *, char *, int);
+extern int bounce_notify_verp(char *, char *, char *, char *, char *, char *, int);
 
  /*
   * bounce_cleanup.c
@@ -50,6 +50,7 @@ typedef struct {
     const char *service;               /* bounce or defer */
     const char *queue_name;            /* incoming, etc. */
     const char *queue_id;              /* base name */
+    const char *mime_encoding;         /* null or encoding */
     const char *mime_boundary;         /* for MIME */
     int     flush;                     /* 0=defer, other=bounce */
     VSTRING *buf;                      /* scratch pad */
@@ -59,7 +60,7 @@ typedef struct {
     BOUNCE_LOG *log_handle;            /* open logfile */
 } BOUNCE_INFO;
 
-extern BOUNCE_INFO *bounce_mail_init(const char *, const char *, const char *, int);
+extern BOUNCE_INFO *bounce_mail_init(const char *, const char *, const char *, const char *, int);
 extern void bounce_mail_free(BOUNCE_INFO *);
 extern int bounce_header(VSTREAM *, BOUNCE_INFO *, const char *);
 extern int bounce_boilerplate(VSTREAM *, BOUNCE_INFO *);
index 02ab36707b6b84ff1b3b210a538b68fab38cac43..63da2cacefde7860129d8ead92d57fc7710c905c 100644 (file)
@@ -78,6 +78,9 @@ cleanup.o: ../../include/record.h
 cleanup.o: ../../include/rec_type.h
 cleanup.o: ../../include/mail_server.h
 cleanup.o: cleanup.h
+cleanup.o: ../../include/nvtable.h
+cleanup.o: ../../include/htable.h
+cleanup.o: ../../include/mymalloc.h
 cleanup.o: ../../include/maps.h
 cleanup.o: ../../include/tok822.h
 cleanup.o: ../../include/resolve_clnt.h
@@ -100,6 +103,8 @@ cleanup_api.o: ../../include/mail_params.h
 cleanup_api.o: ../../include/mail_stream.h
 cleanup_api.o: cleanup.h
 cleanup_api.o: ../../include/argv.h
+cleanup_api.o: ../../include/nvtable.h
+cleanup_api.o: ../../include/htable.h
 cleanup_api.o: ../../include/maps.h
 cleanup_api.o: ../../include/dict.h
 cleanup_api.o: ../../include/tok822.h
@@ -113,6 +118,9 @@ cleanup_envelope.o: ../../include/vstring.h
 cleanup_envelope.o: ../../include/vbuf.h
 cleanup_envelope.o: ../../include/vstream.h
 cleanup_envelope.o: ../../include/mymalloc.h
+cleanup_envelope.o: ../../include/stringops.h
+cleanup_envelope.o: ../../include/nvtable.h
+cleanup_envelope.o: ../../include/htable.h
 cleanup_envelope.o: ../../include/record.h
 cleanup_envelope.o: ../../include/rec_type.h
 cleanup_envelope.o: ../../include/cleanup_user.h
@@ -138,11 +146,16 @@ cleanup_extracted.o: ../../include/vbuf.h
 cleanup_extracted.o: ../../include/vstream.h
 cleanup_extracted.o: ../../include/argv.h
 cleanup_extracted.o: ../../include/mymalloc.h
+cleanup_extracted.o: ../../include/nvtable.h
+cleanup_extracted.o: ../../include/htable.h
 cleanup_extracted.o: ../../include/cleanup_user.h
 cleanup_extracted.o: ../../include/record.h
 cleanup_extracted.o: ../../include/rec_type.h
 cleanup_extracted.o: ../../include/mail_params.h
 cleanup_extracted.o: ../../include/ext_prop.h
+cleanup_extracted.o: ../../include/mail_proto.h
+cleanup_extracted.o: ../../include/iostuff.h
+cleanup_extracted.o: ../../include/attr.h
 cleanup_extracted.o: cleanup.h
 cleanup_extracted.o: ../../include/maps.h
 cleanup_extracted.o: ../../include/dict.h
@@ -164,6 +177,9 @@ cleanup_init.o: ../../include/vstring.h
 cleanup_init.o: ../../include/vbuf.h
 cleanup_init.o: ../../include/vstream.h
 cleanup_init.o: ../../include/argv.h
+cleanup_init.o: ../../include/nvtable.h
+cleanup_init.o: ../../include/htable.h
+cleanup_init.o: ../../include/mymalloc.h
 cleanup_init.o: ../../include/maps.h
 cleanup_init.o: ../../include/dict.h
 cleanup_init.o: ../../include/tok822.h
@@ -186,6 +202,8 @@ cleanup_map11.o: ../../include/maps.h
 cleanup_map11.o: ../../include/quote_822_local.h
 cleanup_map11.o: ../../include/quote_flags.h
 cleanup_map11.o: cleanup.h
+cleanup_map11.o: ../../include/nvtable.h
+cleanup_map11.o: ../../include/htable.h
 cleanup_map11.o: ../../include/tok822.h
 cleanup_map11.o: ../../include/resolve_clnt.h
 cleanup_map11.o: ../../include/been_here.h
@@ -207,6 +225,8 @@ cleanup_map1n.o: ../../include/quote_822_local.h
 cleanup_map1n.o: ../../include/quote_flags.h
 cleanup_map1n.o: ../../include/been_here.h
 cleanup_map1n.o: cleanup.h
+cleanup_map1n.o: ../../include/nvtable.h
+cleanup_map1n.o: ../../include/htable.h
 cleanup_map1n.o: ../../include/tok822.h
 cleanup_map1n.o: ../../include/resolve_clnt.h
 cleanup_map1n.o: ../../include/mail_stream.h
@@ -227,6 +247,7 @@ cleanup_masquerade.o: ../../include/quote_822_local.h
 cleanup_masquerade.o: ../../include/quote_flags.h
 cleanup_masquerade.o: cleanup.h
 cleanup_masquerade.o: ../../include/vstream.h
+cleanup_masquerade.o: ../../include/nvtable.h
 cleanup_masquerade.o: ../../include/maps.h
 cleanup_masquerade.o: ../../include/dict.h
 cleanup_masquerade.o: ../../include/been_here.h
@@ -241,6 +262,9 @@ cleanup_message.o: ../../include/vstream.h
 cleanup_message.o: ../../include/argv.h
 cleanup_message.o: ../../include/split_at.h
 cleanup_message.o: ../../include/mymalloc.h
+cleanup_message.o: ../../include/stringops.h
+cleanup_message.o: ../../include/nvtable.h
+cleanup_message.o: ../../include/htable.h
 cleanup_message.o: ../../include/record.h
 cleanup_message.o: ../../include/rec_type.h
 cleanup_message.o: ../../include/cleanup_user.h
@@ -254,6 +278,9 @@ cleanup_message.o: ../../include/mail_date.h
 cleanup_message.o: ../../include/mail_addr.h
 cleanup_message.o: ../../include/is_header.h
 cleanup_message.o: ../../include/ext_prop.h
+cleanup_message.o: ../../include/mail_proto.h
+cleanup_message.o: ../../include/iostuff.h
+cleanup_message.o: ../../include/attr.h
 cleanup_message.o: cleanup.h
 cleanup_message.o: ../../include/maps.h
 cleanup_message.o: ../../include/dict.h
@@ -272,6 +299,9 @@ cleanup_out.o: ../../include/cleanup_user.h
 cleanup_out.o: ../../include/mail_params.h
 cleanup_out.o: cleanup.h
 cleanup_out.o: ../../include/argv.h
+cleanup_out.o: ../../include/nvtable.h
+cleanup_out.o: ../../include/htable.h
+cleanup_out.o: ../../include/mymalloc.h
 cleanup_out.o: ../../include/maps.h
 cleanup_out.o: ../../include/dict.h
 cleanup_out.o: ../../include/tok822.h
@@ -290,6 +320,9 @@ cleanup_out_recipient.o: cleanup.h
 cleanup_out_recipient.o: ../../include/vstring.h
 cleanup_out_recipient.o: ../../include/vbuf.h
 cleanup_out_recipient.o: ../../include/vstream.h
+cleanup_out_recipient.o: ../../include/nvtable.h
+cleanup_out_recipient.o: ../../include/htable.h
+cleanup_out_recipient.o: ../../include/mymalloc.h
 cleanup_out_recipient.o: ../../include/maps.h
 cleanup_out_recipient.o: ../../include/dict.h
 cleanup_out_recipient.o: ../../include/tok822.h
@@ -309,6 +342,9 @@ cleanup_rewrite.o: ../../include/quote_flags.h
 cleanup_rewrite.o: cleanup.h
 cleanup_rewrite.o: ../../include/vstream.h
 cleanup_rewrite.o: ../../include/argv.h
+cleanup_rewrite.o: ../../include/nvtable.h
+cleanup_rewrite.o: ../../include/htable.h
+cleanup_rewrite.o: ../../include/mymalloc.h
 cleanup_rewrite.o: ../../include/maps.h
 cleanup_rewrite.o: ../../include/dict.h
 cleanup_rewrite.o: ../../include/been_here.h
@@ -320,10 +356,12 @@ cleanup_state.o: ../../include/mymalloc.h
 cleanup_state.o: ../../include/vstring.h
 cleanup_state.o: ../../include/vbuf.h
 cleanup_state.o: ../../include/argv.h
+cleanup_state.o: ../../include/htable.h
 cleanup_state.o: ../../include/been_here.h
 cleanup_state.o: ../../include/mail_params.h
 cleanup_state.o: cleanup.h
 cleanup_state.o: ../../include/vstream.h
+cleanup_state.o: ../../include/nvtable.h
 cleanup_state.o: ../../include/maps.h
 cleanup_state.o: ../../include/dict.h
 cleanup_state.o: ../../include/tok822.h
index 62e01f38f6afe0950d2170a74d66fbe05297068b..082bd4e74e78b212e1a6dcece8fd9fa8c5569711 100644 (file)
@@ -14,6 +14,7 @@
 #include <vstring.h>
 #include <vstream.h>
 #include <argv.h>
+#include <nvtable.h>
 
  /*
   * Global library.
@@ -61,6 +62,7 @@ typedef struct CLEANUP_STATE {
     int     end_seen;                  /* REC_TYPE_END seen */
     int     rcpt_count;                        /* recipient count */
     char   *reason;                    /* failure reason */
+    NVTABLE *attr;                     /* queue file attribute list */
 } CLEANUP_STATE;
 
  /*
index 2f752e459a90d1255b6d5bfa3265006a0bf464cb..80cac48e39ab035cda8b456a3506cda4ad3d92d7 100644 (file)
 /*     These flags control the handling of data errors, and must be set
 /*     before processing the first message record.
 /* .IP CLEANUP_FLAG_BOUNCE
-/*     The cleanup server is responsible for returning undeliverable 
+/*     The cleanup server is responsible for returning undeliverable
 /*     mail (too many hops, message too large) to the sender.
 /* .IP CLEANUP_FLAG_FILTER
-/*     Enable header/body filtering. This should be enabled only with mail 
-/*     that enters Postfix, not with locally forwarded mail or with bounce 
+/*     Enable header/body filtering. This should be enabled only with mail
+/*     that enters Postfix, not with locally forwarded mail or with bounce
 /*     messages.
 /* .IP CLEANUP_FLAG_EXTRACT
 /*     Extract recipients from message headers when no recipients are
@@ -125,7 +125,7 @@ CLEANUP_STATE *cleanup_open(void)
      * that the runtime error handler can clean up in case of problems.
      */
     state->handle = mail_stream_file(MAIL_QUEUE_INCOMING,
-                                    MAIL_CLASS_PUBLIC, var_queue_service, 0);
+                                  MAIL_CLASS_PUBLIC, var_queue_service, 0);
     state->dst = state->handle->stream;
     cleanup_path = mystrdup(VSTREAM_PATH(state->dst));
     state->queue_id = mystrdup(state->handle->id);
@@ -176,6 +176,7 @@ int     cleanup_flush(CLEANUP_STATE *state)
 {
     char   *junk;
     int     status;
+    char   *encoding;
 
     /*
      * Ignore recipient extraction alarms if (a) we did (not need to) extract
@@ -235,7 +236,10 @@ int     cleanup_flush(CLEANUP_STATE *state)
                              "%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->queue_id,
+               (encoding = nvtable_find(state->attr, MAIL_ATTR_ENCODING)) ?
+                               encoding : MAIL_ATTR_ENC_NONE,
+                               state->sender) == 0) {
                state->errs = 0;
            } else {
                if (var_soft_bounce == 0) {
index f4fd30e75d09557d098e4062abafe4e8ddddd369..00858cc91cbae0c31b8385677adb162a5aa5163c 100644 (file)
@@ -56,6 +56,8 @@
 #include <vstring.h>
 #include <vstream.h>
 #include <mymalloc.h>
+#include <stringops.h>
+#include <nvtable.h>
 
 /* Global library. */
 
@@ -104,6 +106,10 @@ void    cleanup_envelope(CLEANUP_STATE *state, int type, char *str, int len)
 
 static void cleanup_envelope_process(CLEANUP_STATE *state, int type, char *buf, int len)
 {
+    char   *attr_name;
+    char   *attr_value;
+    const char *error_text;
+
     if (type == REC_TYPE_MESG) {
        if (state->sender == 0 || state->time == 0) {
            msg_warn("%s: missing sender or time envelope record",
@@ -196,6 +202,21 @@ static void cleanup_envelope_process(CLEANUP_STATE *state, int type, char *buf,
            state->errs |= CLEANUP_STAT_BAD;
            return;
        }
+    } else if (type == REC_TYPE_ATTR) {
+       if (state->attr->used >= var_qattr_count_limit) {
+           msg_warn("%s: queue file attribute count exceeds safety limit: %d",
+                    state->queue_id, var_qattr_count_limit);
+           state->errs |= CLEANUP_STAT_BAD;
+           return;
+       }
+       cleanup_out(state, type, buf, len);
+       if ((error_text = split_nameval(buf, &attr_name, &attr_value)) != 0) {
+           msg_warn("%s: malformed attribute: %s: %.100s",
+                    state->queue_id, error_text, buf);
+           state->errs |= CLEANUP_STAT_BAD;
+           return;
+       }
+       nvtable_update(state->attr, attr_name, attr_value);
     } else {
        cleanup_out(state, type, buf, len);
     }
index b9721bd88e3bcd483f506712ed3f497841c64ae5..df3bcd993d84d2f4f20258e422916b9f5e0bc3f4 100644 (file)
@@ -51,6 +51,7 @@
 #include <vstream.h>
 #include <argv.h>
 #include <mymalloc.h>
+#include <nvtable.h>
 
 /* Global library. */
 
@@ -59,6 +60,7 @@
 #include <rec_type.h>
 #include <mail_params.h>
 #include <ext_prop.h>
+#include <mail_proto.h>
 
 /* Application-specific. */
 
@@ -72,12 +74,23 @@ static void cleanup_extracted_process(CLEANUP_STATE *, int, char *, int);
 
 void    cleanup_extracted(CLEANUP_STATE *state, int type, char *buf, int len)
 {
+    const char *encoding;
 
     /*
      * Start the extracted segment.
      */
     cleanup_out_string(state, REC_TYPE_XTRA, "");
 
+    /*
+     * Older Postfix versions didn't emit encoding information, so this
+     * record can only be optional. Putting this before the mandatory
+     * Return-Receipt-To and Errors-To ensures that the queue manager will
+     * pick up the content encoding before starting deliveries.
+     */
+    if ((encoding = nvtable_find(state->attr, MAIL_ATTR_ENCODING)) != 0)
+       cleanup_out_format(state, REC_TYPE_ATTR, "%s=%s",
+                          MAIL_ATTR_ENCODING, encoding);
+
     /*
      * Always emit Return-Receipt-To and Errors-To records, and always emit
      * them ahead of extracted recipients, so that the queue manager does not
index b3e7a0157e4cd2be359e2713479f29cb6f47ec57..866527936a98c56c84b01f5ee1d4c47aec8e16f3 100644 (file)
@@ -108,12 +108,14 @@ char   *var_always_bcc;                   /* big brother */
 int     var_extra_rcpt_limit;          /* recipient extract limit */
 char   *var_rcpt_witheld;              /* recipients not disclosed */
 char   *var_masq_classes;              /* what to masquerade */
+int     var_qattr_count_limit;         /* named attribute limit */
 
 CONFIG_INT_TABLE cleanup_int_table[] = {
     VAR_HOPCOUNT_LIMIT, DEF_HOPCOUNT_LIMIT, &var_hopcount_limit, 1, 0,
     VAR_HEADER_LIMIT, DEF_HEADER_LIMIT, &var_header_limit, 1, 0,
     VAR_DUP_FILTER_LIMIT, DEF_DUP_FILTER_LIMIT, &var_dup_filter_limit, 0, 0,
     VAR_EXTRA_RCPT_LIMIT, DEF_EXTRA_RCPT_LIMIT, &var_extra_rcpt_limit, 0, 0,
+    VAR_QATTR_COUNT_LIMIT, DEF_QATTR_COUNT_LIMIT, &var_qattr_count_limit, 1, 0,
     0,
 };
 
index 2d25dddcb6cb4652490cae611173bc91ab4f2ef1..3357152206e86f217e622a2e9a5fb9032528e69b 100644 (file)
@@ -61,6 +61,8 @@
 #include <argv.h>
 #include <split_at.h>
 #include <mymalloc.h>
+#include <stringops.h>
+#include <nvtable.h>
 
 /* Global library. */
 
@@ -75,6 +77,7 @@
 #include <mail_addr.h>
 #include <is_header.h>
 #include <ext_prop.h>
+#include <mail_proto.h>
 
 /* Application-specific. */
 
@@ -263,6 +266,7 @@ static int cleanup_act(CLEANUP_STATE *state, char *context, char *buf,
 {
     const char *optional_text = value + strcspn(value, " \t");
     int     command_len = optional_text - value;
+    const char *origin;
 
     while (*optional_text && ISSPACE(*optional_text))
        optional_text++;
@@ -276,8 +280,10 @@ static int cleanup_act(CLEANUP_STATE *state, char *context, char *buf,
            state->reason = mystrdup(*optional_text ? optional_text :
                                     cleanup_strerror(CLEANUP_STAT_CONT));
        state->errs |= CLEANUP_STAT_CONT;
-       msg_info("%s: reject: %s %.200s; from=<%s> to=<%s>: %s",
-                state->queue_id, context, buf, state->sender,
+       if ((origin = nvtable_find(state->attr, MAIL_ATTR_ORIGIN)) == 0)
+           origin = MAIL_ATTR_ORG_NONE;
+       msg_info("%s: reject: %s %.200s from %s; from=<%s> to=<%s>: %s",
+                state->queue_id, context, buf, origin, state->sender,
                 state->recip ? state->recip : "unknown",
                 state->reason);
        return (CLEANUP_ACT_KEEP);
@@ -310,6 +316,20 @@ static void cleanup_header(CLEANUP_STATE *state)
 {
     char   *myname = "cleanup_header";
     HEADER_OPTS *hdr_opts;
+    char   *hdrval;
+    struct code_map {
+       const char *name;
+       const char *encoding;
+    };
+    static struct code_map code_map[] = {      /* RFC 2045 */
+       "7bit", MAIL_ATTR_ENC_7BIT,
+       "8bit", MAIL_ATTR_ENC_8BIT,
+       "binary", MAIL_ATTR_ENC_8BIT,   /* XXX Violation */
+       "quoted-printable", MAIL_ATTR_ENC_7BIT,
+       "base64", MAIL_ATTR_ENC_7BIT,
+       0,
+    };
+    struct code_map *cmp;
 
     if (msg_verbose)
        msg_info("%s: '%s'", myname, vstring_str(state->header_buf));
@@ -365,15 +385,28 @@ static void cleanup_header(CLEANUP_STATE *state)
      */
     else {
        state->headers_seen |= (1 << hdr_opts->type);
+       hdrval = vstring_str(state->header_buf) + strlen(hdr_opts->name) + 2;
+       while (ISSPACE(*hdrval))
+           hdrval++;
+       trimblanks(hdrval, 0);
        if (hdr_opts->type == HDR_MESSAGE_ID)
-           msg_info("%s: message-id=%s", state->queue_id,
-              vstring_str(state->header_buf) + strlen(hdr_opts->name) + 2);
+           msg_info("%s: message-id=%s", state->queue_id, hdrval);
        if (hdr_opts->type == HDR_RESENT_MESSAGE_ID)
-           msg_info("%s: resent-message-id=%s", state->queue_id,
-              vstring_str(state->header_buf) + strlen(hdr_opts->name) + 2);
+           msg_info("%s: resent-message-id=%s", state->queue_id, hdrval);
        if (hdr_opts->type == HDR_RECEIVED)
            if (++state->hop_count >= var_hopcount_limit)
                state->errs |= CLEANUP_STAT_HOPS;
+       if (hdr_opts->type == HDR_CONTENT_TRANSFER_ENCODING) {
+           if (nvtable_find(state->attr, MAIL_ATTR_ENCODING) == 0) {
+               for (cmp = code_map; cmp->name != 0; cmp++) {
+                   if (strcasecmp(hdrval, cmp->name) == 0) {
+                       nvtable_update(state->attr, MAIL_ATTR_ENCODING,
+                                      cmp->encoding);
+                       break;
+                   }
+               }
+           }
+       }
        if (CLEANUP_OUT_OK(state)) {
            if (hdr_opts->flags & HDR_OPT_RR)
                state->resent = "Resent-";
index bfe6bacf970aa810bad274e87128ce0fa9f7364b..6df5fb894e1856c7c83f8ecb03df21ff0c4bf024 100644 (file)
@@ -38,6 +38,7 @@
 #include <mymalloc.h>
 #include <vstring.h>
 #include <argv.h>
+#include <htable.h>
 
 /* Global library. */
 
@@ -86,6 +87,7 @@ CLEANUP_STATE *cleanup_state_alloc(void)
     state->end_seen = 0;
     state->rcpt_count = 0;
     state->reason = 0;
+    state->attr = nvtable_create(10);
     return (state);
 }
 
@@ -117,5 +119,6 @@ void    cleanup_state_free(CLEANUP_STATE *state)
     been_here_free(state->dups);
     if (state->reason)
        myfree(state->reason);
+    nvtable_free(state->attr);
     myfree((char *) state);
 }
index 821147886319a1ad64a3709f28717b968e0d7c9d..3bb158889ce8edb1b36475e7f204f09aba156471 100644 (file)
@@ -6,44 +6,49 @@
 /* SYNOPSIS
 /*     #include <abounce.h>
 /*
-/*     void    abounce_flush(flags, queue, id, sender, callback, context)
+/*     void    abounce_flush(flags, queue, id, encoding, sender, callback, context)
 /*     int     flags;
 /*     const char *queue;
 /*     const char *id;
+/*     const char *encoding;
 /*     const char *sender;
 /*     void    (*callback)(int status, char *context);
 /*     char    *context;
 /*
-/*     void    abounce_flush_verp(flags, queue, id, sender, verp, callback, context)
+/*     void    abounce_flush_verp(flags, queue, id, encoding, sender, verp, callback, context)
 /*     int     flags;
 /*     const char *queue;
 /*     const char *id;
+/*     const char *encoding;
 /*     const char *sender;
 /*     const char *verp;
 /*     void    (*callback)(int status, char *context);
 /*     char    *context;
 /*
-/*     void    adefer_flush(flags, queue, id, sender, callback, context)
+/*     void    adefer_flush(flags, queue, id, encoding, sender, callback, context)
 /*     int     flags;
 /*     const char *queue;
 /*     const char *id;
+/*     const char *encoding;
 /*     const char *sender;
 /*     void    (*callback)(int status, char *context);
 /*     char    *context;
 /*
-/*     void    adefer_flush_verp(flags, queue, id, sender, verp, callback, context)
+/*     void    adefer_flush_verp(flags, queue, id, encoding, sender, verp, callback, context)
 /*     int     flags;
 /*     const char *queue;
 /*     const char *id;
+/*     const char *encoding;
 /*     const char *sender;
 /*     const char *verp;
 /*     void    (*callback)(int status, char *context);
 /*     char    *context;
 /*
-/*     void    adefer_warn(flags, queue, id, sender, callback, context)
+/*     void    adefer_warn(flags, queue, id, encoding, sender, callback, context)
 /*     int     flags;
 /*     const char *queue;
 /*     const char *id;
+/*     const char *encoding;
 /*     const char *sender;
 /*     void    (*callback)(int status, char *context);
 /*     char    *context;
@@ -86,6 +91,8 @@
 /* .IP id
 /*     The message queue id if the original message file. The bounce log
 /*     file has the same name as the original message file.
+/* .IP encoding
+/*     The body content encoding: MAIL_ATTR_ENC_{7BIT,8BIT,NONE}.
 /* .IP sender
 /*     The sender envelope address.
 /* .IP verp
@@ -182,7 +189,9 @@ static void abounce_event(int unused_event, char *context)
 static void abounce_request_verp(const char *class, const char *service,
                                         int command, int flags,
                                         const char *queue, const char *id,
-                                      const char *sender, const char *verp,
+                                        const char *encoding,
+                                        const char *sender,
+                                        const char *verp,
                                         ABOUNCE_FN callback,
                                         char *context)
 {
@@ -205,6 +214,7 @@ static void abounce_request_verp(const char *class, const char *service,
                   ATTR_TYPE_NUM, MAIL_ATTR_FLAGS, flags,
                   ATTR_TYPE_STR, MAIL_ATTR_QUEUE, queue,
                   ATTR_TYPE_STR, MAIL_ATTR_QUEUEID, id,
+                  ATTR_TYPE_STR, MAIL_ATTR_ENCODING, encoding,
                   ATTR_TYPE_STR, MAIL_ATTR_SENDER, sender,
                   ATTR_TYPE_STR, MAIL_ATTR_VERPDL, verp,
                   ATTR_TYPE_END) == 0
@@ -218,23 +228,25 @@ static void abounce_request_verp(const char *class, const char *service,
 /* abounce_flush_verp - asynchronous bounce flush */
 
 void    abounce_flush_verp(int flags, const char *queue, const char *id,
-                                  const char *sender, const char *verp,
-                                  ABOUNCE_FN callback, char *context)
+                                  const char *encoding, const char *sender,
+                                  const char *verp, ABOUNCE_FN callback,
+                                  char *context)
 {
     abounce_request_verp(MAIL_CLASS_PRIVATE, var_bounce_service,
-                        BOUNCE_CMD_VERP, flags, queue, id, sender, verp,
-                        callback, context);
+                        BOUNCE_CMD_VERP, flags, queue, id, encoding,
+                        sender, verp, callback, context);
 }
 
 /* adefer_flush_verp - asynchronous defer flush */
 
 void    adefer_flush_verp(int flags, const char *queue, const char *id,
-                                 const char *sender, const char *verp,
-                                 ABOUNCE_FN callback, char *context)
+                                 const char *encoding, const char *sender,
+                                 const char *verp, ABOUNCE_FN callback,
+                                 char *context)
 {
     abounce_request_verp(MAIL_CLASS_PRIVATE, var_defer_service,
-                        BOUNCE_CMD_VERP, flags, queue, id, sender, verp,
-                        callback, context);
+                        BOUNCE_CMD_VERP, flags, queue, id, encoding,
+                        sender, verp, callback, context);
 }
 
 /* abounce_request - suspend pseudo thread until server reply event */
@@ -242,9 +254,8 @@ void    adefer_flush_verp(int flags, const char *queue, const char *id,
 static void abounce_request(const char *class, const char *service,
                                    int command, int flags,
                                    const char *queue, const char *id,
-                                   const char *sender,
-                                   ABOUNCE_FN callback,
-                                   char *context)
+                                   const char *encoding, const char *sender,
+                                   ABOUNCE_FN callback, char *context)
 {
     ABOUNCE *ap;
 
@@ -265,6 +276,7 @@ static void abounce_request(const char *class, const char *service,
                   ATTR_TYPE_NUM, MAIL_ATTR_FLAGS, flags,
                   ATTR_TYPE_STR, MAIL_ATTR_QUEUE, queue,
                   ATTR_TYPE_STR, MAIL_ATTR_QUEUEID, id,
+                  ATTR_TYPE_STR, MAIL_ATTR_ENCODING, encoding,
                   ATTR_TYPE_STR, MAIL_ATTR_SENDER, sender,
                   ATTR_TYPE_END) == 0
        && vstream_fflush(ap->fp) == 0) {
@@ -277,26 +289,29 @@ static void abounce_request(const char *class, const char *service,
 /* abounce_flush - asynchronous bounce flush */
 
 void    abounce_flush(int flags, const char *queue, const char *id,
-                    const char *sender, ABOUNCE_FN callback, char *context)
+                             const char *encoding, const char *sender,
+                             ABOUNCE_FN callback, char *context)
 {
     abounce_request(MAIL_CLASS_PRIVATE, var_bounce_service, BOUNCE_CMD_FLUSH,
-                   flags, queue, id, sender, callback, context);
+                   flags, queue, id, encoding, sender, callback, context);
 }
 
 /* adefer_flush - asynchronous defer flush */
 
 void    adefer_flush(int flags, const char *queue, const char *id,
-                    const char *sender, ABOUNCE_FN callback, char *context)
+                            const char *encoding, const char *sender,
+                            ABOUNCE_FN callback, char *context)
 {
     abounce_request(MAIL_CLASS_PRIVATE, var_defer_service, BOUNCE_CMD_FLUSH,
-                   flags, queue, id, sender, callback, context);
+                   flags, queue, id, encoding, sender, callback, context);
 }
 
 /* adefer_warn - send copy of defer log to sender as warning bounce */
 
 void    adefer_warn(int flags, const char *queue, const char *id,
-                    const char *sender, ABOUNCE_FN callback, char *context)
+                           const char *encoding, const char *sender,
+                           ABOUNCE_FN callback, char *context)
 {
     abounce_request(MAIL_CLASS_PRIVATE, var_defer_service, BOUNCE_CMD_WARN,
-                   flags, queue, id, sender, callback, context);
+                   flags, queue, id, encoding, sender, callback, context);
 }
index 69542383a5b75fd1fce459b6dccb2d4f106a41e1..bcc70e2f63c534e2f855d8ea7cc4b5335349d115 100644 (file)
   */
 typedef void (*ABOUNCE_FN) (int, char *);
 
-extern void abounce_flush(int, const char *, const char *, const char *, ABOUNCE_FN, char *);
-extern void adefer_flush(int, const char *, const char *, const char *, ABOUNCE_FN, char *);
-extern void adefer_warn(int, const char *, const char *, const char *, ABOUNCE_FN, char *);
+extern void abounce_flush(int, const char *, const char *, const char *, const char *, ABOUNCE_FN, char *);
+extern void adefer_flush(int, const char *, const char *, const char *, const char *, ABOUNCE_FN, char *);
+extern void adefer_warn(int, const char *, const char *, const char *, const char *, ABOUNCE_FN, char *);
 
-extern void abounce_flush_verp(int, const char *, const char *, const char *, const char *, ABOUNCE_FN, char *);
-extern void adefer_flush_verp(int, const char *, const char *, const char *, const char *, ABOUNCE_FN, char *);
+extern void abounce_flush_verp(int, const char *, const char *, const char *, const char *, const char *, ABOUNCE_FN, char *);
+extern void adefer_flush_verp(int, const char *, const char *, const char *, const char *, const char *, ABOUNCE_FN, char *);
 
 /* LICENSE
 /* .ad
index 67f97bb99722c2ec8fbf5743c805059358872032..05648cbc30347de918ac50ae0423269169622fa6 100644 (file)
 /*     const char *format;
 /*     va_list ap;
 /*
-/*     int     bounce_flush(flags, queue, id, sender)
+/*     int     bounce_flush(flags, queue, id, encoding, sender)
 /*     int     flags;
 /*     const char *queue;
 /*     const char *id;
+/*     const char *encoding;
 /*     const char *sender;
 /* DESCRIPTION
 /*     This module implements the client interface to the message
@@ -56,6 +57,8 @@
 /* .IP id
 /*     The message queue id if the original message file. The bounce log
 /*     file has the same name as the original message file.
+/* .IP encoding
+/*     The body content encoding: MAIL_ATTR_ENC_{7BIT,8BIT,NONE}.
 /* .IP sender
 /*     The sender envelope address.
 /* .IP relay
@@ -168,7 +171,7 @@ int     vbounce_append(int flags, const char *id, const char *recipient,
 /* bounce_flush - flush the bounce log and deliver to the sender */
 
 int     bounce_flush(int flags, const char *queue, const char *id,
-                            const char *sender)
+                            const char *encoding, const char *sender)
 {
 
     /*
@@ -182,6 +185,7 @@ int     bounce_flush(int flags, const char *queue, const char *id,
                            ATTR_TYPE_NUM, MAIL_ATTR_FLAGS, flags,
                            ATTR_TYPE_STR, MAIL_ATTR_QUEUE, queue,
                            ATTR_TYPE_STR, MAIL_ATTR_QUEUEID, id,
+                           ATTR_TYPE_STR, MAIL_ATTR_ENCODING, encoding,
                            ATTR_TYPE_STR, MAIL_ATTR_SENDER, sender,
                            ATTR_TYPE_END) == 0) {
        return (0);
index 018b91a4fe6a444452f98d2af1587c96a2df4174..11b91eaf5b7d8b0beae004a1d14206dc10ed2469 100644 (file)
@@ -25,7 +25,7 @@ extern int PRINTFLIKE(6, 7) bounce_append(int, const char *, const char *,
                                                  const char *,...);
 extern int vbounce_append(int, const char *, const char *, const char *,
                                  time_t, const char *, va_list);
-extern int bounce_flush(int, const char *, const char *, const char *);
+extern int bounce_flush(int, const char *, const char *, const char *, const char *);
 
 extern int PRINTFLIKE(8, 9) bounce_recip(int, const char *, const char *,
                                                 const char *, const char *,
index dd331230e596506208f4cc496e613f7655e09d8f..862f3a6fdcb5ecca583b98ce9996b1c5d7556993 100644 (file)
 /*     const char *format;
 /*     va_list ap;
 /*
-/*     int     defer_flush(flags, queue, id, sender)
+/*     int     defer_flush(flags, queue, id, encoding, sender)
 /*     int     flags;
 /*     const char *queue;
 /*     const char *id;
+/*     const char *encoding;
 /*     const char *sender;
 /*
 /*     int     defer_warn(flags, queue, id, sender)
@@ -70,6 +71,8 @@
 /* .IP recipient
 /*     A recipient address that is being deferred. The domain part
 /*     of the address is marked dead (for a limited amount of time).
+/* .IP encoding
+/*     The body content encoding: MAIL_ATTR_ENC_{7BIT,8BIT,NONE}.
 /* .IP sender
 /*     The sender envelope address.
 /* .IP relay
@@ -178,15 +181,16 @@ int     vdefer_append(int flags, const char *id, const char *recipient,
 /* defer_flush - flush the defer log and deliver to the sender */
 
 int     defer_flush(int flags, const char *queue, const char *id,
-                           const char *sender)
+                           const char *encoding, const char *sender)
 {
     if (mail_command_client(MAIL_CLASS_PRIVATE, var_defer_service,
-                          ATTR_TYPE_NUM, MAIL_ATTR_NREQ, BOUNCE_CMD_FLUSH,
-                          ATTR_TYPE_NUM, MAIL_ATTR_FLAGS, flags,
-                          ATTR_TYPE_STR, MAIL_ATTR_QUEUE, queue,
-                          ATTR_TYPE_STR, MAIL_ATTR_QUEUEID, id,
-                          ATTR_TYPE_STR, MAIL_ATTR_SENDER, sender,
-                          ATTR_TYPE_END) == 0) {
+                           ATTR_TYPE_NUM, MAIL_ATTR_NREQ, BOUNCE_CMD_FLUSH,
+                           ATTR_TYPE_NUM, MAIL_ATTR_FLAGS, flags,
+                           ATTR_TYPE_STR, MAIL_ATTR_QUEUE, queue,
+                           ATTR_TYPE_STR, MAIL_ATTR_QUEUEID, id,
+                           ATTR_TYPE_STR, MAIL_ATTR_ENCODING, encoding,
+                           ATTR_TYPE_STR, MAIL_ATTR_SENDER, sender,
+                           ATTR_TYPE_END) == 0) {
        return (0);
     } else {
        return (-1);
@@ -200,12 +204,12 @@ int     defer_warn(int flags, const char *queue, const char *id,
                           const char *sender)
 {
     if (mail_command_client(MAIL_CLASS_PRIVATE, var_defer_service,
-                          ATTR_TYPE_NUM, MAIL_ATTR_NREQ, BOUNCE_CMD_WARN,
-                          ATTR_TYPE_NUM, MAIL_ATTR_FLAGS, flags,
-                          ATTR_TYPE_STR, MAIL_ATTR_QUEUE, queue,
-                          ATTR_TYPE_STR, MAIL_ATTR_QUEUEID, id,
-                          ATTR_TYPE_STR, MAIL_ATTR_SENDER, sender,
-                          ATTR_TYPE_END) == 0) {
+                           ATTR_TYPE_NUM, MAIL_ATTR_NREQ, BOUNCE_CMD_WARN,
+                           ATTR_TYPE_NUM, MAIL_ATTR_FLAGS, flags,
+                           ATTR_TYPE_STR, MAIL_ATTR_QUEUE, queue,
+                           ATTR_TYPE_STR, MAIL_ATTR_QUEUEID, id,
+                           ATTR_TYPE_STR, MAIL_ATTR_SENDER, sender,
+                           ATTR_TYPE_END) == 0) {
        return (0);
     } else {
        return (-1);
index d23e2d664ace786169763a88c4c2cf20932572c8..18bbbddd903e2aa8ae5b6e4fa142c387e99951f5 100644 (file)
@@ -29,7 +29,7 @@ extern int PRINTFLIKE(6, 7) defer_append(int, const char *, const char *,
                                    const char *, time_t, const char *,...);
 extern int vdefer_append(int, const char *, const char *, const char *,
                                 time_t, const char *, va_list);
-extern int defer_flush(int, const char *, const char *, const char *);
+extern int defer_flush(int, const char *, const char *, const char *, const char *);
 
 extern int defer_warn(int, const char *, const char *, const char *);
 
index 35c83e78061852536bab5475a795792a4929a8af..75dd3c61bcea64e91a1c9379846ecfb1f4cf4e28 100644 (file)
@@ -15,6 +15,7 @@
 /*             long    data_offset;
 /*             long    data_size;
 /*             char    *nexthop;
+/*             char    *encoding;
 /*             char    *sender;
 /*             char    *errors_to;
 /*             char    *return_receipt;
@@ -169,6 +170,7 @@ static int deliver_request_get(VSTREAM *stream, DELIVER_REQUEST *request)
     static VSTRING *queue_name;
     static VSTRING *queue_id;
     static VSTRING *nexthop;
+    static VSTRING *encoding;
     static VSTRING *address;
     static VSTRING *errors_to;
     static VSTRING *return_receipt;
@@ -183,6 +185,7 @@ static int deliver_request_get(VSTREAM *stream, DELIVER_REQUEST *request)
        queue_name = vstring_alloc(10);
        queue_id = vstring_alloc(10);
        nexthop = vstring_alloc(10);
+       encoding = vstring_alloc(10);
        address = vstring_alloc(10);
        errors_to = vstring_alloc(10);
        return_receipt = vstring_alloc(10);
@@ -199,11 +202,12 @@ static int deliver_request_get(VSTREAM *stream, DELIVER_REQUEST *request)
                  ATTR_TYPE_LONG, MAIL_ATTR_OFFSET, &request->data_offset,
                  ATTR_TYPE_LONG, MAIL_ATTR_SIZE, &request->data_size,
                  ATTR_TYPE_STR, MAIL_ATTR_NEXTHOP, nexthop,
+                 ATTR_TYPE_STR, MAIL_ATTR_ENCODING, encoding,
                  ATTR_TYPE_STR, MAIL_ATTR_SENDER, address,
                  ATTR_TYPE_STR, MAIL_ATTR_ERRTO, errors_to,
                  ATTR_TYPE_STR, MAIL_ATTR_RRCPT, return_receipt,
                  ATTR_TYPE_LONG, MAIL_ATTR_TIME, &request->arrival_time,
-                 ATTR_TYPE_END) != 10)
+                 ATTR_TYPE_END) != 11)
        return (-1);
     if (mail_open_ok(vstring_str(queue_name),
                     vstring_str(queue_id), &st, &path) == 0)
@@ -212,6 +216,7 @@ static int deliver_request_get(VSTREAM *stream, DELIVER_REQUEST *request)
     request->queue_name = mystrdup(vstring_str(queue_name));
     request->queue_id = mystrdup(vstring_str(queue_id));
     request->nexthop = mystrdup(vstring_str(nexthop));
+    request->encoding = mystrdup(vstring_str(encoding));
     request->sender = mystrdup(vstring_str(address));
     request->errors_to = mystrdup(vstring_str(errors_to));
     request->return_receipt = mystrdup(vstring_str(return_receipt));
@@ -274,6 +279,7 @@ static DELIVER_REQUEST *deliver_request_alloc(void)
     request->queue_name = 0;
     request->queue_id = 0;
     request->nexthop = 0;
+    request->encoding = 0;
     request->sender = 0;
     request->errors_to = 0;
     request->return_receipt = 0;
@@ -296,6 +302,8 @@ static void deliver_request_free(DELIVER_REQUEST *request)
        myfree(request->queue_id);
     if (request->nexthop)
        myfree(request->nexthop);
+    if (request->encoding)
+       myfree(request->encoding);
     if (request->sender)
        myfree(request->sender);
     if (request->errors_to)
index 45c2055234c5e7b25590236f4ac81638e1e8b4fb..bf4f135b5581cbb107b3b89cb7786acae1000e19 100644 (file)
@@ -33,6 +33,7 @@ typedef struct DELIVER_REQUEST {
     long    data_offset;               /* offset to message */
     long    data_size;                 /* message size */
     char   *nexthop;                   /* next hop name */
+    char   *encoding;                  /* content encoding */
     char   *sender;                    /* envelope sender */
     char   *errors_to;                 /* error report address */
     char   *return_receipt;            /* confirm receipt address */
index f4d60544e60e548b53391aa2cb104b0214f74309..a31f651c6d01ce1a1e02360124624a5969f2d0bb 100644 (file)
@@ -51,6 +51,7 @@ static HEADER_OPTS header_opts[] = {
     "Apparently-To", HDR_APPARENTLY_TO, HDR_OPT_RECIP,
     "Bcc", HDR_BCC, HDR_OPT_DROP | HDR_OPT_XRECIP,
     "Cc", HDR_CC, HDR_OPT_XRECIP,
+    "Content-Transfer-Encoding", HDR_CONTENT_TRANSFER_ENCODING, 0,
     "Content-Length", HDR_CONTENT_LENGTH, HDR_OPT_DROP,
     "Delivered-To", HDR_DELIVERED_TO, 0,
     "Date", HDR_DATE, 0,
index 1552c5e9c805a2a7be30b014ce3e683689383832..7a1d62dd234f9004468323ac6660a7d418982df9 100644 (file)
@@ -1486,6 +1486,13 @@ extern int var_db_create_buf;
 #define DEF_DB_READ_BUF                        (128 *1024)
 extern int var_db_read_buf;
 
+ /*
+  * Named queue file attributes.
+  */
+#define VAR_QATTR_COUNT_LIMIT          "queue_file_attribute_count_limit"
+#define DEF_QATTR_COUNT_LIMIT          100
+extern int var_qattr_count_limit;
+
 /* LICENSE
 /* .ad
 /* .fi
index adadcda60c98a956fd66558c2cdb1df462a5d48a..bb4e5caef385c10c07a093906d9ddee8e9b97ba6 100644 (file)
@@ -98,6 +98,21 @@ extern char *mail_pathname(const char *, const char *);
 #define MAIL_ATTR_TRANSPORT    "transport"
 #define MAIL_ATTR_NEXTHOP      "nexthop"
 
+ /*
+  * The following attribute names are stored in queue files. Changing this
+  * means lots of work to maintain backwards compatibility with queued mail.
+  */
+#define MAIL_ATTR_ENCODING     "encoding"      /* internal encoding */
+#define MAIL_ATTR_ENC_8BIT     "8bit"  /* 8BITMIME equivalent */
+#define MAIL_ATTR_ENC_7BIT     "7bit"  /* 7BIT equivalent */
+#define MAIL_ATTR_ENC_NONE     ""      /* encoding unknown */
+#define MAIL_ATTR_CLIENT_NAME  "client_name"   /* client hostname */
+#define MAIL_ATTR_CLIENT_ADDR  "client_address"        /* client address */
+#define MAIL_ATTR_HELO_NAME    "helo_name"     /* SMTP helo name */
+#define MAIL_ATTR_ORIGIN       "message_origin"        /* hostname[address] */
+#define MAIL_ATTR_ORG_NONE     "unknown"       /* origin unknown */
+#define MAIL_ATTR_ORG_LOCAL    "local" /* local submission */
+
 /* LICENSE
 /* .ad
 /* .fi
index 051405c8c3f791ec4c1032264557124237972a5d..8370958da9758d66739210261840f2e5fd87fd3a 100644 (file)
@@ -20,7 +20,7 @@
   * Patches change the patchlevel and the release date. Snapshots change the
   * release date only, unless they include the same bugfix as a patch release.
   */
-#define MAIL_RELEASE_DATE      "20020509"
+#define MAIL_RELEASE_DATE      "20020512"
 
 #define VAR_MAIL_VERSION       "mail_version"
 #define DEF_MAIL_VERSION       "1.1.9-" MAIL_RELEASE_DATE
index 425b1a52d78e4be52250c64afd7c262adc60a8d6..02e3faf0e0e09a819c9a5f6411ea7fc1a3c5fb3e 100644 (file)
@@ -152,6 +152,8 @@ static void post_mail_init(VSTREAM *stream, const char *sender,
      * size record.
      */
     rec_fprintf(stream, REC_TYPE_TIME, "%ld", (long) now);
+    rec_fprintf(stream, REC_TYPE_ATTR, "%s=%s",
+               MAIL_ATTR_ORIGIN, MAIL_ATTR_ORG_LOCAL);
     rec_fputs(stream, REC_TYPE_FROM, sender);
     rec_fputs(stream, REC_TYPE_RCPT, recipient);
     rec_fputs(stream, REC_TYPE_MESG, "");
index f1caaa466feebb08553faca832bbfdd7adba96e9..0c3257a5dd62eb2d0034f3d3635482f41518d7fe 100644 (file)
   * The types of records that I expect to see while processing different
   * record groups. The first member in each set is the record type that
   * indicates the end of that record group.
+  * 
+  * XXX A records in the extracted segment are generated only by the cleanup
+  * server, and are not supposed to be present in locally submitted mail, as
+  * this is "postfix internal" information. However, the pickup server has to
+  * allow for the presence of A records in the extracted segment, because it
+  * can be requested to re-process already queued mail with `postsuper -r'.
   */
 #define REC_TYPE_ENVELOPE      "MCTFILSDROWVA"
 #define REC_TYPE_CONTENT       "XLN"
-#define REC_TYPE_EXTRACT       "EDROPre"       /* NOT A */
+#define REC_TYPE_EXTRACT       "EDROPreA"
 #define REC_TYPE_NOEXTRACT     "E"
 
  /*
index 98939cb5ae0928c0b88e6df1200276c8710e6bb3..2422e352fdb22095c8a9bd43493a7887862589fe 100644 (file)
@@ -163,6 +163,9 @@ lmtp_proto.o: ../../include/off_cvt.h
 lmtp_proto.o: ../../include/mark_corrupt.h
 lmtp_proto.o: ../../include/quote_821_local.h
 lmtp_proto.o: ../../include/quote_flags.h
+lmtp_proto.o: ../../include/mail_proto.h
+lmtp_proto.o: ../../include/iostuff.h
+lmtp_proto.o: ../../include/attr.h
 lmtp_proto.o: lmtp.h
 lmtp_proto.o: ../../include/argv.h
 lmtp_proto.o: lmtp_sasl.h
index 17a5e9c598d7510ac154b9b87f6f1b7251871dc2..aa9aaf350dce62e0bcf9a3f68a4c7f66e19d02fe 100644 (file)
@@ -46,6 +46,7 @@
 /* STANDARDS
 /*     RFC 821 (SMTP protocol)
 /*     RFC 1651 (SMTP service extensions)
+/*     RFC 1652 (8bit-MIME transport)
 /*     RFC 1870 (Message Size Declaration)
 /*     RFC 2033 (LMTP protocol)
 /*     RFC 2197 (Pipelining)
index 4a247950f8d904e5c27fc75dee6621357d8d271b..6dffbc729b2c7dd2c4c869c966af04f8647bcc63 100644 (file)
 #include <off_cvt.h>
 #include <mark_corrupt.h>
 #include <quote_821_local.h>
+#include <mail_proto.h>
 
 /* Application-specific. */
 
@@ -294,12 +295,12 @@ static int lmtp_loop(LMTP_STATE *state, int send_state, int recv_state)
      * Macros for readability. XXX Aren't LMTP addresses supposed to be case
      * insensitive?
      */
-#define REWRITE_ADDRESS(addr) do { \
-         if (*(addr)) { \
-             quote_821_local(state->scratch, addr, QUOTE_FLAG_8BITCLEAN); \
-             myfree(addr); \
-             addr = mystrdup(vstring_str(state->scratch)); \
-             lowercase(addr); \
+#define REWRITE_ADDRESS(dst, src) do { \
+         if (*(src)) { \
+             quote_821_local(dst, src, QUOTE_FLAG_8BITCLEAN); \
+             lowercase(vstring_str(dst)); \
+         } else { \
+             vstring_strcpy(dst, src); \
          } \
     } while (0)
 
@@ -357,12 +358,21 @@ static int lmtp_loop(LMTP_STATE *state, int send_state, int recv_state)
             * Build the MAIL FROM command.
             */
        case LMTP_STATE_MAIL:
-           if (*request->sender)
-               REWRITE_ADDRESS(request->sender);
-           vstring_sprintf(next_command, "MAIL FROM:<%s>", request->sender);
-           if (state->features & LMTP_FEATURE_SIZE)
+           REWRITE_ADDRESS(state->scratch, request->sender);
+           vstring_sprintf(next_command, "MAIL FROM:<%s>",
+                           vstring_str(state->scratch));
+           if (state->features & LMTP_FEATURE_SIZE)    /* RFC 1652 */
                vstring_sprintf_append(next_command, " SIZE=%lu",
                                       request->data_size);
+           if (state->features & LMTP_FEATURE_8BITMIME) {
+               if (strcmp(request->encoding, MAIL_ATTR_ENC_8BIT) == 0)
+                   vstring_strcat(next_command, " BODY=8BITMIME");
+               else if (strcmp(request->encoding, MAIL_ATTR_ENC_7BIT) == 0)
+                   vstring_strcat(next_command, " BODY=7BIT");
+               else if (strcmp(request->encoding, MAIL_ATTR_ENC_NONE) != 0)
+                   msg_warn("%s: unknown content encoding: %s",
+                            request->queue_id, request->encoding);
+           }
            next_state = LMTP_STATE_RCPT;
            break;
 
@@ -372,8 +382,9 @@ static int lmtp_loop(LMTP_STATE *state, int send_state, int recv_state)
             */
        case LMTP_STATE_RCPT:
            rcpt = request->rcpt_list.info + send_rcpt;
-           REWRITE_ADDRESS(rcpt->address);
-           vstring_sprintf(next_command, "RCPT TO:<%s>", rcpt->address);
+           REWRITE_ADDRESS(state->scratch, rcpt->address);
+           vstring_sprintf(next_command, "RCPT TO:<%s>",
+                           vstring_str(state->scratch));
            if ((next_rcpt = send_rcpt + 1) == request->rcpt_list.len)
                next_state = LMTP_STATE_DATA;
            break;
index 7396348c878ea9dd62860154ed8b920aea3f3423..cb465cfa8e3619e8bc45d22bca680c7a5e58e312 100644 (file)
@@ -209,6 +209,9 @@ qmgr_message.o: ../../include/maps.h
 qmgr_message.o: ../../include/opened.h
 qmgr_message.o: ../../include/resolve_local.h
 qmgr_message.o: ../../include/verp_sender.h
+qmgr_message.o: ../../include/mail_proto.h
+qmgr_message.o: ../../include/iostuff.h
+qmgr_message.o: ../../include/attr.h
 qmgr_message.o: ../../include/resolve_clnt.h
 qmgr_message.o: qmgr.h
 qmgr_message.o: ../../include/scan_dir.h
index 8749c35605c4c61346c6e6e929da35afec77ad06..9607268f61054a37f0557894922bfd8d30c2a3d7 100644 (file)
@@ -266,6 +266,7 @@ struct QMGR_MESSAGE {
     long    data_offset;               /* data seek offset */
     char   *queue_name;                        /* queue name */
     char   *queue_id;                  /* queue file */
+    char   *encoding;                  /* content encoding */
     char   *sender;                    /* complete address */
     char   *verp_delims;               /* VERP delimiters */
     char   *errors_to;                 /* error report address */
index 722d810739cb2bf96e6aec10f8bd339342ff76ea..b4b7f9c480bbf838ae31e16cb4b69e5719672b1d 100644 (file)
@@ -283,6 +283,7 @@ void    qmgr_active_done(QMGR_MESSAGE *message)
                abounce_flush(BOUNCE_FLAG_KEEP,
                              message->queue_name,
                              message->queue_id,
+                             message->encoding,
                              message->errors_to,
                              qmgr_active_done_2_bounce_flush,
                              (char *) message);
@@ -290,6 +291,7 @@ void    qmgr_active_done(QMGR_MESSAGE *message)
                abounce_flush_verp(BOUNCE_FLAG_KEEP,
                                   message->queue_name,
                                   message->queue_id,
+                                  message->encoding,
                                   message->errors_to,
                                   message->verp_delims,
                                   qmgr_active_done_2_bounce_flush,
@@ -370,6 +372,7 @@ static void qmgr_active_done_2_generic(QMGR_MESSAGE *message)
                adefer_flush(BOUNCE_FLAG_KEEP,
                             message->queue_name,
                             message->queue_id,
+                            message->encoding,
                             message->errors_to,
                             qmgr_active_done_3_defer_flush,
                             (char *) message);
@@ -377,6 +380,7 @@ static void qmgr_active_done_2_generic(QMGR_MESSAGE *message)
                adefer_flush_verp(BOUNCE_FLAG_KEEP,
                                  message->queue_name,
                                  message->queue_id,
+                                 message->encoding,
                                  message->errors_to,
                                  message->verp_delims,
                                  qmgr_active_done_3_defer_flush,
@@ -389,6 +393,7 @@ static void qmgr_active_done_2_generic(QMGR_MESSAGE *message)
            adefer_warn(BOUNCE_FLAG_KEEP,
                        message->queue_name,
                        message->queue_id,
+                       message->encoding,
                        message->errors_to,
                        qmgr_active_done_3_defer_warn,
                        (char *) message);
index 394b267d6a9b758a9feed4499cd9924713ef1165..d8de110c95abe19fb18062b4f435bbe8bb5b5151 100644 (file)
@@ -166,6 +166,7 @@ static int qmgr_deliver_send_request(QMGR_ENTRY *entry, VSTREAM *stream)
               ATTR_TYPE_LONG, MAIL_ATTR_OFFSET, message->data_offset,
               ATTR_TYPE_LONG, MAIL_ATTR_SIZE, message->data_size,
               ATTR_TYPE_STR, MAIL_ATTR_NEXTHOP, nexthop,
+              ATTR_TYPE_STR, MAIL_ATTR_ENCODING, message->encoding,
               ATTR_TYPE_STR, MAIL_ATTR_SENDER, sender,
               ATTR_TYPE_STR, MAIL_ATTR_ERRTO, message->errors_to,
               ATTR_TYPE_STR, MAIL_ATTR_RRCPT, message->return_receipt,
index d5bde3a3dfcfd1e530ea30f0a7bcd90c74125aef..fac420478627eaeb94a4c7cc5685a701f1738381 100644 (file)
 #include <opened.h>
 #include <resolve_local.h>
 #include <verp_sender.h>
+#include <mail_proto.h>
 
 /* Client stubs. */
 
@@ -153,6 +154,7 @@ static QMGR_MESSAGE *qmgr_message_create(const char *queue_name,
     message->data_offset = 0;
     message->queue_id = mystrdup(queue_id);
     message->queue_name = mystrdup(queue_name);
+    message->encoding = 0;
     message->sender = 0;
     message->errors_to = 0;
     message->return_receipt = 0;
@@ -283,6 +285,9 @@ static int qmgr_message_read(QMGR_MESSAGE *message)
     long    save_offset = message->rcpt_offset;        /* save a flag */
     char   *start;
     int     recipient_limit;
+    const char *error_text;
+    char   *name;
+    char   *value;
 
     /*
      * Initialize. No early returns or we have a memory leak.
@@ -404,6 +409,15 @@ static int qmgr_message_read(QMGR_MESSAGE *message)
                        break;
                }
            }
+       } else if (rec_type == REC_TYPE_ATTR) {
+           if ((error_text = split_nameval(start, &name, &value)) != 0) {
+               msg_warn("%s: bad attribute: %s: %.200s",
+                        message->queue_id, error_text, start);
+               break;
+           }
+           if (strcmp(name, MAIL_ATTR_ENCODING) == 0)
+               if (message->encoding == 0)
+                   message->encoding = mystrdup(value);
        } else if (rec_type == REC_TYPE_ERTO) {
            if (message->errors_to == 0) {
                message->errors_to = mystrdup(start);
@@ -447,6 +461,8 @@ static int qmgr_message_read(QMGR_MESSAGE *message)
        message->errors_to = mystrdup("");
     if (message->return_receipt == 0)
        message->return_receipt = mystrdup("");
+    if (message->encoding == 0)
+       message->encoding = mystrdup(MAIL_ATTR_ENC_NONE);
 
     /*
      * Clean up.
@@ -926,6 +942,8 @@ void    qmgr_message_free(QMGR_MESSAGE *message)
        qmgr_job_free(job);
     myfree(message->queue_id);
     myfree(message->queue_name);
+    if (message->encoding)
+       myfree(message->encoding);
     if (message->sender)
        myfree(message->sender);
     if (message->verp_delims)
index a9006d5edd39615391c76a31a2927182fe662661..a30d1880022d01cd0f83e90f869e2a7a7c771fdf 100644 (file)
@@ -62,6 +62,7 @@ pickup.o: ../../include/vbuf.h
 pickup.o: ../../include/vstream.h
 pickup.o: ../../include/set_ugid.h
 pickup.o: ../../include/safe_open.h
+pickup.o: ../../include/stringops.h
 pickup.o: ../../include/mail_queue.h
 pickup.o: ../../include/mail_open_ok.h
 pickup.o: ../../include/mymalloc.h
index 7bf7d58350442b147a660c988786ec8bdb7f1a36..4ec76b434508513afe72e86e417eb818a39857c5 100644 (file)
@@ -92,6 +92,7 @@
 #include <vstream.h>
 #include <set_ugid.h>
 #include <safe_open.h>
+#include <stringops.h>
 
 /* Global library. */
 
@@ -159,13 +160,21 @@ static int copy_segment(VSTREAM *qfile, VSTREAM *cleanup, PICKUP_INFO *info,
 {
     int     type;
     int     check_first = (*expected == REC_TYPE_CONTENT[0]);
+    const char *error_text;
+    char   *attr_name;
+    char   *attr_value;
 
     /*
      * Limit the input record size. All front-end programs should protect the
      * mail system against unreasonable inputs. This also requires that we
      * limit the size of envelope records written by the local posting agent.
+     * 
      * As time stamp we use the scrutinized queue file modification time, and
      * ignore the time stamp embedded in the queue file.
+     * 
+     * Allow attribute records if the queue file is owned by the mail system
+     * (postsuper -r) or if the attribute specifies the MIME body type
+     * (sendmail -B).
      */
     for (;;) {
        if ((type = rec_get(qfile, buf, var_line_limit)) < 0
@@ -181,6 +190,28 @@ static int copy_segment(VSTREAM *qfile, VSTREAM *cleanup, PICKUP_INFO *info,
                info->rcpt = mystrdup(vstring_str(buf));
        if (type == REC_TYPE_TIME)
            continue;
+       if (type == REC_TYPE_ATTR) {
+           if ((error_text = split_nameval(vstring_str(buf), &attr_name,
+                                           &attr_value)) != 0) {
+               msg_warn("uid=%ld: malformed attribute record: %s: %.200s",
+                     (long) info->st.st_uid, error_text, vstring_str(buf));
+               continue;
+           }
+#define STREQ(x,y) (strcmp(x,y) == 0)
+
+           if (info->st.st_uid == var_owner_uid
+               || (STREQ(attr_name, MAIL_ATTR_ENCODING)
+                   && (STREQ(attr_value, MAIL_ATTR_ENC_7BIT)
+                       || STREQ(attr_value, MAIL_ATTR_ENC_8BIT)
+                       || STREQ(attr_value, MAIL_ATTR_ENC_NONE)))) {
+               rec_fprintf(cleanup, REC_TYPE_ATTR, "%s=%s",
+                           attr_name, attr_value);
+               continue;
+           }
+           msg_warn("uid=%ld: ignoring attribute record: %.200s=%.200s",
+                    (long) info->st.st_uid, attr_name, attr_value);
+           continue;
+       }
        if (type == REC_TYPE_FILT && *expected == REC_TYPE_ENVELOPE[0])
            continue;
        else {
@@ -239,6 +270,12 @@ static int pickup_copy(VSTREAM *qfile, VSTREAM *cleanup,
     if (*var_filter_xport)
        rec_fprintf(cleanup, REC_TYPE_FILT, "%s", var_filter_xport);
 
+    /*
+     * Origin is local.
+     */
+    rec_fprintf(cleanup, REC_TYPE_ATTR, "%s=%s",
+               MAIL_ATTR_ORIGIN, MAIL_ATTR_ORG_LOCAL);
+
     /*
      * Copy the message envelope segment. Allow only those records that we
      * expect to see in the envelope section. The envelope segment must
@@ -322,7 +359,6 @@ static int pickup_file(PICKUP_INFO *info)
     int     status;
     VSTREAM *qfile;
     VSTREAM *cleanup;
-    int     fd;
 
     /*
      * Open the submitted file. If we cannot open it, and we're not having a
@@ -331,8 +367,8 @@ static int pickup_file(PICKUP_INFO *info)
      * Perhaps we should save "bad" files elsewhere for further inspection.
      * XXX How can we delete a file when open() fails with ENOENT?
      */
-    qfile = safe_open(info->path, O_RDONLY | O_NONBLOCK, 0, 
-               (struct stat *) 0, -1, -1, buf);
+    qfile = safe_open(info->path, O_RDONLY | O_NONBLOCK, 0,
+                     (struct stat *) 0, -1, -1, buf);
     if (qfile == 0) {
        if (errno != ENOENT)
            msg_warn("open input file %s: %s", info->path, vstring_str(buf));
index 19f24d7e67e02966b2ff2336e9e5671d412f6013..92ef4a93fee8d7ecffd9a1d6208c24a897e9479d 100644 (file)
@@ -193,6 +193,9 @@ qmgr_message.o: ../../include/maps.h
 qmgr_message.o: ../../include/opened.h
 qmgr_message.o: ../../include/resolve_local.h
 qmgr_message.o: ../../include/verp_sender.h
+qmgr_message.o: ../../include/mail_proto.h
+qmgr_message.o: ../../include/iostuff.h
+qmgr_message.o: ../../include/attr.h
 qmgr_message.o: ../../include/resolve_clnt.h
 qmgr_message.o: qmgr.h
 qmgr_message.o: ../../include/scan_dir.h
index 9839c07c20980e240f21ad8096c7c6df193ec5e7..4f15f8c9046182a26782d55ab26743e3d0fbe9c0 100644 (file)
@@ -226,6 +226,7 @@ struct QMGR_MESSAGE {
     long    data_offset;               /* data seek offset */
     char   *queue_name;                        /* queue name */
     char   *queue_id;                  /* queue file */
+    char   *encoding;                  /* content encoding */
     char   *sender;                    /* complete address */
     char   *verp_delims;               /* VERP delimiters */
     char   *errors_to;                 /* error report address */
index 722d810739cb2bf96e6aec10f8bd339342ff76ea..b4b7f9c480bbf838ae31e16cb4b69e5719672b1d 100644 (file)
@@ -283,6 +283,7 @@ void    qmgr_active_done(QMGR_MESSAGE *message)
                abounce_flush(BOUNCE_FLAG_KEEP,
                              message->queue_name,
                              message->queue_id,
+                             message->encoding,
                              message->errors_to,
                              qmgr_active_done_2_bounce_flush,
                              (char *) message);
@@ -290,6 +291,7 @@ void    qmgr_active_done(QMGR_MESSAGE *message)
                abounce_flush_verp(BOUNCE_FLAG_KEEP,
                                   message->queue_name,
                                   message->queue_id,
+                                  message->encoding,
                                   message->errors_to,
                                   message->verp_delims,
                                   qmgr_active_done_2_bounce_flush,
@@ -370,6 +372,7 @@ static void qmgr_active_done_2_generic(QMGR_MESSAGE *message)
                adefer_flush(BOUNCE_FLAG_KEEP,
                             message->queue_name,
                             message->queue_id,
+                            message->encoding,
                             message->errors_to,
                             qmgr_active_done_3_defer_flush,
                             (char *) message);
@@ -377,6 +380,7 @@ static void qmgr_active_done_2_generic(QMGR_MESSAGE *message)
                adefer_flush_verp(BOUNCE_FLAG_KEEP,
                                  message->queue_name,
                                  message->queue_id,
+                                 message->encoding,
                                  message->errors_to,
                                  message->verp_delims,
                                  qmgr_active_done_3_defer_flush,
@@ -389,6 +393,7 @@ static void qmgr_active_done_2_generic(QMGR_MESSAGE *message)
            adefer_warn(BOUNCE_FLAG_KEEP,
                        message->queue_name,
                        message->queue_id,
+                       message->encoding,
                        message->errors_to,
                        qmgr_active_done_3_defer_warn,
                        (char *) message);
index 45c0a6cdde07d58d458abdc84c56ecc477077051..64b170c26a3a939e3b42d39e00e402dd775c048d 100644 (file)
@@ -161,6 +161,7 @@ static int qmgr_deliver_send_request(QMGR_ENTRY *entry, VSTREAM *stream)
               ATTR_TYPE_LONG, MAIL_ATTR_OFFSET, message->data_offset,
               ATTR_TYPE_LONG, MAIL_ATTR_SIZE, message->data_size,
               ATTR_TYPE_STR, MAIL_ATTR_NEXTHOP, nexthop,
+              ATTR_TYPE_STR, MAIL_ATTR_ENCODING, message->encoding,
               ATTR_TYPE_STR, MAIL_ATTR_SENDER, sender,
               ATTR_TYPE_STR, MAIL_ATTR_ERRTO, message->errors_to,
               ATTR_TYPE_STR, MAIL_ATTR_RRCPT, message->return_receipt,
index 3aa4de8497dc820bd75de3871e0a144ca343cba1..9433f87732ed818f337de7fd72998af884cd68c6 100644 (file)
 #include <opened.h>
 #include <resolve_local.h>
 #include <verp_sender.h>
+#include <mail_proto.h>
 
 /* Client stubs. */
 
@@ -143,6 +144,7 @@ static QMGR_MESSAGE *qmgr_message_create(const char *queue_name,
     message->data_offset = 0;
     message->queue_id = mystrdup(queue_id);
     message->queue_name = mystrdup(queue_name);
+    message->encoding = 0;
     message->sender = 0;
     message->errors_to = 0;
     message->return_receipt = 0;
@@ -203,6 +205,9 @@ static int qmgr_message_read(QMGR_MESSAGE *message)
     char   *start;
     struct stat st;
     int     nrcpt = 0;
+    const char *error_text;
+    char   *name;
+    char   *value;
 
     /*
      * Initialize. No early returns or we have a memory leak.
@@ -294,6 +299,15 @@ static int qmgr_message_read(QMGR_MESSAGE *message)
            }
            if (vstream_fseek(message->fp, extra_offset, SEEK_SET) < 0)
                msg_fatal("seek file %s: %m", VSTREAM_PATH(message->fp));
+       } else if (rec_type == REC_TYPE_ATTR) {
+           if ((error_text = split_nameval(start, &name, &value)) != 0) {
+               msg_warn("%s: bad attribute: %s: %.200s",
+                        message->queue_id, error_text, start);
+               break;
+           }
+           if (strcmp(name, MAIL_ATTR_ENCODING) == 0)
+               if (message->encoding == 0)
+                   message->encoding = mystrdup(value);
        } else if (rec_type == REC_TYPE_ERTO) {
            if (message->errors_to == 0)
                message->errors_to = mystrdup(start);
@@ -336,6 +350,8 @@ static int qmgr_message_read(QMGR_MESSAGE *message)
        message->errors_to = mystrdup("");
     if (message->return_receipt == 0)
        message->return_receipt = mystrdup("");
+    if (message->encoding == 0)
+       message->encoding = mystrdup(MAIL_ATTR_ENC_NONE);
 
     /*
      * Clean up.
@@ -761,6 +777,8 @@ void    qmgr_message_free(QMGR_MESSAGE *message)
        msg_panic("qmgr_message_free: queue file is open");
     myfree(message->queue_id);
     myfree(message->queue_name);
+    if (message->encoding)
+       myfree(message->encoding);
     if (message->sender)
        myfree(message->sender);
     if (message->verp_delims)
index 9ccd01eeb634aca198b033a97fe4b8857c3c78e4..47106e99069d2597a1572beaf36bbb98945c4fd7 100644 (file)
@@ -245,6 +245,18 @@ static void qmqpd_copy_sender(QMQPD_STATE *state)
     state->sender = mystrndup(STR(state->buf), LEN(state->buf));
 }
 
+/* qmqpd_write_attributes - save session attributes */
+
+static void qmqpd_write_attributes(QMQPD_STATE *state)
+{
+    rec_fprintf(state->cleanup, REC_TYPE_ATTR, "%s=%s",
+               MAIL_ATTR_CLIENT_NAME, state->name);
+    rec_fprintf(state->cleanup, REC_TYPE_ATTR, "%s=%s",
+               MAIL_ATTR_CLIENT_ADDR, state->addr);
+    rec_fprintf(state->cleanup, REC_TYPE_ATTR, "%s=%s",
+               MAIL_ATTR_ORIGIN, state->namaddr);
+}
+
 /* qmqpd_copy_recipients - copy message recipients */
 
 static void qmqpd_copy_recipients(QMQPD_STATE *state)
@@ -503,6 +515,11 @@ static void qmqpd_receive(QMQPD_STATE *state)
      */
     qmqpd_copy_sender(state);
 
+    /*
+     * Record some session attributes.
+     */
+    qmqpd_write_attributes(state);
+
     /*
      * Read and write the envelope recipients, including the optional big
      * brother recipient.
index ea054f656aab213b345cc1cb93b9c32f94a1a5fa..138f38be16a9e989f7c46500a68181e8522bbecc 100644 (file)
@@ -49,9 +49,8 @@
 /*     controlled by parameters in the \fBmain.cf\fR configuration file.
 /*
 /*     The following options are recognized:
-/* .IP "\fB-B \fIbody_type\fR (ignored)"
-/*     The message body MIME type. Currently, Postfix implements
-/*     \fBjust-send-eight\fR.
+/* .IP "\fB-B \fIbody_type\fR"
+/*     The message body MIME type: \fB7BIT\fR or \fB8BITMIME\fR.
 /* .IP "\fB-C \fIconfig_file\fR (ignored :-)"
 /*     The path name of the \fBsendmail.cf\fR file. Postfix configuration
 /*     files are kept in \fB/etc/postfix\fR.
@@ -347,8 +346,8 @@ char   *verp_delims;
 
 /* enqueue - post one message */
 
-static void enqueue(const int flags, const char *sender, const char *full_name,
-                           char **recipients)
+static void enqueue(const int flags, const char *encoding, const char *sender,
+                           const char *full_name, char **recipients)
 {
     VSTRING *buf;
     VSTREAM *dst;
@@ -428,6 +427,8 @@ static void enqueue(const int flags, const char *sender, const char *full_name,
     rec_fputs(dst, REC_TYPE_FROM, saved_sender);
     if (verp_delims && *saved_sender == 0)
        msg_fatal("-V option requires non-null sender address");
+    if (encoding)
+       rec_fprintf(dst, REC_TYPE_ATTR, "%s=%s", MAIL_ATTR_ENCODING, encoding);
     if (verp_delims)
        rec_fputs(dst, REC_TYPE_VERP, verp_delims);
     if (recipients) {
@@ -538,6 +539,7 @@ int     main(int argc, char **argv)
     int     n;
     int     flags = SM_FLAG_DEFAULT;
     char   *site_to_flush = 0;
+    char   *encoding = 0;
 
     /*
      * Be consistent with file permissions.
@@ -664,6 +666,14 @@ int     main(int argc, char **argv)
            break;
        case 'n':
            msg_fatal_status(EX_USAGE, "-%c option not supported", c);
+       case 'B':
+           if (strcmp(optarg, "8BITMIME") == 0)/* RFC 1652 */
+               encoding = MAIL_ATTR_ENC_8BIT;
+           else if (strcmp(optarg, "7BIT") == 0)       /* RFC 1652 */
+               encoding = MAIL_ATTR_ENC_7BIT;
+           else
+               msg_fatal_status(EX_USAGE, "-B option needs 8BITMIME or 7BIT");
+           break;
        case 'F':                               /* full name */
            full_name = optarg;
            break;
@@ -779,7 +789,7 @@ int     main(int argc, char **argv)
        /* NOTREACHED */
     case SM_MODE_ENQUEUE:
        if (site_to_flush == 0) {
-           enqueue(flags, sender, full_name, argv + OPTIND);
+           enqueue(flags, encoding, sender, full_name, argv + OPTIND);
            exit(0);
        }
        if (argv[OPTIND])
index 0dc84f510e10d0e31c2aea99f40a6c8084d943a5..d1cbbcfd82ddcfa310d978259d36fbf3d4bcc626 100644 (file)
@@ -167,6 +167,8 @@ smtp_proto.o: ../../include/off_cvt.h
 smtp_proto.o: ../../include/mark_corrupt.h
 smtp_proto.o: ../../include/quote_821_local.h
 smtp_proto.o: ../../include/quote_flags.h
+smtp_proto.o: ../../include/mail_proto.h
+smtp_proto.o: ../../include/attr.h
 smtp_proto.o: smtp.h
 smtp_proto.o: ../../include/argv.h
 smtp_proto.o: smtp_sasl.h
index c4eddd07fa5cb7a272df4fd89f4919355ec29613..a25d7eb4da7b77d415b9a1a03eb79f4efd50b0c4 100644 (file)
@@ -38,6 +38,7 @@
 /* STANDARDS
 /*     RFC 821 (SMTP protocol)
 /*     RFC 1651 (SMTP service extensions)
+/*     RFC 1652 (8bit-MIME transport)
 /*     RFC 1870 (Message Size Declaration)
 /*     RFC 2197 (Pipelining)
 /*     RFC 2554 (AUTH command)
index 8274466ff7fb293f5951e71a1bd883d9f6601060..fe9d2a177ec35a95b687eb87ef4a4ac01bcd05dd 100644 (file)
 #include <off_cvt.h>
 #include <mark_corrupt.h>
 #include <quote_821_local.h>
+#include <mail_proto.h>
 
 /* Application-specific. */
 
@@ -303,20 +304,20 @@ int     smtp_xfer(SMTP_STATE *state)
     /*
      * Macros for readability.
      */
-#define REWRITE_ADDRESS(addr) do { \
-       if (*(addr)) { \
-           quote_821_local(state->scratch, addr, QUOTE_FLAG_8BITCLEAN); \
-           smtp_unalias_addr(state->scratch2, vstring_str(state->scratch)); \
-           myfree(addr); \
-           addr = mystrdup(vstring_str(state->scratch2)); \
+#define REWRITE_ADDRESS(dst, mid, src) do { \
+       if (*(src)) { \
+           quote_821_local(mid, src, QUOTE_FLAG_8BITCLEAN); \
+           smtp_unalias_addr(dst, vstring_str(mid)); \
+       } else { \
+           vstring_strcpy(dst, src); \
        } \
     } while (0)
 
-#define QUOTE_ADDRESS(addr) do { \
-       if (*(addr)) { \
-           quote_821_local(state->scratch, addr, QUOTE_FLAG_8BITCLEAN); \
-           myfree(addr); \
-           addr = mystrdup(vstring_str(state->scratch)); \
+#define QUOTE_ADDRESS(dst, src) do { \
+       if (*(src)) { \
+           quote_821_local(dst, src, QUOTE_FLAG_8BITCLEAN); \
+       } else { \
+           vstring_strcpy(dst, src); \
        } \
     } while (0)
 
@@ -408,14 +409,25 @@ int     smtp_xfer(SMTP_STATE *state)
             */
        case SMTP_STATE_MAIL:
            if (var_disable_dns == 0) {
-               REWRITE_ADDRESS(request->sender);
+               REWRITE_ADDRESS(state->scratch, state->scratch2,
+                               request->sender);
            } else {
-               QUOTE_ADDRESS(request->sender);
+               QUOTE_ADDRESS(state->scratch, request->sender);
            }
-           vstring_sprintf(next_command, "MAIL FROM:<%s>", request->sender);
-           if (state->features & SMTP_FEATURE_SIZE)
+           vstring_sprintf(next_command, "MAIL FROM:<%s>",
+                           vstring_str(state->scratch));
+           if (state->features & SMTP_FEATURE_SIZE)    /* RFC 1652 */
                vstring_sprintf_append(next_command, " SIZE=%lu",
                                       request->data_size);
+           if (state->features & SMTP_FEATURE_8BITMIME) {
+               if (strcmp(request->encoding, MAIL_ATTR_ENC_8BIT) == 0)
+                   vstring_strcat(next_command, " BODY=8BITMIME");
+               else if (strcmp(request->encoding, MAIL_ATTR_ENC_7BIT) == 0)
+                   vstring_strcat(next_command, " BODY=7BIT");
+               else if (strcmp(request->encoding, MAIL_ATTR_ENC_NONE) != 0)
+                   msg_warn("%s: unknown content encoding: %s",
+                            request->queue_id, request->encoding);
+           }
            next_state = SMTP_STATE_RCPT;
            break;
 
@@ -426,11 +438,13 @@ int     smtp_xfer(SMTP_STATE *state)
        case SMTP_STATE_RCPT:
            rcpt = request->rcpt_list.info + send_rcpt;
            if (var_disable_dns == 0) {
-               REWRITE_ADDRESS(rcpt->address);
+               REWRITE_ADDRESS(state->scratch, state->scratch2,
+                               rcpt->address);
            } else {
-               QUOTE_ADDRESS(rcpt->address);
+               QUOTE_ADDRESS(state->scratch, rcpt->address);
            }
-           vstring_sprintf(next_command, "RCPT TO:<%s>", rcpt->address);
+           vstring_sprintf(next_command, "RCPT TO:<%s>",
+                           vstring_str(state->scratch));
            if ((next_rcpt = send_rcpt + 1) == request->rcpt_list.len)
                next_state = SMTP_STATE_DATA;
            break;
index 8668041980ee590f11f8d263ae86f34e7f200e63..0da6928fd1d7f05e15f1f26cbe50daad995237f7 100644 (file)
@@ -130,6 +130,8 @@ smtpd.o: ../../include/verp_sender.h
 smtpd.o: ../../include/string_list.h
 smtpd.o: ../../include/match_list.h
 smtpd.o: ../../include/match_ops.h
+smtpd.o: ../../include/quote_822_local.h
+smtpd.o: ../../include/quote_flags.h
 smtpd.o: ../../include/mail_server.h
 smtpd.o: smtpd_token.h
 smtpd.o: smtpd.h
index fdd063caffe590ac52d8d8ae53a64f8371dbab98..ddc016bc9cfad6740950a14361c4faf5c1256ae5 100644 (file)
@@ -655,6 +655,7 @@ static int mail_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *argv)
     int     narg;
     char   *arg;
     char   *verp_delims = 0;
+    char   *encoding = 0;
 
     state->msg_size = 0;
 
@@ -695,10 +696,11 @@ static int mail_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *argv)
     }
     for (narg = 3; narg < argc; narg++) {
        arg = argv[narg].strval;
-       if (strcasecmp(arg, "BODY=8BITMIME") == 0
-           || strcasecmp(arg, "BODY=7BIT") == 0) {
-            /* void */ ;
-       } else if (strncasecmp(arg, "SIZE=", 5) == 0) {
+       if (strcasecmp(arg, "BODY=8BITMIME") == 0) {    /* RFC 1652 */
+           encoding = MAIL_ATTR_ENC_8BIT;
+       } else if (strcasecmp(arg, "BODY=7BIT") == 0) { /* RFC 1652 */
+           encoding = MAIL_ATTR_ENC_7BIT;
+       } else if (strncasecmp(arg, "SIZE=", 5) == 0) { /* RFC 1870 */
            /* Reject non-numeric size. */
            if (!alldig(arg + 5)) {
                state->error_mask |= MAIL_ERROR_PROTOCOL;
@@ -771,6 +773,18 @@ static int mail_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *argv)
     if (*var_filter_xport)
        rec_fprintf(state->cleanup, REC_TYPE_FILT, "%s", var_filter_xport);
     rec_fputs(state->cleanup, REC_TYPE_FROM, argv[2].strval);
+    if (encoding != 0)
+       rec_fprintf(state->cleanup, REC_TYPE_ATTR, "%s=%s",
+                   MAIL_ATTR_ENCODING, encoding);
+    rec_fprintf(state->cleanup, REC_TYPE_ATTR, "%s=%s",
+               MAIL_ATTR_CLIENT_NAME, state->name);
+    rec_fprintf(state->cleanup, REC_TYPE_ATTR, "%s=%s",
+               MAIL_ATTR_CLIENT_ADDR, state->addr);
+    rec_fprintf(state->cleanup, REC_TYPE_ATTR, "%s=%s",
+               MAIL_ATTR_ORIGIN, state->namaddr);
+    if (state->helo_name != 0)
+       rec_fprintf(state->cleanup, REC_TYPE_ATTR, "%s=%s",
+                   MAIL_ATTR_HELO_NAME, state->helo_name);
     if (verp_delims)
        rec_fputs(state->cleanup, REC_TYPE_VERP, verp_delims);
     state->sender = mystrdup(argv[2].strval);
index 4580b16242451ff507d98d563deadbcafd418fd5..32868885c493e9dfe8f78ddcb3df493830fb6951 100644 (file)
@@ -26,7 +26,7 @@ SRCS  = alldig.c argv.c argv_split.c attr_print0.c attr_print64.c \
        unix_connect.c unix_listen.c unix_trigger.c unsafe.c username.c \
        valid_hostname.c vbuf.c vbuf_print.c vstream.c vstream_popen.c \
        vstring.c vstring_vstream.c watchdog.c writable.c write_buf.c \
-       write_wait.c strcasecmp.c
+       write_wait.c strcasecmp.c nvtable.c
 OBJS   = alldig.o argv.o argv_split.o attr_print0.o attr_print64.o \
        attr_scan0.o attr_scan64.o base64_code.o basename.o binhash.o \
        chroot_uid.o clean_env.o close_on_exec.o concatenate.o ctable.o \
@@ -54,7 +54,7 @@ OBJS  = alldig.o argv.o argv_split.o attr_print0.o attr_print64.o \
        unix_connect.o unix_listen.o unix_trigger.o unsafe.o username.o \
        valid_hostname.o vbuf.o vbuf_print.o vstream.o vstream_popen.o \
        vstring.o vstring_vstream.o watchdog.o writable.o write_buf.o \
-       write_wait.o $(STRCASE)
+       write_wait.o nvtable.o $(STRCASE)
 HDRS   = argv.h attr.h base64_code.h binhash.h chroot_uid.h clean_env.h \
        connect.h ctable.h dict.h dict_db.h dict_dbm.h dict_env.h \
        dict_ht.h dict_ldap.h dict_mysql.h dict_ni.h dict_nis.h \
@@ -71,7 +71,8 @@ HDRS  = argv.h attr.h base64_code.h binhash.h chroot_uid.h clean_env.h \
        scan_dir.h set_eugid.h set_ugid.h sigdelay.h spawn_command.h \
        split_at.h stat_as.h stringops.h sys_defs.h timed_connect.h \
        timed_wait.h trigger.h username.h valid_hostname.h vbuf.h \
-       vbuf_print.h vstream.h vstring.h vstring_vstream.h watchdog.h
+       vbuf_print.h vstream.h vstring.h vstring_vstream.h watchdog.h \
+       nvtable.h
 TESTSRC        = fifo_open.c fifo_rdwr_bug.c fifo_rdonly_bug.c select_bug.c \
        stream_test.c dup2_pass_on_exec.c
 WARN   = -W -Wformat -Wimplicit -Wmissing-prototypes \
@@ -922,6 +923,11 @@ non_blocking.o: non_blocking.c
 non_blocking.o: sys_defs.h
 non_blocking.o: msg.h
 non_blocking.o: iostuff.h
+nvtable.o: nvtable.c
+nvtable.o: sys_defs.h
+nvtable.o: mymalloc.h
+nvtable.o: htable.h
+nvtable.o: nvtable.h
 open_as.o: open_as.c
 open_as.o: sys_defs.h
 open_as.o: msg.h
index 92fedc57e1c69ad85660c94f2d860ee6d6b7e07d..e19587781f4a06f78b9beea19387774bfcef93bc 100644 (file)
@@ -407,7 +407,7 @@ static int dict_eval_action(int type, VSTRING *buf, char *ptr)
     char   *myname = "dict_eval_action";
     const char *pp;
 
-    if (msg_verbose)
+    if (msg_verbose > 1)
        msg_info("%s: type %s buf %s context %s \"%s\" %s",
                 myname, type == MAC_PARSE_VARNAME ? "variable" : "literal",
                 STR(buf), ctxt->dict_name, STR(ctxt->buf),
diff --git a/postfix/src/util/nvtable.c b/postfix/src/util/nvtable.c
new file mode 100644 (file)
index 0000000..693f693
--- /dev/null
@@ -0,0 +1,122 @@
+/*++
+/* NAME
+/*     nvtable 3
+/* SUMMARY
+/*     attribute list manager
+/* SYNOPSIS
+/*     #include <nvtable.h>
+/*
+/*     typedef struct {
+/* .in +4
+/*             char    *key;
+/*             char    *value;
+/*             /* private fields... */
+/* .in -4
+/*     } NVTABLE_INFO;
+/*
+/*     NVTABLE *nvtable_create(size)
+/*     int     size;
+/*
+/*     NVTABLE_INFO *nvtable_update(table, key, value)
+/*     NVTABLE *table;
+/*     const char *key;
+/*     const char *value;
+/*
+/*     char    *nvtable_find(table, key)
+/*     NVTABLE *table;
+/*     const char *key;
+/*
+/*     NVTABLE_INFO *nvtable_locate(table, key)
+/*     NVTABLE *table;
+/*     const char *key;
+/*
+/*     void    nvtable_delete(table, key)
+/*     NVTABLE *table;
+/*     const char *key;
+/*
+/*     void    nvtable_free(table)
+/*     NVTABLE *table;
+/*
+/*     void    nvtable_walk(table, action, ptr)
+/*     NVTABLE *table;
+/*     void    (*action)(NVTABLE_INFO *, char *ptr);
+/*     char    *ptr;
+/*
+/*     NVTABLE_INFO **nvtable_list(table)
+/*     NVTABLE *table;
+/* DESCRIPTION
+/*     This module maintains one or more attribute lists. It provides a
+/*     more convenient interface than hash tables, although it uses the
+/*     same underlying implementation. Each attribute list entry consists
+/*     of a unique string-valued lookup key and a string value.
+/*
+/*     nvtable_create() creates a table of the specified size and returns a
+/*     pointer to the result.
+/*
+/*     nvtable_update() stores or updates a (key, value) pair in the specified
+/*     table and returns a pointer to the resulting entry. The key and the
+/*     value are copied.
+/*
+/*     nvtable_find() returns the value that was stored under the given key,
+/*     or a null pointer if it was not found. In order to distinguish
+/*     a null value from a non-existent value, use nvtable_locate().
+/*
+/*     nvtable_locate() returns a pointer to the entry that was stored
+/*     for the given key, or a null pointer if it was not found.
+/*
+/*     nvtable_delete() removes one entry that was stored under the given key.
+/*
+/*     nvtable_free() destroys a hash table, including contents.
+/*
+/*     nvtable_walk() invokes the action function for each table entry, with
+/*     a pointer to the entry as its argument. The ptr argument is passed
+/*     on to the action function.
+/*
+/*     nvtable_list() returns a null-terminated list of pointers to
+/*     all elements in the named table. The list should be passed to
+/*     myfree().
+/* RESTRICTIONS
+/*     A callback function should not modify the attribute list that is
+/*     specified to its caller.
+/* DIAGNOSTICS
+/*     The following conditions are reported and cause the program to
+/*     terminate immediately: memory allocation failure; an attempt
+/*     to delete a non-existent entry.
+/* SEE ALSO
+/*     mymalloc(3) memory management wrapper
+/*     htable(3) hash table manager
+/* 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
+/*--*/
+
+/* C library */
+
+#include <sys_defs.h>
+
+/* Utility library. */
+
+#include <mymalloc.h>
+#include <htable.h>
+#include <nvtable.h>
+
+/* nvtable_update - update or enter (key, value) pair */
+
+NVTABLE_INFO *nvtable_update(NVTABLE * table, const char *key, const char *value)
+{
+    NVTABLE_INFO *ht;
+
+    if ((ht = htable_locate(table, key)) != 0) {
+       myfree(ht->value);
+    } else {
+       ht = htable_enter(table, key, (char *) 0);
+    }
+    ht->value = mystrdup(value);
+    return (ht);
+}
diff --git a/postfix/src/util/nvtable.h b/postfix/src/util/nvtable.h
new file mode 100644 (file)
index 0000000..b2bccaf
--- /dev/null
@@ -0,0 +1,44 @@
+#ifndef _NVTABLE_H_INCLUDED_
+#define _NVTABLE_H_INCLUDED_
+
+/*++
+/* NAME
+/*     nvtable 3h
+/* SUMMARY
+/*     attribute list manager
+/* SYNOPSIS
+/*     #include <nvtable.h>
+/* DESCRIPTION
+/* .nf
+
+ /*
+  * Utility library.
+  */
+#include <htable.h>
+#include <mymalloc.h>
+
+typedef struct HTABLE NVTABLE;
+typedef struct HTABLE_INFO NVTABLE_INFO;
+
+#define nvtable_create(size)           htable_create(size)
+#define nvtable_locate(table, key)     htable_locate((table), (key))
+#define nvtable_walk(table, action, ptr) htable_walk((table), (action), (ptr))
+#define nvtable_list(table)            htable_list(table)
+#define nvtable_find(table, key)       htable_find((table), (key))
+#define nvtable_delete(table, key)     htable_delete((table), (key), myfree)
+#define nvtable_free(table)            htable_free((table), myfree)
+
+extern NVTABLE_INFO *nvtable_update(NVTABLE *, const char *, const char *);
+
+/* 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
+/*--*/
+
+#endif