Re: [Exim] [PATCH] MIME encapsulated bounce and autoreply me…

Etusivu
Poista viesti
Vastaa
Lähettäjä: Eli Chen
Päiväys:  
Vastaanottaja: exim-users
Aihe: Re: [Exim] [PATCH] MIME encapsulated bounce and autoreply messages
Hi, I already found a problem with my boundary generation code. This one's
much better because it adds the message id to the time stamp, similar to
Sendmail's method:

/* Generate a pseudo-random MIME boundary string */
-#define generateMimeBoundary(buf)
snprintf(buf,sizeof(buf),"mimeboundary.%d.%d",time(NULL),time(NULL)*2);
+#define generateMimeBoundary(buf)
snprintf(buf,sizeof(buf),"mimeboundary.%s.%d",message_id,time(NULL));

Eli

----- Original Message -----
From: "Eli Chen" <eli@???>
To: <exim-users@???>
Sent: Wednesday, April 24, 2002 4:05 PM
Subject: [Exim] [PATCH] MIME encapsulated bounce and autoreply messages


> This is a multi-part message in MIME format.
> --
> I know this is on the wishlist, but I can't wait any longer. ;)
>
> This encloses the original message in exim-generated bounce and
> autoreply messages in MIME encapsulated format. The original message is
> also attached to warning messages. This allows the original message to
> be viewed correctly in its original language. Sendmail and Microsoft
> Exchange already does this.
>
> I didn't allow this to be a configurable option, so there might be some
> work involved there. I know the MIME boundary generation code is a
> little silly; any suggestions/improvements are welcome!
>
> The attached diff is done on v. 3.32
> --
> diff -u -r1.3 deliver.c
> --- deliver.c 2002/02/20 18:24:58 1.3
> +++ deliver.c 2002/04/24 22:25:30
> @@ -5224,9 +5224,12 @@
>        BOOL to_sender = strcmpic(sender_address, errmsg_recipient) == 0;
>        int max = (return_size_limit/DELIVER_IN_BUFFER_SIZE + 1) *
>          DELIVER_IN_BUFFER_SIZE;
> -
> +      char mimeboundary[256];
> +
>        DEBUG(9) debug_printf("sending error message to: %s\n",

errmsg_recipient);
>
> +      generateMimeBoundary(mimeboundary);
> +
>        /* Scan the addresses for all that have the same errors_address,

removing
>        them from the addr_failed chain, and putting them on msgchain. */

>
> @@ -5291,6 +5294,9 @@
>        bcc = moan_check_errorcopy(errmsg_recipient);
>        if (bcc != NULL) fprintf(f, "Bcc: %s\n", bcc);

>
> +      /* Add MIME-encapsulated message headers */
> +      fprintf(f, "MIME-Version: 1.0\nContent-Type:

multipart/mixed;\n\tboundary=\"%s\"\n", mimeboundary);
> +
>        /* The texts for the message can be read from a template file; if

there
>        isn't one, or if it is too short, built-in texts are used. The

first
>        emf text is a Subject: and any other headers. */
> @@ -5302,6 +5308,12 @@
>            to_sender? ": returning message to sender" : "");
>          }

>
> +      /* Print MIME warning */
> +      fprintf(f, "This is a MIME-encapsulated message\n\n");
> +
> +      /* MIME-encapsulate text */
> +      fprintf(f, "--%s\n\n", mimeboundary);
> +
>        emf_text = next_emf(emf, "intro");
>        if (emf_text != NULL) fprintf(f, "%s", emf_text); else
>          {
> @@ -5442,7 +5454,7 @@
>        if (emf_text != NULL) fprintf(f, "%s", emf_text); else
>          {
>          fprintf(f,
> -"------ This is a copy of the message, including all the

headers. ------\n");
> +"------ Attached is a copy of the message. ------\n");
>          }

>
>        /* While reading the "truncated" message, set return_size_limit to
> @@ -5472,6 +5484,10 @@
>          }

>
>        fprintf(f, "\n");
> +
> +      /* MIME-encapsulate original message */
> +      fprintf(f, "--%s\nContent-Type: message/rfc822\n\n", mimeboundary);
> +
>        fflush(f);
>        transport_filter_argv = NULL;   /* Just in case */
>        return_path = sender_address;   /* In case not previously set */
> @@ -5487,6 +5503,9 @@
>          fclose(emf);
>          }

