mirror of
https://github.com/vdukhovni/postfix
synced 2025-09-01 14:45:32 +00:00
snapshot-19990405
This commit is contained in:
@@ -2511,6 +2511,29 @@ Apologies for any names omitted.
|
|||||||
the extension to recipient addresses. This is more consistent
|
the extension to recipient addresses. This is more consistent
|
||||||
with the way aliases are expanded. File: local/dotforward.c.
|
with the way aliases are expanded. File: local/dotforward.c.
|
||||||
|
|
||||||
|
19990404
|
||||||
|
|
||||||
|
Bugfix: after receiving mail, the SMTP server didn't reset
|
||||||
|
the cleanup error flag, so that multiple deliveries over
|
||||||
|
the same SMTP session could fail due to errors with previous
|
||||||
|
deliveries. Found by Lamont Jones, Hewlett-Packard.
|
||||||
|
|
||||||
|
19990405
|
||||||
|
|
||||||
|
Feature: MIME-encapsulated bounces. Philip A. Prindeville,
|
||||||
|
Mirapoint, Inc., USA. File: bounce/bounce_notify_service.c
|
||||||
|
|
||||||
|
Cleanup: vstreams now properly look at the EOF flag before
|
||||||
|
attempting to read, eliminating the need for typing Ctrl-D
|
||||||
|
twice to test programs; the EOF flag is reset after each
|
||||||
|
unget or seek operation. Files: util/vstream.c, util/vbuf.c.
|
||||||
|
|
||||||
|
Feature: in preparation for configurable message headers
|
||||||
|
the mac_parse() routine now balances the parentheses in
|
||||||
|
${name} or $(name). We need this in order to support
|
||||||
|
conditional expressions such as ${name?text} where `text'
|
||||||
|
contains other ${name} expressions.
|
||||||
|
|
||||||
Future:
|
Future:
|
||||||
|
|
||||||
Planned: must be able to list the same hash table in
|
Planned: must be able to list the same hash table in
|
||||||
|
@@ -91,7 +91,8 @@
|
|||||||
|
|
||||||
/* bounce_header - generate bounce message header */
|
/* bounce_header - generate bounce message header */
|
||||||
|
|
||||||
static int bounce_header(VSTREAM *bounce, VSTRING *buf, const char *dest, int flush)
|
static int bounce_header(VSTREAM *bounce, VSTRING *buf, const char *dest,
|
||||||
|
const char *boundary, int flush)
|
||||||
{
|
{
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -113,15 +114,33 @@ static int bounce_header(VSTREAM *bounce, VSTRING *buf, const char *dest, int fl
|
|||||||
"Subject: Delayed Mail (still being retried)");
|
"Subject: Delayed Mail (still being retried)");
|
||||||
}
|
}
|
||||||
post_mail_fprintf(bounce, "To: %s", STR(quote_822_local(buf, dest)));
|
post_mail_fprintf(bounce, "To: %s", STR(quote_822_local(buf, dest)));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* MIME header.
|
||||||
|
*/
|
||||||
|
post_mail_fprintf(bounce, "MIME-Version: 1.0");
|
||||||
|
post_mail_fprintf(bounce, "Content-Type: %s/%s;", "multipart", "mixed");
|
||||||
|
post_mail_fprintf(bounce, "\tboundary=\"%s\"", boundary);
|
||||||
|
post_mail_fputs(bounce, "");
|
||||||
|
post_mail_fputs(bounce, "This is a MIME-encapsulated message.");
|
||||||
post_mail_fputs(bounce, "");
|
post_mail_fputs(bounce, "");
|
||||||
return (vstream_ferror(bounce));
|
return (vstream_ferror(bounce));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* bounce_boilerplate - generate boiler-plate text */
|
/* bounce_boilerplate - generate boiler-plate text */
|
||||||
|
|
||||||
static int bounce_boilerplate(VSTREAM *bounce, VSTRING *buf, int flush)
|
static int bounce_boilerplate(VSTREAM *bounce, VSTRING *buf,
|
||||||
|
const char *boundary, int flush)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
/*
|
||||||
|
* MIME header.
|
||||||
|
*/
|
||||||
|
post_mail_fprintf(bounce, "--%s", boundary);
|
||||||
|
post_mail_fprintf(bounce, "Content-Description: %s", "Notification");
|
||||||
|
post_mail_fprintf(bounce, "Content-Type: %s/%s", "text", "plain");
|
||||||
|
post_mail_fputs(bounce, "");
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Print the message body with the problem report. XXX For now, we use a
|
* Print the message body with the problem report. XXX For now, we use a
|
||||||
* fixed bounce template. We could use a site-specific parametrized
|
* fixed bounce template. We could use a site-specific parametrized
|
||||||
@@ -166,6 +185,7 @@ static int bounce_boilerplate(VSTREAM *bounce, VSTRING *buf, int flush)
|
|||||||
}
|
}
|
||||||
post_mail_fputs(bounce, "");
|
post_mail_fputs(bounce, "");
|
||||||
post_mail_fprintf(bounce, "\t\t\tThe %s program", var_mail_name);
|
post_mail_fprintf(bounce, "\t\t\tThe %s program", var_mail_name);
|
||||||
|
post_mail_fputs(bounce, "");
|
||||||
return (vstream_ferror(bounce));
|
return (vstream_ferror(bounce));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -180,10 +200,19 @@ static void bounce_print(const char *str, int len, int indent, char *context)
|
|||||||
|
|
||||||
/* bounce_diagnostics - send bounce log report */
|
/* bounce_diagnostics - send bounce log report */
|
||||||
|
|
||||||
static int bounce_diagnostics(char *service, VSTREAM *bounce, VSTRING *buf, char *queue_id)
|
static int bounce_diagnostics(char *service, VSTREAM *bounce, VSTRING *buf,
|
||||||
|
char *queue_id, const char *boundary)
|
||||||
{
|
{
|
||||||
VSTREAM *log;
|
VSTREAM *log;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* MIME header.
|
||||||
|
*/
|
||||||
|
post_mail_fprintf(bounce, "--%s", boundary);
|
||||||
|
post_mail_fprintf(bounce, "Content-Description: %s", "Delivery error report");
|
||||||
|
post_mail_fprintf(bounce, "Content-Type: %s/%s", "text", "plain");
|
||||||
|
post_mail_fputs(bounce, "");
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If the bounce log cannot be found, do not raise a fatal run-time
|
* If the bounce log cannot be found, do not raise a fatal run-time
|
||||||
* error. There is nothing we can do about the error, and all we are
|
* error. There is nothing we can do about the error, and all we are
|
||||||
@@ -195,7 +224,6 @@ static int bounce_diagnostics(char *service, VSTREAM *bounce, VSTRING *buf, char
|
|||||||
if ((log = mail_queue_open(service, queue_id, O_RDONLY, 0)) == 0) {
|
if ((log = mail_queue_open(service, queue_id, O_RDONLY, 0)) == 0) {
|
||||||
if (errno != ENOENT)
|
if (errno != ENOENT)
|
||||||
msg_fatal("open %s %s: %m", service, queue_id);
|
msg_fatal("open %s %s: %m", service, queue_id);
|
||||||
post_mail_fputs(bounce, "");
|
|
||||||
post_mail_fputs(bounce, "\t--- Delivery error report unavailable ---");
|
post_mail_fputs(bounce, "\t--- Delivery error report unavailable ---");
|
||||||
post_mail_fputs(bounce, "");
|
post_mail_fputs(bounce, "");
|
||||||
}
|
}
|
||||||
@@ -211,9 +239,6 @@ static int bounce_diagnostics(char *service, VSTREAM *bounce, VSTRING *buf, char
|
|||||||
|
|
||||||
#define LENGTH 79
|
#define LENGTH 79
|
||||||
#define INDENT 4
|
#define INDENT 4
|
||||||
post_mail_fputs(bounce, "");
|
|
||||||
post_mail_fputs(bounce, "\t--- Delivery error report follows ---");
|
|
||||||
post_mail_fputs(bounce, "");
|
|
||||||
while (vstream_ferror(bounce) == 0 && vstring_fgets_nonl(buf, log)) {
|
while (vstream_ferror(bounce) == 0 && vstring_fgets_nonl(buf, log)) {
|
||||||
printable(STR(buf), '_');
|
printable(STR(buf), '_');
|
||||||
line_wrap(STR(buf), LENGTH, INDENT, bounce_print, (char *) bounce);
|
line_wrap(STR(buf), LENGTH, INDENT, bounce_print, (char *) bounce);
|
||||||
@@ -229,13 +254,22 @@ static int bounce_diagnostics(char *service, VSTREAM *bounce, VSTRING *buf, char
|
|||||||
/* bounce_original - send a copy of the original to the victim */
|
/* bounce_original - send a copy of the original to the victim */
|
||||||
|
|
||||||
static int bounce_original(char *service, VSTREAM *bounce, VSTRING *buf,
|
static int bounce_original(char *service, VSTREAM *bounce, VSTRING *buf,
|
||||||
char *queue_name, char *queue_id, int headers_only)
|
char *queue_name, char *queue_id,
|
||||||
|
const char *boundary, int headers_only)
|
||||||
{
|
{
|
||||||
int status = 0;
|
int status = 0;
|
||||||
VSTREAM *src;
|
VSTREAM *src;
|
||||||
int rec_type;
|
int rec_type;
|
||||||
int bounce_length;
|
int bounce_length;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* MIME headers.
|
||||||
|
*/
|
||||||
|
post_mail_fprintf(bounce, "--%s", boundary);
|
||||||
|
post_mail_fprintf(bounce, "Content-Description: %s", "Undelivered Message");
|
||||||
|
post_mail_fprintf(bounce, "Content-Type: %s/%s", "message", "rfc822");
|
||||||
|
post_mail_fputs(bounce, "");
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If the original message cannot be found, do not raise a run-time
|
* If the original message cannot be found, do not raise a run-time
|
||||||
* error. There is nothing we can do about the error, and all we are
|
* error. There is nothing we can do about the error, and all we are
|
||||||
@@ -248,15 +282,10 @@ static int bounce_original(char *service, VSTREAM *bounce, VSTRING *buf,
|
|||||||
if (errno != ENOENT)
|
if (errno != ENOENT)
|
||||||
msg_fatal("open %s %s: %m", service, queue_id);
|
msg_fatal("open %s %s: %m", service, queue_id);
|
||||||
post_mail_fputs(bounce, "\t--- Undelivered message unavailable ---");
|
post_mail_fputs(bounce, "\t--- Undelivered message unavailable ---");
|
||||||
|
post_mail_fputs(bounce, "");
|
||||||
return (vstream_ferror(bounce));
|
return (vstream_ferror(bounce));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Append a copy of the rejected message.
|
|
||||||
*/
|
|
||||||
post_mail_fputs(bounce, "\t--- Undelivered message follows ---");
|
|
||||||
post_mail_fputs(bounce, "");
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Skip over the original message envelope records. If the envelope is
|
* Skip over the original message envelope records. If the envelope is
|
||||||
* corrupted just send whatever we can (remember this is a best effort,
|
* corrupted just send whatever we can (remember this is a best effort,
|
||||||
@@ -285,6 +314,7 @@ static int bounce_original(char *service, VSTREAM *bounce, VSTRING *buf,
|
|||||||
status = (REC_PUT_BUF(bounce, rec_type, buf) != rec_type);
|
status = (REC_PUT_BUF(bounce, rec_type, buf) != rec_type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
post_mail_fprintf(bounce, "--%s--", boundary);
|
||||||
if (headers_only == 0 && rec_type != REC_TYPE_XTRA)
|
if (headers_only == 0 && rec_type != REC_TYPE_XTRA)
|
||||||
status |= mark_corrupt(src);
|
status |= mark_corrupt(src);
|
||||||
if (vstream_fclose(src))
|
if (vstream_fclose(src))
|
||||||
@@ -302,6 +332,13 @@ int bounce_notify_service(char *service, char *queue_name,
|
|||||||
int postmaster_status = 1;
|
int postmaster_status = 1;
|
||||||
VSTREAM *bounce;
|
VSTREAM *bounce;
|
||||||
int notify_mask = name_mask(mail_error_masks, var_notify_classes);
|
int notify_mask = name_mask(mail_error_masks, var_notify_classes);
|
||||||
|
VSTRING *boundary = vstring_alloc(100);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Unique string for multi-part message boundaries.
|
||||||
|
*/
|
||||||
|
vstring_sprintf(boundary, "%s.%ld/%s",
|
||||||
|
queue_id, event_time(), var_myhostname);
|
||||||
|
|
||||||
#define NULL_SENDER MAIL_ADDR_EMPTY /* special address */
|
#define NULL_SENDER MAIL_ADDR_EMPTY /* special address */
|
||||||
#define NULL_CLEANUP_FLAGS 0
|
#define NULL_CLEANUP_FLAGS 0
|
||||||
@@ -354,9 +391,12 @@ int bounce_notify_service(char *service, char *queue_name,
|
|||||||
* reason for the bounce, and the headers of the original
|
* reason for the bounce, and the headers of the original
|
||||||
* message. Don't bother sending the boiler-plate text.
|
* message. Don't bother sending the boiler-plate text.
|
||||||
*/
|
*/
|
||||||
if (!bounce_header(bounce, buf, mail_addr_postmaster(), flush)
|
if (!bounce_header(bounce, buf, mail_addr_postmaster(),
|
||||||
&& bounce_diagnostics(service, bounce, buf, queue_id) == 0)
|
STR(boundary), flush)
|
||||||
|
&& bounce_diagnostics(service, bounce, buf, queue_id,
|
||||||
|
STR(boundary)) == 0)
|
||||||
bounce_original(service, bounce, buf, queue_name, queue_id,
|
bounce_original(service, bounce, buf, queue_name, queue_id,
|
||||||
|
STR(boundary),
|
||||||
flush ? BOUNCE_ALL : BOUNCE_HEADERS);
|
flush ? BOUNCE_ALL : BOUNCE_HEADERS);
|
||||||
bounce_status = post_mail_fclose(bounce);
|
bounce_status = post_mail_fclose(bounce);
|
||||||
}
|
}
|
||||||
@@ -376,10 +416,12 @@ int bounce_notify_service(char *service, char *queue_name,
|
|||||||
* pretends that we are a polite mail system, the text with
|
* pretends that we are a polite mail system, the text with
|
||||||
* reason for the bounce, and a copy of the original message.
|
* reason for the bounce, and a copy of the original message.
|
||||||
*/
|
*/
|
||||||
if (bounce_header(bounce, buf, recipient, flush) == 0
|
if (bounce_header(bounce, buf, recipient, STR(boundary), flush) == 0
|
||||||
&& bounce_boilerplate(bounce, buf, flush) == 0
|
&& bounce_boilerplate(bounce, buf, STR(boundary), flush) == 0
|
||||||
&& bounce_diagnostics(service, bounce, buf, queue_id) == 0)
|
&& bounce_diagnostics(service, bounce, buf, queue_id,
|
||||||
|
STR(boundary)) == 0)
|
||||||
bounce_original(service, bounce, buf, queue_name, queue_id,
|
bounce_original(service, bounce, buf, queue_name, queue_id,
|
||||||
|
STR(boundary),
|
||||||
flush ? BOUNCE_ALL : BOUNCE_HEADERS);
|
flush ? BOUNCE_ALL : BOUNCE_HEADERS);
|
||||||
bounce_status = post_mail_fclose(bounce);
|
bounce_status = post_mail_fclose(bounce);
|
||||||
}
|
}
|
||||||
@@ -407,10 +449,12 @@ int bounce_notify_service(char *service, char *queue_name,
|
|||||||
mail_addr_postmaster(),
|
mail_addr_postmaster(),
|
||||||
NULL_CLEANUP_FLAGS,
|
NULL_CLEANUP_FLAGS,
|
||||||
"BOUNCE")) != 0) {
|
"BOUNCE")) != 0) {
|
||||||
if (!bounce_header(bounce, buf, mail_addr_postmaster(), flush)
|
if (!bounce_header(bounce, buf, mail_addr_postmaster(),
|
||||||
&& bounce_diagnostics(service, bounce, buf, queue_id) == 0)
|
STR(boundary), flush)
|
||||||
|
&& bounce_diagnostics(service, bounce, buf,
|
||||||
|
queue_id, STR(boundary)) == 0)
|
||||||
bounce_original(service, bounce, buf, queue_name, queue_id,
|
bounce_original(service, bounce, buf, queue_name, queue_id,
|
||||||
BOUNCE_HEADERS);
|
STR(boundary), BOUNCE_HEADERS);
|
||||||
postmaster_status = post_mail_fclose(bounce);
|
postmaster_status = post_mail_fclose(bounce);
|
||||||
}
|
}
|
||||||
if (postmaster_status)
|
if (postmaster_status)
|
||||||
@@ -432,6 +476,7 @@ int bounce_notify_service(char *service, char *queue_name,
|
|||||||
* Cleanup.
|
* Cleanup.
|
||||||
*/
|
*/
|
||||||
vstring_free(buf);
|
vstring_free(buf);
|
||||||
|
vstring_free(boundary);
|
||||||
|
|
||||||
return (bounce_status);
|
return (bounce_status);
|
||||||
}
|
}
|
||||||
|
@@ -15,7 +15,7 @@
|
|||||||
* Version of this program.
|
* Version of this program.
|
||||||
*/
|
*/
|
||||||
#define VAR_MAIL_VERSION "mail_version"
|
#define VAR_MAIL_VERSION "mail_version"
|
||||||
#define DEF_MAIL_VERSION "Snapshot-19990402"
|
#define DEF_MAIL_VERSION "Snapshot-19990405"
|
||||||
extern char *var_mail_version;
|
extern char *var_mail_version;
|
||||||
|
|
||||||
/* LICENSE
|
/* LICENSE
|
||||||
|
@@ -497,6 +497,7 @@ static void mail_reset(SMTPD_STATE *state)
|
|||||||
mail_stream_cleanup(state->dest);
|
mail_stream_cleanup(state->dest);
|
||||||
state->dest = 0;
|
state->dest = 0;
|
||||||
state->cleanup = 0;
|
state->cleanup = 0;
|
||||||
|
state->err = 0;
|
||||||
}
|
}
|
||||||
if (state->queue_id != 0) {
|
if (state->queue_id != 0) {
|
||||||
myfree(state->queue_id);
|
myfree(state->queue_id);
|
||||||
|
@@ -72,6 +72,7 @@ void mac_parse(const char *value, MAC_PARSE_FN action, char *context)
|
|||||||
const char *ep; /* string end pointer */
|
const char *ep; /* string end pointer */
|
||||||
static char open_paren[] = "({";
|
static char open_paren[] = "({";
|
||||||
static char close_paren[] = ")}";
|
static char close_paren[] = ")}";
|
||||||
|
int level;
|
||||||
|
|
||||||
#define SKIP(start, var, cond) \
|
#define SKIP(start, var, cond) \
|
||||||
for (var = start; *var && (cond); var++);
|
for (var = start; *var && (cond); var++);
|
||||||
@@ -92,12 +93,18 @@ void mac_parse(const char *value, MAC_PARSE_FN action, char *context)
|
|||||||
vp += 1;
|
vp += 1;
|
||||||
pp = open_paren;
|
pp = open_paren;
|
||||||
if (*vp == *pp || *vp == *++pp) { /* ${x} or $(x) */
|
if (*vp == *pp || *vp == *++pp) { /* ${x} or $(x) */
|
||||||
|
level = 1;
|
||||||
vp += 1;
|
vp += 1;
|
||||||
SKIP(vp, ep, *ep != close_paren[pp - open_paren]);
|
for (ep = vp; level > 0; ep++) {
|
||||||
if (*ep == 0)
|
if (*ep == 0)
|
||||||
msg_fatal("incomplete macro: %s", value);
|
msg_fatal("incomplete macro: %s", value);
|
||||||
vstring_strncat(buf, vp, ep - vp);
|
if (*ep == *pp)
|
||||||
vp = ep + 1;
|
level++;
|
||||||
|
if (*ep == close_paren[pp - open_paren])
|
||||||
|
level--;
|
||||||
|
}
|
||||||
|
vstring_strncat(buf, vp, ep - vp - 1);
|
||||||
|
vp = ep;
|
||||||
} else { /* plain $x */
|
} else { /* plain $x */
|
||||||
SKIP(vp, ep, ISALNUM(*ep) || *ep == '_');
|
SKIP(vp, ep, ISALNUM(*ep) || *ep == '_');
|
||||||
vstring_strncat(buf, vp, ep - vp);
|
vstring_strncat(buf, vp, ep - vp);
|
||||||
|
@@ -134,7 +134,7 @@ int vbuf_unget(VBUF *bp, int ch)
|
|||||||
return (VBUF_EOF);
|
return (VBUF_EOF);
|
||||||
} else {
|
} else {
|
||||||
bp->cnt--;
|
bp->cnt--;
|
||||||
bp->flags &= ~VBUF_FLAG_ERR;
|
bp->flags &= ~VBUF_FLAG_EOF;
|
||||||
return (*--bp->ptr = ch);
|
return (*--bp->ptr = ch);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -594,6 +594,12 @@ static int vstream_buf_get_ready(VBUF *bp)
|
|||||||
if (vstream_fflush_delayed(stream))
|
if (vstream_fflush_delayed(stream))
|
||||||
return (VSTREAM_EOF);
|
return (VSTREAM_EOF);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Did we receive an EOF indication?
|
||||||
|
*/
|
||||||
|
if (bp->flags & VSTREAM_FLAG_EOF)
|
||||||
|
return (VSTREAM_EOF);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Fill the buffer with as much data as we can handle, or with as much
|
* Fill the buffer with as much data as we can handle, or with as much
|
||||||
* data as is available right now, whichever is less. Update the cached
|
* data as is available right now, whichever is less. Update the cached
|
||||||
@@ -766,6 +772,7 @@ long vstream_fseek(VSTREAM *stream, long offset, int whence)
|
|||||||
} else {
|
} else {
|
||||||
bp->flags |= VSTREAM_FLAG_SEEK;
|
bp->flags |= VSTREAM_FLAG_SEEK;
|
||||||
}
|
}
|
||||||
|
bp->flags &= ~VSTREAM_FLAG_EOF;
|
||||||
return (stream->offset);
|
return (stream->offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user