]> git.ipfire.org Git - thirdparty/postfix.git/commitdiff
postfix-2.3-20050402
authorWietse Venema <wietse@porcupine.org>
Sat, 2 Apr 2005 05:00:00 +0000 (00:00 -0500)
committerViktor Dukhovni <viktor@dukhovni.org>
Tue, 5 Feb 2013 06:31:00 +0000 (06:31 +0000)
12 files changed:
postfix/.indent.pro
postfix/HISTORY
postfix/src/cleanup/cleanup_message.c
postfix/src/global/mail_version.h
postfix/src/global/mime_state.c
postfix/src/global/mime_state.h
postfix/src/lmtp/lmtp_chat.c
postfix/src/smtp/smtp_chat.c
postfix/src/smtp/smtp_proto.c
postfix/src/util/Makefile.in
postfix/src/util/gccw.c [new file with mode: 0644]
postfix/src/util/gccw.ref [new file with mode: 0644]

index 08e5e99d6bdb579735d4dbc64b60b43b4e3da7d1..984448ac3adf0b9f474fad2b7fb03626333af561 100644 (file)
 -TMIME_INFO
 -TMIME_STACK
 -TMIME_STATE
+-TMIME_STATE_DETAIL
 -TMIME_TOKEN
 -TMKMAP
 -TMKMAP_DB
index 16e094cb3f92e6b86ad93e51606b6b22d650f450..404cecfcce51f8479f9500bde0173988d6a38b06 100644 (file)
@@ -10588,6 +10588,24 @@ Apologies for any names omitted.
        dsn_vstring_update() module. File: global/dsn_util.h,
        global/pipe_command.c.
 
+20050401
+
+       Cleanup: ignore incorrect enhanced status codes (such as
+       5xx reply followed by a 4.x.x status), and don't look for
+       enhanced status codes unless the server replies with a
+       [245]XX reply.  Files: smtp/smtp_chat.c, lmtp/lmtp_chat.c.
+
+20050402
+
+       Feature: enhanced status code support for errors found by
+       the MIME processor. Files: global/mime_state.c,
+       cleanup/cleanup_message.c, smtp/smtp_proto.c.
+
+       Cleanup: updated error messages about MIME processing
+       errors in the SMTP client. These errors are no longer
+       specific to 8bit->7bit conversion; they can also happen
+       with generic address mapping. File: smtp/smtp_proto.c.
+
 Open problems:
 
        Med: disable header address rewriting after XCLIENT?