>
> +      /* end MIME-encapsulation */
> +      fprintf(f, "--%s--\n", mimeboundary);
> +
>        /* Close the file, which should send an EOF to the child process
>        that is receiving the message. Wait for it to finish. */

>
> @@ -5735,6 +5754,11 @@
>        header_line *h;
>        int fd;
>        pid_t pid = child_open_exim(&fd);
> +      int max = (return_size_limit/DELIVER_IN_BUFFER_SIZE + 1) *
> +        DELIVER_IN_BUFFER_SIZE;
> +      char mimeboundary[256];
> +
> +      generateMimeBoundary(mimeboundary);

>
>        if (pid > 0)
>          {
> @@ -5761,6 +5785,9 @@
>            qualify_domain_sender);
>          fprintf(f, "To: %s\n", recipients);

>
> +        /* Add MIME-encapsulated message headers */
> +        fprintf(f, "MIME-Version: 1.0\nContent-Type:

multipart/mixed;\n\tboundary=\"%s\"\n", mimeboundary);
> +
>          wmf_text = next_emf(wmf, "header");
>          if (wmf_text != NULL)
>            fprintf(f, "%s\n", wmf_text);
> @@ -5768,6 +5795,12 @@
>            fprintf(f, "Subject: Warning: message %s delayed %s\n\n",
>              message_id, warnmsg_delay);

>
> +        /* Print MIME warning */
> +        fprintf(f, "This is a MIME-encapsulated message\n\n");
> +
> +        /* MIME-encapsulate text */
> +        fprintf(f, "--%s\n\n", mimeboundary);
> +
>          wmf_text = next_emf(wmf, "intro");
>          if (wmf_text != NULL) fprintf(f, "%s", wmf_text); else
>            {
> @@ -5839,6 +5872,68 @@
>  "and when that happens, the message will be returned to you.\n");
>            }

