2
0
mirror of https://github.com/vdukhovni/postfix synced 2025-08-30 21:55:20 +00:00

snapshot-19990405

This commit is contained in:
Wietse Venema
1999-04-05 00:00:00 -05:00
parent c40b6e2174
commit 08307123e8
7 changed files with 112 additions and 29 deletions

View File

@@ -2511,6 +2511,29 @@ Apologies for any names omitted.
the extension to recipient addresses. This is more consistent
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:
Planned: must be able to list the same hash table in

View File

@@ -91,7 +91,8 @@
/* 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)");
}
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, "");
return (vstream_ferror(bounce));
}
/* 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
* 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_fprintf(bounce, "\t\t\tThe %s program", var_mail_name);
post_mail_fputs(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 */
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;
/*
* 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
* 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 (errno != ENOENT)
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, "");
}
@@ -211,9 +239,6 @@ static int bounce_diagnostics(char *service, VSTREAM *bounce, VSTRING *buf, char
#define LENGTH 79
#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)) {
printable(STR(buf), '_');
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 */
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;
VSTREAM *src;
int rec_type;
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
* 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)
msg_fatal("open %s %s: %m", service, queue_id);
post_mail_fputs(bounce, "\t--- Undelivered message unavailable ---");
post_mail_fputs(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
* 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);
}
}
post_mail_fprintf(bounce, "--%s--", boundary);
if (headers_only == 0 && rec_type != REC_TYPE_XTRA)
status |= mark_corrupt(src);
if (vstream_fclose(src))
@@ -302,6 +332,13 @@ int bounce_notify_service(char *service, char *queue_name,
int postmaster_status = 1;
VSTREAM *bounce;
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_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
* message. Don't bother sending the boiler-plate text.
*/
if (!bounce_header(bounce, buf, mail_addr_postmaster(), flush)
&& bounce_diagnostics(service, bounce, buf, queue_id) == 0)
if (!bounce_header(bounce, buf, mail_addr_postmaster(),
STR(boundary), flush)
&& bounce_diagnostics(service, bounce, buf, queue_id,
STR(boundary)) == 0)
bounce_original(service, bounce, buf, queue_name, queue_id,
STR(boundary),
flush ? BOUNCE_ALL : BOUNCE_HEADERS);
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
* reason for the bounce, and a copy of the original message.
*/
if (bounce_header(bounce, buf, recipient, flush) == 0
&& bounce_boilerplate(bounce, buf, flush) == 0
&& bounce_diagnostics(service, bounce, buf, queue_id) == 0)
if (bounce_header(bounce, buf, recipient, STR(boundary), flush) == 0
&& bounce_boilerplate(bounce, buf, STR(boundary), flush) == 0
&& bounce_diagnostics(service, bounce, buf, queue_id,
STR(boundary)) == 0)
bounce_original(service, bounce, buf, queue_name, queue_id,
STR(boundary),
flush ? BOUNCE_ALL : BOUNCE_HEADERS);
bounce_status = post_mail_fclose(bounce);
}
@@ -407,10 +449,12 @@ int bounce_notify_service(char *service, char *queue_name,
mail_addr_postmaster(),
NULL_CLEANUP_FLAGS,
"BOUNCE")) != 0) {
if (!bounce_header(bounce, buf, mail_addr_postmaster(), flush)
&& bounce_diagnostics(service, bounce, buf, queue_id) == 0)
if (!bounce_header(bounce, buf, mail_addr_postmaster(),
STR(boundary), flush)
&& bounce_diagnostics(service, bounce, buf,
queue_id, STR(boundary)) == 0)
bounce_original(service, bounce, buf, queue_name, queue_id,
BOUNCE_HEADERS);
STR(boundary), BOUNCE_HEADERS);
postmaster_status = post_mail_fclose(bounce);
}
if (postmaster_status)
@@ -432,6 +476,7 @@ int bounce_notify_service(char *service, char *queue_name,
* Cleanup.
*/
vstring_free(buf);
vstring_free(boundary);
return (bounce_status);
}

View File

@@ -15,7 +15,7 @@
* Version of this program.
*/
#define VAR_MAIL_VERSION "mail_version"
#define DEF_MAIL_VERSION "Snapshot-19990402"
#define DEF_MAIL_VERSION "Snapshot-19990405"
extern char *var_mail_version;
/* LICENSE

View File

@@ -497,6 +497,7 @@ static void mail_reset(SMTPD_STATE *state)
mail_stream_cleanup(state->dest);
state->dest = 0;
state->cleanup = 0;
state->err = 0;
}
if (state->queue_id != 0) {
myfree(state->queue_id);

View File

@@ -72,6 +72,7 @@ void mac_parse(const char *value, MAC_PARSE_FN action, char *context)
const char *ep; /* string end pointer */
static char open_paren[] = "({";
static char close_paren[] = ")}";
int level;
#define SKIP(start, var, cond) \
for (var = start; *var && (cond); var++);
@@ -92,12 +93,18 @@ void mac_parse(const char *value, MAC_PARSE_FN action, char *context)
vp += 1;
pp = open_paren;
if (*vp == *pp || *vp == *++pp) { /* ${x} or $(x) */
level = 1;
vp += 1;
SKIP(vp, ep, *ep != close_paren[pp - open_paren]);
if (*ep == 0)
msg_fatal("incomplete macro: %s", value);
vstring_strncat(buf, vp, ep - vp);
vp = ep + 1;
for (ep = vp; level > 0; ep++) {
if (*ep == 0)
msg_fatal("incomplete macro: %s", value);
if (*ep == *pp)
level++;
if (*ep == close_paren[pp - open_paren])
level--;
}
vstring_strncat(buf, vp, ep - vp - 1);
vp = ep;
} else { /* plain $x */
SKIP(vp, ep, ISALNUM(*ep) || *ep == '_');
vstring_strncat(buf, vp, ep - vp);

View File

@@ -134,7 +134,7 @@ int vbuf_unget(VBUF *bp, int ch)
return (VBUF_EOF);
} else {
bp->cnt--;
bp->flags &= ~VBUF_FLAG_ERR;
bp->flags &= ~VBUF_FLAG_EOF;
return (*--bp->ptr = ch);
}
}

View File

@@ -594,6 +594,12 @@ static int vstream_buf_get_ready(VBUF *bp)
if (vstream_fflush_delayed(stream))
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
* 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 {
bp->flags |= VSTREAM_FLAG_SEEK;
}
bp->flags &= ~VSTREAM_FLAG_EOF;
return (stream->offset);
}