index 51be87e99418e93236f8b7cbcfb32fe863605c96..f8524f74962053de8ecf2be486f94eb0989a2dbd 100644 (file)
@@ -697,6 +697,7 @@ static void cleanup_message_headerbody(CLEANUP_STATE *state, int type,
                                               const char *buf, int len)
 {
     char   *myname = "cleanup_message_headerbody";
+    MIME_STATE_DETAIL *detail;
 
     /*
      * Copy text record to the output.
@@ -715,7 +716,8 @@ static void cleanup_message_headerbody(CLEANUP_STATE *state, int type,
        state->mime_errs &= ~MIME_ERR_TRUNC_HEADER;
        if (state->mime_errs && state->reason == 0) {
            state->errs |= CLEANUP_STAT_CONT;
-           state->reason = mystrdup(mime_state_error(state->mime_errs));
+           detail = mime_state_detail(state->mime_errs);
+           state->reason = dsn_prepend(detail->dsn, detail->text);
        }
        state->mime_state = mime_state_free(state->mime_state);
        if ((state->xtra_offset = vstream_ftell(state->dst)) < 0)
index 1fb39eadceb22b927621039f32e9d5a63ba8b72e..66f9a453ba7d937a9ede8e5c297b7f4f0f31e5dd 100644 (file)
@@ -20,7 +20,7 @@
   * Patches change the patchlevel and the release date. Snapshots change the
   * release date only.
   */
-#define MAIL_RELEASE_DATE      "20050401"
+#define MAIL_RELEASE_DATE      "20050402"
 #define MAIL_VERSION_NUMBER    "2.3"
 
 #define VAR_MAIL_VERSION       "mail_version"
index f5bd56056d12a182044d26fff04db030c0b77d36..409e1231d66d3e289fe338bfa3ad3e90d6899558 100644 (file)
 /*
 /*     const char *mime_state_error(error_code)
 /*     int     error_code;
+/*
+/*     typedef struct {
+/* .in +4
+/*             const int code;         /* internal error code */
+/*             const char *dsn;        /* RFC 3463 */
+/*             const char *text;       /* descriptive text */
+/* .in -4
+/*     } MIME_STATE_DETAIL;
+/*
+/*     MIME_STATE_DETAIL *mime_state_detail(error_code)
+/*     int     error_code;
 /* DESCRIPTION
 /*     This module implements a one-pass MIME processor with optional
 /*     8-bit to quoted-printable conversion.
 /*     specified error code. When multiple errors are specified it
 /*     reports what it deems the most serious one.
 /*
+/*     mime_state_detail() returns a table entry with error
+/*     information for the specified error code. When multiple
+/*     errors are specified it reports what it deems the most
+/*     serious one.
+/*
 /*     Arguments:
 /* .IP body_out
 /*     The output routine for body lines. It receives unmodified input
@@ -1015,27 +1031,51 @@ int     mime_state_update(MIME_STATE *state, int rec_type,
     }
 }
 
+ /*
+  * Mime error to (DSN, text) mapping. Order matters; more serious errors
+  * must precede less serious errors, because the error-to-text conversion
+  * can report only one error.
+  */
+static MIME_STATE_DETAIL mime_err_detail[] = {
+    MIME_ERR_NESTING, "5.6.0", "MIME nesting exceeds safety limit",
+    MIME_ERR_TRUNC_HEADER, "5.6.0", "message header length exceeds safety limit",
+    MIME_ERR_8BIT_IN_HEADER, "5.6.0", "improper use of 8-bit data in message header",
+    MIME_ERR_8BIT_IN_7BIT_BODY, "5.6.0", "improper use of 8-bit data in message body",
+    MIME_ERR_ENCODING_DOMAIN, "5.6.0", "invalid message/* or multipart/* encoding domain",
+    0,
+};
+
 /* mime_state_error - error code to string */
 
 const char *mime_state_error(int error_code)
 {
+    MIME_STATE_DETAIL *mp;
+
     if (error_code == 0)
        msg_panic("mime_state_error: there is no error");
-    if (error_code & MIME_ERR_NESTING)
-       return ("MIME nesting exceeds safety limit");
-    if (error_code & MIME_ERR_TRUNC_HEADER)
-       return ("message header length exceeds safety limit");
-    if (error_code & MIME_ERR_8BIT_IN_HEADER)
-       return ("improper use of 8-bit data in message header");
-    if (error_code & MIME_ERR_8BIT_IN_7BIT_BODY)
-       return ("improper use of 8-bit data in message body");
-    if (error_code & MIME_ERR_ENCODING_DOMAIN)
-       return ("invalid message/* or multipart/* encoding domain");
+    for (mp = mime_err_detail; mp->code; mp++)
+       if (mp->code & error_code)
+           return (mp->text);
     msg_panic("mime_state_error: unknown error code %d", error_code);
 }
 
+/* mime_state_detail - error code to table entry with assorted data */
+
+MIME_STATE_DETAIL *mime_state_detail(int error_code)
+{
+    MIME_STATE_DETAIL *mp;
+
+    if (error_code == 0)
+       msg_panic("mime_state_detail: there is no error");
+    for (mp = mime_err_detail; mp->code; mp++)
+       if (mp->code & error_code)
+           return (mp);
+    msg_panic("mime_state_detail: unknown error code %d", error_code);
+}
+
 #ifdef TEST
 
+#include <stdlib.h>
 #include <stringops.h>
 #include <vstream.h>
 #include <msg_vstream.h>
index a3318c881ed473f463bca5ccfccd1f8e749f2328..820be42885231301019aa0d20bcabe6e923b4119 100644 (file)
@@ -33,7 +33,6 @@ typedef void (*MIME_STATE_ERR_PRINT) (void *, int, const char *);
 extern MIME_STATE *mime_state_alloc(int, MIME_STATE_HEAD_OUT, MIME_STATE_ANY_END, MIME_STATE_BODY_OUT, MIME_STATE_ANY_END, MIME_STATE_ERR_PRINT, void *);
 extern int mime_state_update(MIME_STATE *, int, const char *, int);
 extern MIME_STATE *mime_state_free(MIME_STATE *);
-extern const char *mime_state_error(int);
 
  /*
   * Processing options.
@@ -58,12 +57,21 @@ extern const char *mime_state_error(int);
  /*
   * Processing errors, not necessarily lethal.
   */
+typedef struct {
+    const int code;                    /* internal error code */
+    const char *dsn;                   /* RFC 3463 */
+    const char *text;                  /* descriptive text */
+} MIME_STATE_DETAIL;
+
 #define MIME_ERR_NESTING               (1<<0)
 #define MIME_ERR_TRUNC_HEADER          (1<<1)
 #define MIME_ERR_8BIT_IN_HEADER                (1<<2)
 #define MIME_ERR_8BIT_IN_7BIT_BODY     (1<<3)
 #define MIME_ERR_ENCODING_DOMAIN       (1<<4)
 
+extern MIME_STATE_DETAIL *mime_state_detail(int);
+extern const char *mime_state_error(int);
+
  /*
   * Header classes. Look at the header_opts argument to find out if something
   * is a MIME header in a primary or nested section.
index f42790691e33c1730a1c265aa47868e048c9efdc..170e7f9ddb861202fabfdd7dc5c3e2d6a015e37b 100644 (file)
@@ -232,17 +232,23 @@ LMTP_RESP *lmtp_chat_resp(LMTP_STATE *state)
     /*
      * Extract RFC 821 reply code and RFC 2034 detail code. Use a default
      * detail code if none was given.
+     * 
+     * Ignore out-of-protocol enhanced status codes: codes that accompany 3XX
+     * replies, or codes whose initial digit is out of sync with the reply
+     * code.
      */
     DSN_CLASS(rdata.dsn) = 0;
     if (three_digs != 0) {
        rdata.code = atoi(STR(state->buffer));
-       for (cp = STR(state->buffer) + 4; *cp == ' '; cp++)
-            /* void */ ;
-       if ((len = dsn_valid(cp)) > 0) {
-           DSN_UPDATE(rdata.dsn, cp, len);
-       } else if (strchr("245", STR(state->buffer)[0]) != 0) {
-           DSN_UPDATE(rdata.dsn, "0.0.0", sizeof("0.0.0") - 1);
-           DSN_CLASS(rdata.dsn) = STR(state->buffer)[0];
+       if (strchr("245", STR(state->buffer)[0]) != 0) {
+           for (cp = STR(state->buffer) + 4; *cp == ' '; cp++)
+                /* void */ ;
+           if ((len = dsn_valid(cp)) > 0 && *cp == *STR(state->buffer)) {
+               DSN_UPDATE(rdata.dsn, cp, len);
+           } else {
+               DSN_UPDATE(rdata.dsn, "0.0.0", sizeof("0.0.0") - 1);
+               DSN_CLASS(rdata.dsn) = STR(state->buffer)[0];
+           }
        }
     } else {
        rdata.code = 0;
index 889ce0fe18dc19e91ab699b72551305552a9a879..aad0929a9ccb5506f1061085849a9f57755e72bf 100644 (file)
@@ -255,17 +255,23 @@ SMTP_RESP *smtp_chat_resp(SMTP_SESSION *session)
     /*
      * Extract RFC 821 reply code and RFC 2034 detail. Use a default detail
      * code if none was given.
+     * 
+     * Ignore out-of-protocol enhanced status codes: codes that accompany 3XX
+     * replies, or codes whose initial digit is out of sync with the reply
+     * code.
      */
     DSN_CLASS(rdata.dsn) = 0;
     if (three_digs != 0) {
        rdata.code = atoi(STR(session->buffer));
-       for (cp = STR(session->buffer) + 4; *cp == ' '; cp++)
-            /* void */ ;
-       if ((len = dsn_valid(cp)) > 0) {
-           DSN_UPDATE(rdata.dsn, cp, len);
-       } else if (strchr("245", STR(session->buffer)[0]) != 0) {
-           DSN_UPDATE(rdata.dsn, "0.0.0", sizeof("0.0.0") - 1);
-           DSN_CLASS(rdata.dsn) = STR(session->buffer)[0];
+       if (strchr("245", STR(session->buffer)[0]) != 0) {
+           for (cp = STR(session->buffer) + 4; *cp == ' '; cp++)
+                /* void */ ;
+           if ((len = dsn_valid(cp)) > 0 && *cp == *STR(session->buffer)) {
+               DSN_UPDATE(rdata.dsn, cp, len);
+           } else {
+               DSN_UPDATE(rdata.dsn, "0.0.0", sizeof("0.0.0") - 1);
+               DSN_CLASS(rdata.dsn) = STR(session->buffer)[0];
+           }
        }
     } else {
        rdata.code = 0;
index 1cfbb6815b2d0bbbaa0c7810c32c8fbdf84c1a42..3ab9eac2b8aa921fa5aa8d5431dde218109f9410 100644 (file)
@@ -819,6 +819,7 @@ static int smtp_loop(SMTP_STATE *state, NOCLOBBER int send_state,
     NOCLOBBER int mail_from_rejected;
     NOCLOBBER int downgrading;
     int     mime_errs;
+    MIME_STATE_DETAIL *detail;
 
     /*
      * Macros for readability.
@@ -1378,9 +1379,9 @@ static int smtp_loop(SMTP_STATE *state, NOCLOBBER int send_state,
                                          vstring_str(session->scratch),
                                          VSTRING_LEN(session->scratch));
                    if (mime_errs) {
-                       smtp_mesg_fail(state, "5.6.5", 554,
-                                      "MIME 7-bit conversion failed: %s",
-                                      mime_state_error(mime_errs));
+                       detail = mime_state_detail(mime_errs);
+                       smtp_mesg_fail(state, detail->dsn, 554, "%s",
+                                      detail->text);
                        RETURN(0);
                    }
                }
@@ -1396,13 +1397,14 @@ static int smtp_loop(SMTP_STATE *state, NOCLOBBER int send_state,
                 * ending in newline via /usr/sbin/sendmail while MIME input
                 * processing is turned off, and MIME 8bit->7bit conversion
                 * is requested upon delivery.
+                * 
+                * Or some error while doing generic address mapping.
                 */
                mime_errs =
                    mime_state_update(session->mime_state, rec_type, "", 0);
                if (mime_errs) {
-                   smtp_mesg_fail(state, "5.6.5", 554,
-                                  "MIME 7-bit conversion failed: %s",
-                                  mime_state_error(mime_errs));
+                   detail = mime_state_detail(mime_errs);
+                   smtp_mesg_fail(state, detail->dsn, 554, "%s", detail->text);
                    RETURN(0);
                }
            } else if (prev_type == REC_TYPE_CONT)      /* missing newline */
index 34685b848e3600e6163874b909c958cdd2711886..17917a2c2c49f61871cf1ff5e890e3b11f66df36 100644 (file)
@@ -392,6 +392,12 @@ inet_proto: $(LIB)
 stream_test: stream_test.c $(LIB)
        $(CC) $(CFLAGS)  -o $@ $@.c $(LIB) $(SYSLIBS)
 
+gcctest: gccw.c gccw.ref
+       rm -f gccw.o
+       make gccw.o 2>&1 | sed "s/\`/'/g; s/return-/return /" | sort >gccw.tmp
+       diff gccw.ref gccw.tmp
+       rm -f gccw.o gccw.tmp
+
 tests: valid_hostname_test mac_expand_test dict_test unescape_test \
        hex_quote_test ctable_test inet_addr_list_test base64_code_test \
        attr_scan64_test attr_scan0_test dict_pcre_test host_port_test \
diff --git a/postfix/src/util/gccw.c b/postfix/src/util/gccw.c
new file mode 100644 (file)
index 0000000..d3421fe
--- /dev/null
@@ -0,0 +1,58 @@
+ /*
+  * This is is a regression test for all the things that gcc is meant to warn
+  * about.
+  * 
+  * gcc version 3 breaks several tests:
+  * 
+  * -W does not report missing return value
+  * 
+  * -Wunused does not report unused parameter
+  */
+
+#include <stdio.h>
+#include <setjmp.h>
+
+jmp_buf jbuf;
+
+ /* -Wmissing-prototypes: no previous prototype for 'test1' */
+ /* -Wimplicit: return type defaults to `int' */
+test1(void)
+{
+    /* -Wunused: unused variable `foo' */
+    int     foo;
+
+    /* -Wparentheses: suggest parentheses around && within || */
+    printf("%d\n", 1 && 2 || 3 && 4);
+    /* -W: statement with no effect */
+    0;
+    /* BROKEN in gcc 3 */
+    /* -W: control reaches end of non-void function */
+}
+
+
+ /* -W??????: unused parameter `foo' */
+void    test2(int foo)
+{
+    enum {
+    a = 10, b = 15} moe;
+    int     bar;
+
+    /* -Wuninitialized: 'bar' might be used uninitialized in this function */
+    /* -Wformat: format argument is not a pointer (arg 2) */
+    printf("%s\n", bar);
+    /* -Wformat: too few arguments for format */
+    printf("%s%s\n", "bar");
+    /* -Wformat: too many arguments for format */
+    printf("%s\n", "bar", "bar");
+
+    /* -Wswitch: enumeration value `b' not handled in switch */
+    switch (moe) {
+    case a:
+       return;
+    }
+}
+
+ /* -Wstrict-prototypes: function declaration isn't a prototype */
+void    test3()
+{
+}
diff --git a/postfix/src/util/gccw.ref b/postfix/src/util/gccw.ref
new file mode 100644 (file)
index 0000000..7616c29
--- /dev/null
@@ -0,0 +1,18 @@
+gcc -Wall -Wno-comment -Wformat -Wimplicit -Wmissing-prototypes  -Wparentheses -Wstrict-prototypes -Wswitch -Wuninitialized  -Wunused -DUSE_TLS -DHAS_PCRE -I/usr/local/include -DSNAPSHOT -g -O -I. -DFREEBSD5 -c gccw.c
+gccw.c: At top level:
+gccw.c: At top level:
+gccw.c: In function 'test1':
+gccw.c: In function 'test2':
+gccw.c:20: warning: no previous prototype for 'test1'
+gccw.c:20: warning: return type defaults to 'int'
+gccw.c:22: warning: unused variable 'foo'
+gccw.c:25: warning: suggest parentheses around && within ||
+gccw.c:27: warning: statement with no effect
+gccw.c:30: warning: control reaches end of non-void function
+gccw.c:35: warning: no previous prototype for 'test2'
+gccw.c:38: warning: 'bar' might be used uninitialized in this function
+gccw.c:42: warning: format argument is not a pointer (arg 2)
+gccw.c:44: warning: too few arguments for format
+gccw.c:46: warning: too many arguments for format
+gccw.c:52: warning: enumeration value 'b' not handled in switch
+gccw.c:57: warning: function declaration isn't a prototype