>
> +        fprintf(f, "\n");
> +
> +        /* Now copy the message, trying to give an intelligible comment

if
> +           it is too long for it all to be copied. The limit isn't

strictly
> +           applied because of the buffering. */
> +
> +        wmf_text = next_emf(wmf, "copy");
> +        if (wmf_text != NULL) fprintf(f, "%s", wmf_text); else
> +        {
> +            fprintf(f,
> +                    "------ Attached is a copy of the

message. ------\n");
> +        }
> +
> +        /* While reading the "truncated" message, set return_size_limit

to
> +           the actual max testing value, rounded. We need to read the

message
> +           whether we are going to use it or not. */
> +
> +        {
> +            int temp = return_size_limit;
> +            return_size_limit = (max/1000)*1000;
> +            wmf_text = next_emf(wmf, "truncated");
> +            return_size_limit = temp;
> +        }
> +
> +        if (return_size_limit > 0)
> +        {
> +            struct stat statbuf;
> +            if (fstat(deliver_datafile, &statbuf) == 0 && statbuf.st_size
> max)
> +            {
> +                if (wmf_text != NULL) fprintf(f, "%s", wmf_text); else
> +                {
> +                    fprintf(f,
> +                            "------ The body of the message is %d

characters long; only the first\n"
> +                            "------ %d or so are included here.\n",

(int)statbuf.st_size,
> +                            return_size_limit);
> +                }
> +            }
> +        }
> +
> +        fprintf(f, "\n");
> +
> +        /* MIME-encapsulate original message */
> +        fprintf(f, "--%s\nContent-Type: message/rfc822\n\n",

mimeboundary);
> +
> +        fflush(f);
> +        transport_filter_argv = NULL;   /* Just in case */
> +        return_path = sender_address;   /* In case not previously set */
> +        transport_write_message(NULL, fileno(f), topt_add_return_path,
> +                                return_size_limit, NULL, NULL, NULL,

NULL, NULL, 0);
> +
> +        /* Write final text and close the template file if one is open */
> +
> +        if (wmf != NULL)
> +        {
> +            wmf_text = next_emf(wmf, "final");
> +            if (wmf_text != NULL) fprintf(f, "%s", wmf_text);
> +            fclose(wmf);
> +        }
> +
> +        /* end MIME-encapsulation */
> +        fprintf(f, "--%s--\n", mimeboundary);
> +
>          /* Close and wait for child process to complete, without a

timeout.
>          If there's an error, don't update the count. */

>
> diff -u -r1.2 macros.h
> --- macros.h 2001/11/27 05:43:44 1.2
> +++ macros.h 2002/04/24 22:25:30
> @@ -6,6 +6,9 @@
> /* See the file NOTICE for conditions of use and distribution. */
>
>
> +/* Generate a pseudo-random MIME boundary string */
> +#define generateMimeBoundary(buf)

snprintf(buf,sizeof(buf),"mimeboundary.%d.%d",time(NULL),time(NULL)*2);
> +
> /* These aren't macros, but they're the sort of general definition that

fits in
> this file and we need to have them defined early. Some operating systems
> (naughtily, imo) include a definition for "uchar" in the standard header

files,
> diff -u -r1.1.1.1 autoreply.c
> --- transports/autoreply.c 2001/09/11 18:36:06 1.1.1.1
> +++ transports/autoreply.c 2002/04/24 22:25:30
> @@ -204,12 +204,15 @@
> time_t once_repeat;
> FILE *f;
> FILE *ff = NULL;
> +char mimeboundary[256];
>
>  autoreply_transport_options_block *ob =
>    (autoreply_transport_options_block *)(tblock->options_block);

>
> DEBUG(2) debug_printf("%s transport entered\n", tblock->name);
>
> +generateMimeBoundary(mimeboundary);
> +
> /* Set up for the good case */
>
> addr->transport_return = OK;
> @@ -482,8 +485,18 @@
> /* Add any specially requested headers */
>
> if (headers != NULL) fprintf(f, "%s\n", headers);
> +
> +/* Add MIME-encapsulated message headers */
> +fprintf(f, "MIME-Version: 1.0\nContent-Type:

multipart/mixed;\n\tboundary=\"%s\"\n", mimeboundary);
> +
> fprintf(f, "\n");
>
> +/* Print MIME warning */
> +fprintf(f, "This is a MIME-encapsulated message\n\n");
> +
> +/* MIME-encapsulate text */
> +fprintf(f, "--%s\n\n", mimeboundary);
> +
>  if (text != NULL)
>    {
>    fprintf(f, "%s", text);
> @@ -522,17 +535,20 @@
>      if (fstat(deliver_datafile, &statbuf) == 0 && statbuf.st_size > max)
>        {
>        int size = statbuf.st_size;  /* Because might be a long */
> -      fprintf(f, "\n"
> -"------ This is a copy of the message, including all the headers.\n"
> +      fprintf(f, "\n\n"
> +"------ Attached is a copy of the message.\n"
>  "------ The body of the message is %d characters long; only the first\n"
>  "------ %d or so are included here.\n\n", size, (max/1000)*1000);
>        }
> -    else fprintf(f, "\n"
> -"------ This is a copy of the message, including all the

headers. ------\n\n");
> +    else fprintf(f, "\n\n"
> +"------ Attached is a copy of the message. ------\n\n");
>      }
> -  else fprintf(f, "\n"
> -"------ This is a copy of the message, including all the

headers. ------\n\n");
> + else fprintf(f, "\n\n"
> +"------ Attached is a copy of the message. ------\n\n");
>
> +  /* MIME-encapsulate original message */
> +  fprintf(f, "--%s\nContent-Type: message/rfc822\n\n", mimeboundary);
> +
>    fflush(f);
>    transport_write_message(addr, fileno(f),
>      (tblock->body_only? topt_no_headers : 0) |
> @@ -543,6 +559,9 @@
>      return_size_limit, tblock->add_headers, tblock->remove_headers,
>      NULL, NULL, tblock->rewrite_rules, tblock->rewrite_existflags);
>    }
> +
> +/* end MIME-encapsulation */
> +fprintf(f, "--%s--\n", mimeboundary);

>
> /* End the message and wait for the child process to end; no timeout. */
>
>
>
> --
>
>
> --
>
> ## List details at http://www.exim.org/mailman/listinfo/exim-users Exim

details at http://www.exim.org/ ##
>