diff --git a/postfix/.indent.pro b/postfix/.indent.pro
index 00e85e8cd..1dea5debd 100644
--- a/postfix/.indent.pro
+++ b/postfix/.indent.pro
@@ -22,6 +22,7 @@
-TBOUNCE_LOG_RCPT_BUF
-TBOUNCE_STAT
-TBOUNCE_TEMPLATE
+-TBOUNCE_TEMPLATES
-TBOUNCE_TIME_DIVISOR
-TBOUNCE_TIME_PARAMETER
-TCFG_PARSER
diff --git a/postfix/HISTORY b/postfix/HISTORY
index 57780f515..a2ff4fa23 100644
--- a/postfix/HISTORY
+++ b/postfix/HISTORY
@@ -11394,6 +11394,12 @@ Apologies for any names omitted.
Cleanup: renamed fail_template into failure_template.
+20051117
+
+ Cleanup: bounce template code reorg, no functionality change.
+ Files: bounce/bounce_template.[hc], bounce/bounce_templates.c,
+ bounce/bounce_notify_util.c.
+
Open problems:
"postsuper -r" no longer resets the message arrival time,
diff --git a/postfix/html/postconf.1.html b/postfix/html/postconf.1.html
index 55d8c2cec..0d0de949d 100644
--- a/postfix/html/postconf.1.html
+++ b/postfix/html/postconf.1.html
@@ -217,7 +217,7 @@ POSTCONF(1) POSTCONF(1)
/etc/postfix/main.cf, Postfix configuration parameters
SEE ALSO
- bounce(5), bouce template file format
+ bounce(5), bounce template file format
postconf(5), configuration parameters
README FILES
diff --git a/postfix/man/man1/postconf.1 b/postfix/man/man1/postconf.1
index ee179c3be..05ee5f8d5 100644
--- a/postfix/man/man1/postconf.1
+++ b/postfix/man/man1/postconf.1
@@ -187,7 +187,7 @@ Pathname of a configuration file with bounce message templates.
.SH "SEE ALSO"
.na
.nf
-bounce(5), bouce template file format
+bounce(5), bounce template file format
postconf(5), configuration parameters
.SH "README FILES"
.na
diff --git a/postfix/src/bounce/Makefile.in b/postfix/src/bounce/Makefile.in
index 4a1edaae1..7c2b2febb 100644
--- a/postfix/src/bounce/Makefile.in
+++ b/postfix/src/bounce/Makefile.in
@@ -2,11 +2,11 @@ SHELL = /bin/sh
SRCS = bounce.c bounce_append_service.c bounce_notify_service.c \
bounce_cleanup.c bounce_notify_util.c bounce_notify_verp.c \
bounce_one_service.c bounce_warn_service.c bounce_trace_service.c \
- bounce_template.c dict_ml.c
+ bounce_template.c bounce_templates.c
OBJS = bounce.o bounce_append_service.o bounce_notify_service.o \
bounce_cleanup.o bounce_notify_util.o bounce_notify_verp.o \
bounce_one_service.o bounce_warn_service.o bounce_trace_service.o \
- bounce_template.o dict_ml.o
+ bounce_template.o bounce_templates.o
HDRS =
TESTSRC =
DEFS = -I. -I$(INC_DIR) -D$(SYSTYPE)
@@ -23,11 +23,12 @@ $(PROG): $(OBJS) $(LIBS)
$(CC) $(CFLAGS) -o $@ $(OBJS) $(LIBS) $(SYSLIBS)
# Avoid dependency on installed Postfix.
-../../conf/bounce.cf.default: $(PROG) annotate.pl
+../../conf/bounce.cf.default: $(PROG) annotate.pl main.cf
rm -f $@
- echo queue_directory=. >main.cf
MAIL_CONFIG=. ./$(PROG) -SVzndump_templates | perl annotate.pl >$@
- rm -f main.cf
+
+main.cf:
+ echo queue_directory=. >main.cf
$(OBJS): ../../conf/makedefs.out
@@ -61,12 +62,13 @@ clean:
tidy: clean
# Avoid dependency on installed Postfix.
-template_test: $(PROG)
- echo queue_directory=. >main.cf
- MAIL_CONFIG=. ./$(PROG) -SVzndump_templates >junk
+template_test: $(PROG) main.cf template_test.ref
+ MAIL_CONFIG=. ./$(PROG) -SVzndump_templates >template_test.tmp
+ diff template_test.ref template_test.tmp
MAIL_CONFIG=. ./$(PROG) -SVzndump_templates \
- -o bounce_template_file=junk | diff junk -
- rm -f junk main.cf
+ -o bounce_template_file=template_test.ref > template_test.tmp
+ diff template_test.ref template_test.tmp
+ rm -f template_test.tmp
depend: $(MAKES)
(sed '1,/^# do not edit/!d' Makefile.in; \
@@ -86,6 +88,7 @@ bounce.o: ../../include/dsb_scan.h
bounce.o: ../../include/dsn.h
bounce.o: ../../include/dsn_buf.h
bounce.o: ../../include/iostuff.h
+bounce.o: ../../include/load_file.h
bounce.o: ../../include/mail_addr.h
bounce.o: ../../include/mail_conf.h
bounce.o: ../../include/mail_params.h
@@ -103,6 +106,7 @@ bounce.o: ../../include/vstream.h
bounce.o: ../../include/vstring.h
bounce.o: bounce.c
bounce.o: bounce_service.h
+bounce.o: bounce_template.h
bounce_append_service.o: ../../include/attr.h
bounce_append_service.o: ../../include/bounce_log.h
bounce_append_service.o: ../../include/deliver_flock.h
@@ -125,6 +129,7 @@ bounce_append_service.o: ../../include/vstream.h
bounce_append_service.o: ../../include/vstring.h
bounce_append_service.o: bounce_append_service.c
bounce_append_service.o: bounce_service.h
+bounce_append_service.o: bounce_template.h
bounce_cleanup.o: ../../include/attr.h
bounce_cleanup.o: ../../include/bounce_log.h
bounce_cleanup.o: ../../include/dsn.h
@@ -140,6 +145,7 @@ bounce_cleanup.o: ../../include/vstream.h
bounce_cleanup.o: ../../include/vstring.h
bounce_cleanup.o: bounce_cleanup.c
bounce_cleanup.o: bounce_service.h
+bounce_cleanup.o: bounce_template.h
bounce_notify_service.o: ../../include/attr.h
bounce_notify_service.o: ../../include/bounce.h
bounce_notify_service.o: ../../include/bounce_log.h
@@ -164,6 +170,7 @@ bounce_notify_service.o: ../../include/vstream.h
bounce_notify_service.o: ../../include/vstring.h
bounce_notify_service.o: bounce_notify_service.c
bounce_notify_service.o: bounce_service.h
+bounce_notify_service.o: bounce_template.h
bounce_notify_util.o: ../../include/attr.h
bounce_notify_util.o: ../../include/bounce_log.h
bounce_notify_util.o: ../../include/cleanup_user.h
@@ -200,6 +207,7 @@ bounce_notify_util.o: ../../include/vstream.h
bounce_notify_util.o: ../../include/vstring.h
bounce_notify_util.o: bounce_notify_util.c
bounce_notify_util.o: bounce_service.h
+bounce_notify_util.o: bounce_template.h
bounce_notify_verp.o: ../../include/attr.h
bounce_notify_verp.o: ../../include/bounce.h
bounce_notify_verp.o: ../../include/bounce_log.h
@@ -225,6 +233,7 @@ bounce_notify_verp.o: ../../include/vstream.h
bounce_notify_verp.o: ../../include/vstring.h
bounce_notify_verp.o: bounce_notify_verp.c
bounce_notify_verp.o: bounce_service.h
+bounce_notify_verp.o: bounce_template.h
bounce_one_service.o: ../../include/attr.h
bounce_one_service.o: ../../include/bounce.h
bounce_one_service.o: ../../include/bounce_log.h
@@ -248,34 +257,39 @@ bounce_one_service.o: ../../include/vstream.h
bounce_one_service.o: ../../include/vstring.h
bounce_one_service.o: bounce_one_service.c
bounce_one_service.o: bounce_service.h
-bounce_template.o: ../../include/argv.h
+bounce_one_service.o: bounce_template.h
bounce_template.o: ../../include/attr.h
-bounce_template.o: ../../include/bounce_log.h
-bounce_template.o: ../../include/cleanup_user.h
-bounce_template.o: ../../include/dict.h
-bounce_template.o: ../../include/dsn.h
-bounce_template.o: ../../include/dsn_buf.h
bounce_template.o: ../../include/iostuff.h
bounce_template.o: ../../include/is_header.h
bounce_template.o: ../../include/mac_expand.h
bounce_template.o: ../../include/mac_parse.h
-bounce_template.o: ../../include/mail_addr.h
bounce_template.o: ../../include/mail_conf.h
bounce_template.o: ../../include/mail_params.h
bounce_template.o: ../../include/mail_proto.h
bounce_template.o: ../../include/msg.h
bounce_template.o: ../../include/mymalloc.h
-bounce_template.o: ../../include/post_mail.h
-bounce_template.o: ../../include/rcpt_buf.h
-bounce_template.o: ../../include/recipient_list.h
+bounce_template.o: ../../include/split_at.h
bounce_template.o: ../../include/stringops.h
bounce_template.o: ../../include/sys_defs.h
bounce_template.o: ../../include/vbuf.h
bounce_template.o: ../../include/vstream.h
bounce_template.o: ../../include/vstring.h
-bounce_template.o: bounce_service.h
bounce_template.o: bounce_template.c
-bounce_template.o: dict_ml.h
+bounce_template.o: bounce_template.h
+bounce_templates.o: ../../include/attr.h
+bounce_templates.o: ../../include/iostuff.h
+bounce_templates.o: ../../include/mail_addr.h
+bounce_templates.o: ../../include/mail_proto.h
+bounce_templates.o: ../../include/msg.h
+bounce_templates.o: ../../include/mymalloc.h
+bounce_templates.o: ../../include/stringops.h
+bounce_templates.o: ../../include/sys_defs.h
+bounce_templates.o: ../../include/vbuf.h
+bounce_templates.o: ../../include/vstream.h
+bounce_templates.o: ../../include/vstring.h
+bounce_templates.o: ../../include/vstring_vstream.h
+bounce_templates.o: bounce_template.h
+bounce_templates.o: bounce_templates.c
bounce_trace_service.o: ../../include/attr.h
bounce_trace_service.o: ../../include/bounce_log.h
bounce_trace_service.o: ../../include/cleanup_user.h
@@ -298,6 +312,7 @@ bounce_trace_service.o: ../../include/vbuf.h
bounce_trace_service.o: ../../include/vstream.h
bounce_trace_service.o: ../../include/vstring.h
bounce_trace_service.o: bounce_service.h
+bounce_trace_service.o: bounce_template.h
bounce_trace_service.o: bounce_trace_service.c
bounce_warn_service.o: ../../include/attr.h
bounce_warn_service.o: ../../include/bounce_log.h
@@ -319,16 +334,5 @@ bounce_warn_service.o: ../../include/vbuf.h
bounce_warn_service.o: ../../include/vstream.h
bounce_warn_service.o: ../../include/vstring.h
bounce_warn_service.o: bounce_service.h
+bounce_warn_service.o: bounce_template.h
bounce_warn_service.o: bounce_warn_service.c
-dict_ml.o: ../../include/argv.h
-dict_ml.o: ../../include/dict.h
-dict_ml.o: ../../include/iostuff.h
-dict_ml.o: ../../include/msg.h
-dict_ml.o: ../../include/stringops.h
-dict_ml.o: ../../include/sys_defs.h
-dict_ml.o: ../../include/vbuf.h
-dict_ml.o: ../../include/vstream.h
-dict_ml.o: ../../include/vstring.h
-dict_ml.o: ../../include/vstring_vstream.h
-dict_ml.o: dict_ml.c
-dict_ml.o: dict_ml.h
diff --git a/postfix/src/bounce/bounce.c b/postfix/src/bounce/bounce.c
index 76f410b19..1a19890c7 100644
--- a/postfix/src/bounce/bounce.c
+++ b/postfix/src/bounce/bounce.c
@@ -142,6 +142,7 @@
#include
#include
#include
+#include
/* Global library. */
@@ -160,7 +161,7 @@
/* Application-specific. */
-#include "bounce_service.h"
+#include
/*
* Tunables.
@@ -186,6 +187,11 @@ static VSTRING *dsn_envid;
static VSTRING *verp_delims;
static DSN_BUF *dsn_buf;
+ /*
+ * Templates.
+ */
+BOUNCE_TEMPLATES *bounce_templates;
+
#define STR vstring_str
/* bounce_append_proto - bounce_append server protocol */
@@ -247,7 +253,8 @@ static int bounce_append_proto(char *service_name, VSTREAM *client)
static int bounce_notify_proto(char *service_name, VSTREAM *client,
int (*service) (int, char *, char *, char *,
- char *, char *, char *, int))
+ char *, char *, char *, int,
+ BOUNCE_TEMPLATES *))
{
char *myname = "bounce_notify_proto";
int flags;
@@ -294,7 +301,8 @@ static int bounce_notify_proto(char *service_name, VSTREAM *client,
*/
return (service(flags, service_name, STR(queue_name),
STR(queue_id), STR(encoding),
- STR(sender), STR(dsn_envid), dsn_ret));
+ STR(sender), STR(dsn_envid), dsn_ret,
+ bounce_templates));
}
/* bounce_verp_proto - bounce_notify server protocol, VERP style */
@@ -356,12 +364,13 @@ static int bounce_verp_proto(char *service_name, VSTREAM *client)
msg_warn("request to send VERP-style notification of bounced mail");
return (bounce_notify_service(flags, service_name, STR(queue_name),
STR(queue_id), STR(encoding),
- STR(sender), STR(dsn_envid), dsn_ret));
+ STR(sender), STR(dsn_envid), dsn_ret,
+ bounce_templates));
} else
return (bounce_notify_verp(flags, service_name, STR(queue_name),
STR(queue_id), STR(encoding),
STR(sender), STR(dsn_envid), dsn_ret,
- STR(verp_delims)));
+ STR(verp_delims), bounce_templates));
}
/* bounce_one_proto - bounce_one server protocol */
@@ -427,7 +436,7 @@ static int bounce_one_proto(char *service_name, VSTREAM *client)
*/
return (bounce_one_service(flags, STR(queue_name), STR(queue_id),
STR(encoding), STR(sender), STR(dsn_envid),
- dsn_ret, &rcpt, &dsn));
+ dsn_ret, &rcpt, &dsn, bounce_templates));
}
/* bounce_service - parse bounce command type and delegate */
@@ -495,39 +504,51 @@ static void bounce_service(VSTREAM *client, char *service_name, char **argv)
}
}
+static void load_helper(VSTREAM *stream, void *context)
+{
+ BOUNCE_TEMPLATES *templates = (BOUNCE_TEMPLATES *) context;
+
+ bounce_templates_load(stream, templates);
+}
+
/* pre_jail_init - pre-jail initialization */
-static void pre_jail_init(char *service_name, char **unused_argv)
+static void pre_jail_init(char *unused_name, char **unused_argv)
{
/*
- * Load the alternate message files (if specified) before entering the ch
- * root jail.
+ * Bundle up a bunch of bounce template information.
*/
- if (*var_bounce_tmpl)
- bounce_template_load(var_bounce_tmpl);
+ bounce_templates = bounce_templates_create();
/*
- * Special case: dump bounce templates. This is not part of the
- * master(5) public interface.
+ * Load the alternate message files (if specified) before entering the
+ * chroot jail.
*/
- if (strcmp(service_name, "dump_templates") == 0) {
- bounce_template_dump_all(VSTREAM_OUT);
- vstream_fflush(VSTREAM_OUT);
- exit(0);
- }
- if (strcmp(service_name, "expand_templates") == 0) {
- bounce_template_expand_all(VSTREAM_OUT);
- vstream_fflush(VSTREAM_OUT);
- exit(0);
- }
+ if (*var_bounce_tmpl)
+ load_file(var_bounce_tmpl, load_helper, (char *) bounce_templates);
}
/* post_jail_init - initialize after entering chroot jail */
-static void post_jail_init(char *unused_name, char **unused_argv)
+static void post_jail_init(char *service_name, char **unused_argv)
{
+ /*
+ * Special case: dump bounce templates. This is not part of the master(5)
+ * public interface.
+ */
+ if (strcmp(service_name, "dump_templates") == 0) {
+ bounce_templates_dump(VSTREAM_OUT, bounce_templates);
+ vstream_fflush(VSTREAM_OUT);
+ exit(0);
+ }
+ if (strcmp(service_name, "expand_templates") == 0) {
+ bounce_templates_expand(VSTREAM_OUT, bounce_templates);
+ vstream_fflush(VSTREAM_OUT);
+ exit(0);
+ }
+
/*
* Initialize. We're single threaded so we can reuse some memory upon
* successive requests.
diff --git a/postfix/src/bounce/bounce_notify_service.c b/postfix/src/bounce/bounce_notify_service.c
index 415bdeec4..c02ffb9c3 100644
--- a/postfix/src/bounce/bounce_notify_service.c
+++ b/postfix/src/bounce/bounce_notify_service.c
@@ -7,7 +7,7 @@
/* #include "bounce_service.h"
/*
/* int bounce_notify_service(flags, queue_name, queue_id, encoding,
-/* sender, dsn_envid, dsn_ret)
+/* sender, dsn_envid, dsn_ret, templates)
/* int flags;
/* char *queue_name;
/* char *queue_id;
@@ -15,6 +15,7 @@
/* char *sender;
/* char *dsn_envid;
/* int dsn_ret;
+/* BOUNCE_TEMPLATES *templates;
/* DESCRIPTION
/* This module implements the server side of the bounce_flush()
/* (send bounce message) request.
@@ -83,7 +84,7 @@
int bounce_notify_service(int flags, char *service, char *queue_name,
char *queue_id, char *encoding,
char *recipient, char *dsn_envid,
- int dsn_ret)
+ int dsn_ret, BOUNCE_TEMPLATES *ts)
{
BOUNCE_INFO *bounce_info;
int bounce_status = 1;
@@ -127,7 +128,7 @@ int bounce_notify_service(int flags, char *service, char *queue_name,
* notification is enabled.
*/
bounce_info = bounce_mail_init(service, queue_name, queue_id,
- encoding, dsn_envid, FAIL_TEMPLATE());
+ encoding, dsn_envid, ts->failure);
#define NULL_SENDER MAIL_ADDR_EMPTY /* special address */
#define NULL_TRACE_FLAGS 0
@@ -182,7 +183,8 @@ int bounce_notify_service(int flags, char *service, char *queue_name,
* message. Don't bother sending the boiler-plate text.
*/
count = -1;
- if (bounce_header(bounce, bounce_info, postmaster) == 0
+ if (bounce_header(bounce, bounce_info, postmaster,
+ POSTMASTER_COPY) == 0
&& (count = bounce_diagnostic_log(bounce, bounce_info,
DSN_NOTIFY_OVERRIDE)) > 0
&& bounce_header_dsn(bounce, bounce_info) == 0
@@ -215,7 +217,8 @@ int bounce_notify_service(int flags, char *service, char *queue_name,
* reason for the bounce, and a copy of the original message.
*/
count = -1;
- if (bounce_header(bounce, bounce_info, recipient) == 0
+ if (bounce_header(bounce, bounce_info, recipient,
+ NO_POSTMASTER_COPY) == 0
&& bounce_boilerplate(bounce, bounce_info) == 0
&& (count = bounce_diagnostic_log(bounce, bounce_info,
DSN_NOTIFY_FAILURE)) > 0
@@ -258,7 +261,8 @@ int bounce_notify_service(int flags, char *service, char *queue_name,
CLEANUP_FLAG_MASK_INTERNAL,
NULL_TRACE_FLAGS)) != 0) {
count = -1;
- if (bounce_header(bounce, bounce_info, postmaster) == 0
+ if (bounce_header(bounce, bounce_info, postmaster,
+ POSTMASTER_COPY) == 0
&& (count = bounce_diagnostic_log(bounce, bounce_info,
DSN_NOTIFY_OVERRIDE)) > 0
&& bounce_header_dsn(bounce, bounce_info) == 0
diff --git a/postfix/src/bounce/bounce_notify_util.c b/postfix/src/bounce/bounce_notify_util.c
index fe74aedcf..0078b680c 100644
--- a/postfix/src/bounce/bounce_notify_util.c
+++ b/postfix/src/bounce/bounce_notify_util.c
@@ -22,7 +22,8 @@
/* const BOUNCE_TEMPLATE *template;
/*
/* BOUNCE_INFO *bounce_mail_one_init(queue_name, queue_id, encoding,
-/* dsn_envid, dsn_notify, rcpt, dsn)
+/* dsn_envid, dsn_notify, rcpt, dsn,
+/* template)
/* const char *queue_name;
/* const char *queue_id;
/* const char *encoding;
@@ -30,14 +31,16 @@
/* const char *dsn_envid;
/* RECIPIENT *rcpt;
/* DSN *dsn;
+/* const BOUNCE_TEMPLATE *template;
/*
/* void bounce_mail_free(bounce_info)
/* BOUNCE_INFO *bounce_info;
/*
-/* int bounce_header(fp, bounce_info, recipient)
+/* int bounce_header(fp, bounce_info, recipient, postmaster_copy)
/* VSTREAM *fp;
/* BOUNCE_INFO *bounce_info;
/* const char *recipient;
+/* int postmaster_copy;
/*
/* int bounce_boilerplate(fp, bounce_info)
/* VSTREAM *fp;
@@ -86,15 +89,15 @@
/* undeliverable message.
/*
/* bounce_mail_one_init() provides the same function for only
-/* one recipient that is not read from bounce logfile. It
-/* assumes a template type of FAIL_TEMPLATE().
+/* one recipient that is not read from bounce logfile.
/*
/* bounce_mail_free() releases memory allocated by bounce_mail_init()
/* and closes any files opened by bounce_mail_init().
/*
/* bounce_header() produces a standard mail header with the specified
/* recipient and starts a text/plain message segment for the
-/* human-readable problem description.
+/* human-readable problem description. postmaster_copy is either
+/* POSTMASTER_COPY or NO_POSTMASTER_COPY.
/*
/* bounce_boilerplate() produces the standard "sorry" text that
/* creates the illusion that mail systems are civilized.
@@ -208,7 +211,7 @@ static BOUNCE_INFO *bounce_mail_alloc(const char *service,
const char *queue_id,
const char *encoding,
const char *dsn_envid,
- const BOUNCE_TEMPLATE *template,
+ BOUNCE_TEMPLATE *template,
BOUNCE_LOG *log_handle)
{
BOUNCE_INFO *bounce_info;
@@ -324,7 +327,7 @@ BOUNCE_INFO *bounce_mail_init(const char *service,
const char *queue_id,
const char *encoding,
const char *dsn_envid,
- const BOUNCE_TEMPLATE *template)
+ BOUNCE_TEMPLATE *template)
{
BOUNCE_INFO *bounce_info;
BOUNCE_LOG *log_handle;
@@ -352,7 +355,8 @@ BOUNCE_INFO *bounce_mail_one_init(const char *queue_name,
const char *encoding,
const char *dsn_envid,
RECIPIENT *rcpt,
- DSN *dsn)
+ DSN *dsn,
+ BOUNCE_TEMPLATE *template)
{
BOUNCE_INFO *bounce_info;
BOUNCE_LOG *log_handle;
@@ -363,7 +367,7 @@ BOUNCE_INFO *bounce_mail_one_init(const char *queue_name,
*/
log_handle = bounce_log_forge(rcpt, dsn);
bounce_info = bounce_mail_alloc("none", queue_name, queue_id, encoding,
- dsn_envid, FAIL_TEMPLATE(), log_handle);
+ dsn_envid, template, log_handle);
return (bounce_info);
}
@@ -388,10 +392,9 @@ void bounce_mail_free(BOUNCE_INFO *bounce_info)
/* bounce_header - generate bounce message header */
int bounce_header(VSTREAM *bounce, BOUNCE_INFO *bounce_info,
- const char *dest)
+ const char *dest, int postmaster_copy)
{
- const BOUNCE_TEMPLATE *template = bounce_info->template;
- int postmaster_copy;
+ BOUNCE_TEMPLATE *template = bounce_info->template;
/*
* Print a minimal bounce header. The cleanup service will add other
@@ -399,22 +402,12 @@ int bounce_header(VSTREAM *bounce, BOUNCE_INFO *bounce_info,
*/
#define STREQ(a, b) (strcasecmp((a), (b)) == 0)
- /*
- * XXX This should be caller specified.
- */
- postmaster_copy =
- (template->postmaster_subject != 0
- && (dest == var_bounce_rcpt || dest == var_2bounce_rcpt
- || dest == var_delay_rcpt));
-
/*
* Generic headers.
*/
- post_mail_fprintf(bounce, "From: %s", template->from);
- post_mail_fprintf(bounce, "Subject: %s", postmaster_copy ?
- template->postmaster_subject : template->subject);
- post_mail_fprintf(bounce, "To: %s",
- STR(quote_822_local(bounce_info->buf, dest)));
+ bounce_template_headers(post_mail_fprintf, bounce, template,
+ STR(quote_822_local(bounce_info->buf, dest)),
+ postmaster_copy);
/*
* MIME header. Use 8bit encoding when either the bounced message or the
@@ -427,7 +420,8 @@ int bounce_header(VSTREAM *bounce, BOUNCE_INFO *bounce_info,
if (bounce_info->mime_encoding)
post_mail_fprintf(bounce, "Content-Transfer-Encoding: %s",
STREQ(bounce_info->mime_encoding, MAIL_ATTR_ENC_7BIT) ?
- template->mime_encoding : bounce_info->mime_encoding);
+ bounce_template_encoding(template) :
+ bounce_info->mime_encoding);
post_mail_fputs(bounce, "");
post_mail_fputs(bounce, "This is a MIME-encapsulated message.");
@@ -438,7 +432,7 @@ int bounce_header(VSTREAM *bounce, BOUNCE_INFO *bounce_info,
post_mail_fprintf(bounce, "--%s", bounce_info->mime_boundary);
post_mail_fprintf(bounce, "Content-Description: %s", "Notification");
post_mail_fprintf(bounce, "Content-Type: %s; charset=%s",
- "text/plain", template->charset);
+ "text/plain", bounce_template_charset(template));
post_mail_fputs(bounce, "");
return (vstream_ferror(bounce));
@@ -525,7 +519,7 @@ int bounce_diagnostic_log(VSTREAM *bounce, BOUNCE_INFO *bounce_info,
*/
if (bounce_info->log_handle == 0
|| bounce_log_rewind(bounce_info->log_handle)) {
- if (IS_FAIL_TEMPLATE(bounce_info->template)) {
+ if (IS_FAILURE_TEMPLATE(bounce_info->template)) {
post_mail_fputs(bounce, "\t--- Delivery report unavailable ---");
count = 1; /* XXX don't abort */
}
@@ -617,7 +611,7 @@ int bounce_recipient_dsn(VSTREAM *bounce, BOUNCE_INFO *bounce_info)
bounce_info->log_handle->rcpt.orig_addr);
}
post_mail_fprintf(bounce, "Action: %s",
- IS_FAIL_TEMPLATE(bounce_info->template) ?
+ IS_FAILURE_TEMPLATE(bounce_info->template) ?
"failed" : bounce_info->log_handle->dsn.action);
post_mail_fprintf(bounce, "Status: %s",
bounce_info->log_handle->dsn.status);
@@ -663,7 +657,7 @@ int bounce_diagnostic_dsn(VSTREAM *bounce, BOUNCE_INFO *bounce_info,
*/
if (bounce_info->log_handle == 0
|| bounce_log_rewind(bounce_info->log_handle)) {
- if (IS_FAIL_TEMPLATE(bounce_info->template))
+ if (IS_FAILURE_TEMPLATE(bounce_info->template))
count = 1; /* XXX don't abort */
} else {
while (bounce_log_read(bounce_info->log_handle) != 0) {
@@ -700,7 +694,7 @@ int bounce_original(VSTREAM *bounce, BOUNCE_INFO *bounce_info,
* MIME headers.
*/
#define IS_UNDELIVERED_TEMPLATE(template) \
- (IS_FAIL_TEMPLATE(template) || IS_DELAY_TEMPLATE(template))
+ (IS_FAILURE_TEMPLATE(template) || IS_DELAY_TEMPLATE(template))
post_mail_fputs(bounce, "");
post_mail_fprintf(bounce, "--%s", bounce_info->mime_boundary);
diff --git a/postfix/src/bounce/bounce_notify_verp.c b/postfix/src/bounce/bounce_notify_verp.c
index 2c938be8d..e1f69dc01 100644
--- a/postfix/src/bounce/bounce_notify_verp.c
+++ b/postfix/src/bounce/bounce_notify_verp.c
@@ -7,7 +7,8 @@
/* #include "bounce_service.h"
/*
/* int bounce_notify_verp(flags, service, queue_name, queue_id, sender,
-/* dsn_envid, dsn_ret, verp_delims)
+/* dsn_envid, dsn_ret, verp_delims,
+/* templates)
/* int flags;
/* char *queue_name;
/* char *queue_id;
@@ -15,6 +16,7 @@
/* char *dsn_envid;
/* int dsn_ret;
/* char *verp_delims;
+/* BOUNCE_TEMPLATES *templates;
/* DESCRIPTION
/* This module implements the server side of the bounce_notify()
/* (send bounce message) request. The logfile
@@ -84,7 +86,8 @@
int bounce_notify_verp(int flags, char *service, char *queue_name,
char *queue_id, char *encoding,
char *recipient, char *dsn_envid,
- int dsn_ret, char *verp_delims)
+ int dsn_ret, char *verp_delims,
+ BOUNCE_TEMPLATES *ts)
{
char *myname = "bounce_notify_verp";
BOUNCE_INFO *bounce_info;
@@ -109,7 +112,7 @@ int bounce_notify_verp(int flags, char *service, char *queue_name,
* Initialize. Open queue file, bounce log, etc.
*/
bounce_info = bounce_mail_init(service, queue_name, queue_id,
- encoding, dsn_envid, FAIL_TEMPLATE());
+ encoding, dsn_envid, ts->failure);
#define NULL_SENDER MAIL_ADDR_EMPTY /* special address */
#define NULL_TRACE_FLAGS 0
@@ -138,7 +141,8 @@ int bounce_notify_verp(int flags, 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, bounce_info, STR(verp_buf)) == 0
+ if (bounce_header(bounce, bounce_info, STR(verp_buf),
+ NO_POSTMASTER_COPY) == 0
&& bounce_boilerplate(bounce, bounce_info) == 0
&& bounce_recipient_log(bounce, bounce_info) == 0
&& bounce_header_dsn(bounce, bounce_info) == 0
@@ -186,7 +190,8 @@ int bounce_notify_verp(int flags, char *service, char *queue_name,
postmaster,
CLEANUP_FLAG_MASK_INTERNAL,
NULL_TRACE_FLAGS)) != 0) {
- if (bounce_header(bounce, bounce_info, postmaster) == 0
+ if (bounce_header(bounce, bounce_info, postmaster,
+ POSTMASTER_COPY) == 0
&& bounce_recipient_log(bounce, bounce_info) == 0
&& bounce_header_dsn(bounce, bounce_info) == 0
&& bounce_recipient_dsn(bounce, bounce_info) == 0)
diff --git a/postfix/src/bounce/bounce_one_service.c b/postfix/src/bounce/bounce_one_service.c
index 45e42c00e..d6355afba 100644
--- a/postfix/src/bounce/bounce_one_service.c
+++ b/postfix/src/bounce/bounce_one_service.c
@@ -8,7 +8,7 @@
/*
/* int bounce_one_service(flags, queue_name, queue_id, encoding,
/* orig_sender, envid, ret,
-/* rcpt, dsn)
+/* rcpt, dsn, templates)
/* int flags;
/* char *queue_name;
/* char *queue_id;
@@ -18,6 +18,7 @@
/* int ret;
/* RECIPIENT *rcpt;
/* DSN *dsn;
+/* BOUNCE_TEMPLATES *templates;
/* DESCRIPTION
/* This module implements the server side of the bounce_one()
/* (send bounce message for one recipient) request.
@@ -85,7 +86,8 @@
int bounce_one_service(int flags, char *queue_name, char *queue_id,
char *encoding, char *orig_sender,
char *dsn_envid, int dsn_ret,
- RECIPIENT *rcpt, DSN *dsn)
+ RECIPIENT *rcpt, DSN *dsn,
+ BOUNCE_TEMPLATES *ts)
{
BOUNCE_INFO *bounce_info;
int bounce_status = 1;
@@ -98,7 +100,7 @@ int bounce_one_service(int flags, char *queue_name, char *queue_id,
* Initialize. Open queue file, bounce log, etc.
*/
bounce_info = bounce_mail_one_init(queue_name, queue_id, encoding,
- dsn_envid, rcpt, dsn);
+ dsn_envid, rcpt, dsn, ts->failure);
#define NULL_SENDER MAIL_ADDR_EMPTY /* special address */
#define NULL_TRACE_FLAGS 0
@@ -152,7 +154,8 @@ int bounce_one_service(int flags, char *queue_name, char *queue_id,
* reason for the bounce, and the headers of the original
* message. Don't bother sending the boiler-plate text.
*/
- if (!bounce_header(bounce, bounce_info, var_2bounce_rcpt)
+ if (!bounce_header(bounce, bounce_info, var_2bounce_rcpt,
+ POSTMASTER_COPY)
&& bounce_recipient_log(bounce, bounce_info) == 0
&& bounce_header_dsn(bounce, bounce_info) == 0
&& bounce_recipient_dsn(bounce, bounce_info) == 0)
@@ -180,7 +183,8 @@ int bounce_one_service(int flags, char *queue_name, char *queue_id,
* 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, bounce_info, orig_sender) == 0
+ if (bounce_header(bounce, bounce_info, orig_sender,
+ NO_POSTMASTER_COPY) == 0
&& bounce_boilerplate(bounce, bounce_info) == 0
&& bounce_recipient_log(bounce, bounce_info) == 0
&& bounce_header_dsn(bounce, bounce_info) == 0
@@ -214,7 +218,8 @@ int bounce_one_service(int flags, char *queue_name, char *queue_id,
var_bounce_rcpt,
CLEANUP_FLAG_MASK_INTERNAL,
NULL_TRACE_FLAGS)) != 0) {
- if (bounce_header(bounce, bounce_info, var_bounce_rcpt) == 0
+ if (bounce_header(bounce, bounce_info, var_bounce_rcpt,
+ POSTMASTER_COPY) == 0
&& bounce_recipient_log(bounce, bounce_info) == 0
&& bounce_header_dsn(bounce, bounce_info) == 0
&& bounce_recipient_dsn(bounce, bounce_info) == 0)
diff --git a/postfix/src/bounce/bounce_service.h b/postfix/src/bounce/bounce_service.h
index 9a5111609..fb3af89c7 100644
--- a/postfix/src/bounce/bounce_service.h
+++ b/postfix/src/bounce/bounce_service.h
@@ -18,6 +18,11 @@
*/
#include
+ /*
+ * Application-specific.
+ */
+#include
+
/*
* bounce_append_service.c
*/
@@ -26,27 +31,27 @@ extern int bounce_append_service(int, char *, char *, RECIPIENT_VAR *, DSN_VAR *
/*
* bounce_notify_service.c
*/
-extern int bounce_notify_service(int, char *, char *, char *, char *, char *, char *, int);
+extern int bounce_notify_service(int, char *, char *, char *, char *, char *, char *, int, BOUNCE_TEMPLATES *);
/*
* bounce_warn_service.c
*/
-extern int bounce_warn_service(int, char *, char *, char *, char *, char *, char *, int);
+extern int bounce_warn_service(int, char *, char *, char *, char *, char *, char *, int, BOUNCE_TEMPLATES *);
/*
* bounce_trace_service.c
*/
-extern int bounce_trace_service(int, char *, char *, char *, char *, char *, char *, int);
+extern int bounce_trace_service(int, char *, char *, char *, char *, char *, char *, int, BOUNCE_TEMPLATES *);
/*
* bounce_notify_verp.c
*/
-extern int bounce_notify_verp(int, char *, char *, char *, char *, char *, char *, int, char *);
+extern int bounce_notify_verp(int, char *, char *, char *, char *, char *, char *, int, char *, BOUNCE_TEMPLATES *);
/*
* bounce_one_service.c
*/
-extern int bounce_one_service(int, char *, char *, char *, char *, char *, int, RECIPIENT *, DSN *);
+extern int bounce_one_service(int, char *, char *, char *, char *, char *, int, RECIPIENT *, DSN *, BOUNCE_TEMPLATES *);
/*
* bounce_cleanup.c
@@ -58,80 +63,6 @@ extern void bounce_cleanup_unregister(void);
#define bounce_cleanup_registered() (bounce_cleanup_path != 0)
- /*
- * bounce_template.c
- */
-typedef struct {
- const char *class; /* for diagnostics (fixed) */
- const char *charset; /* character set (configurable) */
- const char *mime_encoding; /* 7bit or 8bit (derived) */
- const char *from; /* originator (configurable) */
- const char *subject; /* general subject (configurable) */
- const char *postmaster_subject; /* postmaster subject (configurable) */
- const char **message_text; /* message text (configurable) */
-} BOUNCE_TEMPLATE;
-
-typedef int (*BOUNCE_OUT_FN)(VSTREAM *, const char *);
-extern void bounce_template_load(const char *);
-extern void bounce_template_expand(BOUNCE_OUT_FN, VSTREAM *, const BOUNCE_TEMPLATE *);
-extern const BOUNCE_TEMPLATE *bounce_template_find(const char *, const BOUNCE_TEMPLATE *);
-extern void bounce_template_dump_all(VSTREAM *);
-extern void bounce_template_expand_all(VSTREAM *);
-
-#define BOUNCE_TMPL_CLASS_FAIL "failure"
-#define BOUNCE_TMPL_CLASS_DELAY "delay"
-#define BOUNCE_TMPL_CLASS_SUCCESS "success"
-#define BOUNCE_TMPL_CLASS_VERIFY "verify"
-
-#define BOUNCE_TEMPLATE_DICT "bounce_templates"
-#define BOUNCE_TMPL_DICT_FAIL (BOUNCE_TMPL_CLASS_FAIL "_template")
-#define BOUNCE_TMPL_DICT_DELAY (BOUNCE_TMPL_CLASS_DELAY "_template")
-#define BOUNCE_TMPL_DICT_SUCCESS (BOUNCE_TMPL_CLASS_SUCCESS "_template")
-#define BOUNCE_TMPL_DICT_VERIFY (BOUNCE_TMPL_CLASS_VERIFY "_template")
-
-#define FAIL_TEMPLATE() \
- (bounce_fail_template ? bounce_fail_template : \
- (bounce_fail_template = \
- bounce_template_find(BOUNCE_TMPL_DICT_FAIL, \
- &def_bounce_fail_template)))
-
-#define DELAY_TEMPLATE() \
- (bounce_delay_template ? bounce_delay_template : \
- (bounce_delay_template = \
- bounce_template_find(BOUNCE_TMPL_DICT_DELAY, \
- &def_bounce_delay_template)))
-
-#define SUCCESS_TEMPLATE() \
- (bounce_success_template ? bounce_success_template : \
- (bounce_success_template = \
- bounce_template_find(BOUNCE_TMPL_DICT_SUCCESS, \
- &def_bounce_success_template)))
-
-#define VERIFY_TEMPLATE() \
- (bounce_verify_template ? bounce_verify_template : \
- (bounce_verify_template = \
- bounce_template_find(BOUNCE_TMPL_DICT_VERIFY, \
- &def_bounce_verify_template)))
-
-#define IS_FAIL_TEMPLATE(t) ((t) == bounce_fail_template)
-#define IS_DELAY_TEMPLATE(t) ((t) == bounce_delay_template)
-#define IS_SUCCESS_TEMPLATE(t) ((t) == bounce_success_template)
-#define IS_VERIFY_TEMPLATE(t) ((t) == bounce_verify_template)
-
- /*
- * The following are not part of the bounce_template() interface. Use the
- * above macros instead.
- */
-extern const BOUNCE_TEMPLATE *bounce_fail_template;
-extern const BOUNCE_TEMPLATE *bounce_delay_template;
-extern const BOUNCE_TEMPLATE *bounce_success_template;
-extern const BOUNCE_TEMPLATE *bounce_verify_template;
-
-extern const BOUNCE_TEMPLATE def_bounce_fail_template;
-extern const BOUNCE_TEMPLATE def_bounce_delay_template;
-extern const BOUNCE_TEMPLATE def_bounce_success_template;
-extern const BOUNCE_TEMPLATE def_bounce_verify_template;
-
/*
* bounce_notify_util.c
*/
@@ -142,7 +73,7 @@ typedef struct {
const char *mime_encoding; /* null or encoding */
const char *dsn_envid; /* DSN envelope ID */
const char *mime_boundary; /* for MIME */
- const BOUNCE_TEMPLATE *template; /* see above */
+ BOUNCE_TEMPLATE *template; /* bounce message template */
VSTRING *buf; /* scratch pad */
VSTRING *sender; /* envelope sender */
VSTREAM *orig_fp; /* open queue file */
@@ -155,10 +86,10 @@ typedef struct {
/* */
-extern BOUNCE_INFO *bounce_mail_init(const char *, const char *, const char *, const char *, const char *, const BOUNCE_TEMPLATE *);
-extern BOUNCE_INFO *bounce_mail_one_init(const char *, const char *, const char *, const char *, RECIPIENT *, DSN *);
+extern BOUNCE_INFO *bounce_mail_init(const char *, const char *, const char *, const char *, const char *, BOUNCE_TEMPLATE *);
+extern BOUNCE_INFO *bounce_mail_one_init(const char *, const char *, const char *, const char *, RECIPIENT *, DSN *, BOUNCE_TEMPLATE *);
extern void bounce_mail_free(BOUNCE_INFO *);
-extern int bounce_header(VSTREAM *, BOUNCE_INFO *, const char *);
+extern int bounce_header(VSTREAM *, BOUNCE_INFO *, const char *, int);
extern int bounce_boilerplate(VSTREAM *, BOUNCE_INFO *);
extern int bounce_recipient_log(VSTREAM *, BOUNCE_INFO *);
extern int bounce_diagnostic_log(VSTREAM *, BOUNCE_INFO *, int);
diff --git a/postfix/src/bounce/bounce_template.c b/postfix/src/bounce/bounce_template.c
index 619cf6ebe..029c41a7b 100644
--- a/postfix/src/bounce/bounce_template.c
+++ b/postfix/src/bounce/bounce_template.c
@@ -2,61 +2,90 @@
/* NAME
/* bounce_template 3
/* SUMMARY
-/* bounce template processing
+/* bounce template support
/* SYNOPSIS
-/* #include "bounce_service.h"
+/* #include
/*
-/* void bounce_template_load(path)
-/* const char *path;
+/* BOUNCE_TEMPLATE *bounce_template_create(def_template)
+/* const BOUNCE_TEMPLATE *def_template;
/*
-/* const BOUNCE_TEMPLATE *FAIL_TEMPLATE()
+/* void bounce_template_free(template)
+/* BOUNCE_TEMPLATE *template;
/*
-/* const BOUNCE_TEMPLATE *DELAY_TEMPLATE()
+/* void bounce_template_load(stream, buffer, origin)
+/* VSTREAM *stream;
+/* const char *buffer;
+/* const char *origin;
/*
-/* const BOUNCE_TEMPLATE *SUCCESS_TEMPLATE()
-/*
-/* const BOUNCE_TEMPLATE *VERIFY_TEMPLATE()
-/*
-/* void bounce_template_expand(stream, template)
+/* void bounce_template_headers(out_fn, stream, template,
+/* rcpt, postmaster_copy)
+/* int (*out_fn)(VSTREAM *, const char *, ...);
/* VSTREAM *stream;
/* BOUNCE_TEMPLATE *template;
-/* AUXILIARY FUNCTIONS
-/* void bounce_template_dump_all(stream)
-/* VSTREAM *stream;
+/* const char *rcpt;
+/* int postmaster_copy;
/*
-/* void bounce_template_expand_all(stream)
+/* const char *bounce_template_encoding(template)
+/* BOUNCE_TEMPLATE *template;
+/*
+/* const char *bounce_template_charset(template)
+/* BOUNCE_TEMPLATE *template;
+/*
+/* void bounce_template_expand(out_fn, stream, template)
+/* int (*out_fn)(VSTREAM *, const char *);
/* VSTREAM *stream;
+/* BOUNCE_TEMPLATE *template;
+/*
+/* void bounce_template_dump(stream, template)
+/* VSTREAM *stream;
+/* BOUNCE_TEMPLATE *template;
+/*
+/* int IS_FAILURE_TEMPLATE(template)
+/* int IS_DELAY_TEMPLATE(template)
+/* int IS_SUCCESS_TEMPLATE(template)
+/* int IS_VERIFY_TEMPLATE(template)
+/* BOUNCE_TEMPLATE *template;
/* DESCRIPTION
/* This module implements the built-in and external bounce
/* message template support.
/*
-/* bounce_template_load() reads bounce templates from the
-/* specified file.
+/* bounce_template_create() creates a template, with the
+/* specified default settings. The template defaults are not
+/* copied.
/*
-/* FAIL_TEMPLATE() etc. look up the corresponding bounce
-/* template from file, or use a built-in template when no
-/* template was specified externally.
+/* bounce_template_free() destroys a bounce message template.
+/*
+/* bounce_template_load() reads a bounce template from the
+/* specified buffer with the specified origin. The buffer and
+/* origin are copied. Specify a null buffer and origin pointer
+/* to reset the template to the defaults specified with
+/* bounce_template_create().
+/*
+/* bounce_template_headers() sends the postmaster or non-postmaster
+/* From/Subject/To message headers to the specified stream.
+/* The recipient address is expected to be in RFC822 external
+/* form. The postmaster_copy argument is one of POSTMASTER_COPY
+/* or NO_POSTMASTER_COPY.
+/*
+/* bounce_template_encoding() returns the encoding (MAIL_ATTR_ENC_7BIT
+/* or MAIL_ATTR_ENC_8BIT) for the bounce template message text.
+/*
+/* bounce_template_charset() returns the character set for the
+/* bounce template message text.
/*
/* bounce_template_expand() expands the body text of the
/* specified template and writes the result to the specified
-/* queue file record stream.
+/* stream.
/*
-/* bounce_template_dump_default() dumps the built-in default templates
-/* to the specified stream. This can be used to generate input
-/* for the default bounce service configuration file.
+/* bounce_template_dump() dumps the specified template to the
+/* specified stream.
/*
-/* bounce_template_dump_actual() dumps the actually-used templates
-/* to the specified stream. This can be used to verify that
-/* the bounce server correctly reads its own bounce_template_dump_default()
-/* output.
-/*
-/* bounce_template_expand_actual() expands the template message
-/* text and dumps the result to the specified stream. This can
-/* be used to verify that templates produce the desired text.
+/* The IS_MUMBLE_TEMPLATE() macros are predicates that
+/* return when the template is of the specified type.
/* DIAGNOSTICS
-/* Fatal error: error opening template file, out of memory,
-/* undefined macro name in template.
-/* BUGS
+/* Fatal error: out of memory, undefined macro name in template.
+/* SEE ALSO
+/* bounce_templates(3) bounce template group support
/* LICENSE
/* .ad
/* .fi
@@ -85,146 +114,17 @@
#include
#include
#include
-#include
/* Global library. */
#include
-#include
-#include
-#include
-#include
#include
+#include
+#include
/* Application-specific. */
-#include
-
- /*
- * The fail template is for permanent failure.
- */
-static const char *def_bounce_fail_body[];
-
-const BOUNCE_TEMPLATE def_bounce_fail_template = {
- BOUNCE_TMPL_CLASS_FAIL,
- "us-ascii",
- MAIL_ATTR_ENC_7BIT,
- MAIL_ADDR_MAIL_DAEMON " (Mail Delivery System)",
- "Undelivered Mail Returned to Sender",
- "Postmaster Copy: Undelivered Mail",
- def_bounce_fail_body,
-};
-
-static const char *def_bounce_fail_body[] = {
- "This is the $mail_name program at host $myhostname.",
- "",
- "I'm sorry to have to inform you that your message could not",
- "be delivered to one or more recipients. It's attached below.",
- "",
- "For further assistance, please send mail to <" MAIL_ADDR_POSTMASTER ">",
- "",
- "If you do so, please include this problem report. You can",
- "delete your own text from the attached returned message.",
- "",
- " The $mail_name program",
- 0,
-};
-
- /*
- * The delay template is for delayed mail notifications.
- */
-static const char *def_bounce_delay_body[];
-
-const BOUNCE_TEMPLATE def_bounce_delay_template = {
- BOUNCE_TMPL_CLASS_DELAY,
- "us-ascii",
- MAIL_ATTR_ENC_7BIT,
- MAIL_ADDR_MAIL_DAEMON " (Mail Delivery System)",
- "Delayed Mail (still being retried)",
- "Postmaster Warning: Delayed Mail",
- def_bounce_delay_body,
-};
-
-static const char *def_bounce_delay_body[] = {
- "This is the $mail_name program at host $myhostname.",
- "",
- "####################################################################",
- "# THIS IS A WARNING ONLY. YOU DO NOT NEED TO RESEND YOUR MESSAGE. #",
- "####################################################################",
- "",
- "Your message could not be delivered for $delay_warning_time_hours hour(s).",
- "It will be retried until it is $maximal_queue_lifetime_days day(s) old.",
- "",
- "For further assistance, please send mail to <" MAIL_ADDR_POSTMASTER ">",
- "",
- "If you do so, please include this problem report. You can",
- "delete your own text from the attached returned message.",
- "",
- " The $mail_name program",
- 0,
-};
-
- /*
- * The success template is for "delivered", "expanded" and "relayed" success
- * notifications.
- */
-static const char *def_bounce_success_body[];
-
-const BOUNCE_TEMPLATE def_bounce_success_template = {
- BOUNCE_TMPL_CLASS_SUCCESS,
- "us-ascii",
- MAIL_ATTR_ENC_7BIT,
- MAIL_ADDR_MAIL_DAEMON " (Mail Delivery System)",
- "Successful Mail Delivery Report",
- 0,
- def_bounce_success_body,
-};
-
-static const char *def_bounce_success_body[] = {
- "This is the $mail_name program at host $myhostname.",
- "",
- "Your message was successfully delivered to the destination(s)",
- "listed below. If the message was delivered to mailbox you will",
- "receive no further notifications. Otherwise you may still receive",
- "notifications of mail delivery errors from other systems.",
- "",
- " The $mail_name program",
- 0,
-};
-
- /*
- * The "verify" template is for verbose delivery (sendmail -v) and for
- * address verification (sendmail -bv).
- */
-static const char *def_bounce_verify_body[];
-
-const BOUNCE_TEMPLATE def_bounce_verify_template = {
- BOUNCE_TMPL_CLASS_VERIFY,
- "us-ascii",
- MAIL_ATTR_ENC_7BIT,
- MAIL_ADDR_MAIL_DAEMON " (Mail Delivery System)",
- "Mail Delivery Status Report",
- 0,
- def_bounce_verify_body,
-};
-
-static const char *def_bounce_verify_body[] = {
- "This is the $mail_name program at host $myhostname.",
- "",
- "Enclosed is the mail delivery report that you requested.",
- "",
- " The $mail_name program",
- 0,
-};
-
- /*
- * Pointers, so that we can override a built-in template with one from file
- * without clobbering the built-in template.
- */
-const BOUNCE_TEMPLATE *bounce_fail_template;
-const BOUNCE_TEMPLATE *bounce_delay_template;
-const BOUNCE_TEMPLATE *bounce_success_template;
-const BOUNCE_TEMPLATE *bounce_verify_template;
+#include
/*
* The following tables implement support for bounce template expansions of
@@ -300,108 +200,61 @@ static BOUNCE_TIME_PARAMETER time_parameter[] = {
*/
#define STR(x) vstring_str(x)
-/* bounce_template_lookup - lookup $name value */
+/* bounce_template_create - create one template */
-static const char *bounce_template_lookup(const char *key, int unused_mode,
- char *context)
-{
- BOUNCE_TEMPLATE *template = (BOUNCE_TEMPLATE *) context;
- BOUNCE_TIME_PARAMETER *bp;
- BOUNCE_TIME_DIVISOR *bd;
- static VSTRING *buf;
- int result;
-
- /*
- * Look for parameter names that can have a time unit suffix, and scale
- * the time value according to the suffix.
- */
- for (bp = time_parameter; bp->param_name; bp++) {
- if (strncmp(key, bp->param_name, bp->param_name_len) == 0
- && key[bp->param_name_len] == '_') {
- for (bd = time_divisors; bd->suffix; bd++) {
- if (strcmp(key + bp->param_name_len + 1, bd->suffix) == 0) {
- result = bp->value[0] / bd->divisor;
- if (result > 999 && bd->divisor < 86400) {
- msg_warn("%s: excessive result \"%d\" in %s "
- "template conversion of parameter \"%s\"",
- *var_bounce_tmpl ? var_bounce_tmpl : "[built-in]",
- result, template->class, key);
- msg_warn("please increase time unit \"%s\" of \"%s\" "
- "in %s template", bd->suffix, key,
- template->class);
- } else if (result == 0 && bp->value[0] && bd->divisor > 1) {
- msg_warn("%s: zero result in %s template "
- "conversion of parameter \"%s\"",
- *var_bounce_tmpl ? var_bounce_tmpl : "[built-in]",
- template->class, key);
- msg_warn("please reduce time unit \"%s\" of \"%s\" "
- "in %s template", bd->suffix, key,
- template->class);
- }
- if (buf == 0)
- buf = vstring_alloc(10);
- vstring_sprintf(buf, "%d", result);
- return (STR(buf));
- }
- }
- msg_fatal("%s: unrecognized suffix \"%s\" in parameter \"%s\"",
- *var_bounce_tmpl ? var_bounce_tmpl : "[built-in]",
- key + bp->param_name_len + 1, key);
- }
- }
- return (mail_conf_lookup_eval(key));
-}
-
-/* bounce_template_expand - expand template body */
-
-void bounce_template_expand(BOUNCE_OUT_FN out_fn, VSTREAM *stream,
- const BOUNCE_TEMPLATE *template)
-{
- VSTRING *buf = vstring_alloc(100);
- const char **cpp;
- int stat;
- const char *filter = "\t !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~";
-
-#define NO_CONTEXT ((char *) 0)
-
- for (cpp = template->message_text; *cpp; cpp++) {
- stat = mac_expand(buf, *cpp, MAC_EXP_FLAG_NONE, filter,
- bounce_template_lookup, (char *) template);
- if (stat & MAC_PARSE_ERROR)
- msg_fatal("%s: bad $name syntax in %s template: %s",
- *var_bounce_tmpl ? var_bounce_tmpl : "[built-in]",
- template->class, *cpp);
- if (stat & MAC_PARSE_UNDEF)
- msg_fatal("%s: undefined $name in %s template: %s",
- *var_bounce_tmpl ? var_bounce_tmpl : "[built-in]",
- template->class, *cpp);
- out_fn(stream, STR(buf));
- }
- vstring_free(buf);
-}
-
-/* bounce_template_load - load template(s) from file */
-
-void bounce_template_load(const char *path)
-{
- static int once = 0;
-
- /*
- * Split the input stream into chunks between begin/end markers, ignoring
- * comment lines.
- */
- if (once++ > 0)
- msg_panic("bounce_template_load: multiple calls");
- dict_ml_load_file(BOUNCE_TEMPLATE_DICT, path);
-}
-
-/* bounce_template_find - return default or user-specified template */
-
-const BOUNCE_TEMPLATE *bounce_template_find(const char *template_name,
- const BOUNCE_TEMPLATE *def_template)
+BOUNCE_TEMPLATE *bounce_template_create(const BOUNCE_TEMPLATE *prototype)
{
BOUNCE_TEMPLATE *tp;
- char *tval;
+
+ tp = (BOUNCE_TEMPLATE *) mymalloc(sizeof(*tp));
+ *tp = *prototype;
+ return (tp);
+}
+
+/* bounce_template_free - destroy one template */
+
+void bounce_template_free(BOUNCE_TEMPLATE *tp)
+{
+ if (tp->buffer) {
+ myfree(tp->buffer);
+ myfree((char *) tp->origin);
+ }
+ myfree((char *) tp);
+}
+
+/* bounce_template_load - override one template */
+
+void bounce_template_load(BOUNCE_TEMPLATE *tp, const char *origin,
+ const char *buffer)
+{
+
+ /*
+ * Clean up after a previous call.
+ */
+ if (tp->buffer) {
+ myfree(tp->buffer);
+ myfree((char *) tp->origin);
+ }
+
+ /*
+ * Postpone the work of template parsing until it is really needed. Most
+ * bounce service calls never need a template.
+ */
+ if (buffer && origin) {
+ tp->flags |= BOUNCE_TMPL_FLAG_NEW_BUFFER;
+ tp->buffer = mystrdup(buffer);
+ tp->origin = mystrdup(origin);
+ } else {
+ *tp = *(tp->prototype);
+ /* Also resets the buffer and origin fields. */
+ }
+}
+
+/* bounce_template_parse_buffer - initialize template */
+
+static void bounce_template_parse_buffer(BOUNCE_TEMPLATE *tp)
+{
+ char *tval = tp->buffer;
char *cp;
char **cpp;
int cpp_len;
@@ -410,31 +263,26 @@ const BOUNCE_TEMPLATE *bounce_template_find(const char *template_name,
char *hval;
/*
- * Look up a non-default template. Once we found it we are going to
- * destroy it; no-one will access this data again.
+ * Sanity check.
*/
- if (*var_bounce_tmpl == 0
- || (tval = (char *) dict_lookup(BOUNCE_TEMPLATE_DICT, template_name)) == 0)
- return (def_template);
+ if ((tp->flags & BOUNCE_TMPL_FLAG_NEW_BUFFER) == 0)
+ msg_panic("bounce_template_parse_buffer: nothing to do here");
+ tp->flags &= ~BOUNCE_TMPL_FLAG_NEW_BUFFER;
/*
- * Initialize a new template. We're not going to use the message text
- * from the default template.
+ * Discard the unusable template and use the default one instead.
*/
- tp = (BOUNCE_TEMPLATE *) mymalloc(sizeof(*tp));
- *tp = *def_template;
-
-#define CLEANUP_AND_RETURN(x) do { \
- myfree((char *) tp); \
- return (x); \
+#define CLEANUP_AND_RETURN() do { \
+ myfree(tp->buffer); \
+ myfree((char *) tp->origin); \
+ *tp = *(tp->prototype); \
} while (0)
-
/*
* Parse pseudo-header labels and values.
*/
#define GETLINE(line, buf) \
- (((line) = (buf)) ? ((buf) = split_at((buf), '\n'), (line)) : 0)
+ (((line) = (buf)) ? ((buf) = split_at((buf), '\n'), (line)) : 0)
while ((GETLINE(cp, tval)) != 0 && (hlen = is_header(cp)) > 0) {
for (hval = cp + hlen; *hval && (*hval == ':' || ISSPACE(*hval)); hval++)
@@ -442,19 +290,17 @@ const BOUNCE_TEMPLATE *bounce_template_find(const char *template_name,
if (*hval == 0) {
msg_warn("%s: empty \"%s\" header value in %s template "
"-- ignoring this template",
- *var_bounce_tmpl ? var_bounce_tmpl : "[built-in]",
- cp, template_name);
- CLEANUP_AND_RETURN(def_template);
+ tp->origin, cp, tp->class);
+ CLEANUP_AND_RETURN();
}
if (!allascii(hval)) {
msg_warn("%s: non-ASCII \"%s\" header value in %s template "
"-- ignoring this template",
- *var_bounce_tmpl ? var_bounce_tmpl : "[built-in]",
- cp, template_name);
- CLEANUP_AND_RETURN(def_template);
+ tp->origin, cp, tp->class);
+ CLEANUP_AND_RETURN();
}
if (strcasecmp("charset", cp) == 0) {
- tp->charset = hval;
+ tp->mime_charset = hval;
} else if (strcasecmp("from", cp) == 0) {
tp->from = hval;
} else if (strcasecmp("subject", cp) == 0) {
@@ -463,17 +309,15 @@ const BOUNCE_TEMPLATE *bounce_template_find(const char *template_name,
if (tp->postmaster_subject == 0) {
msg_warn("%s: inapplicable \"%s\" header label in %s template "
"-- ignoring this template",
- *var_bounce_tmpl ? var_bounce_tmpl : "[built-in]",
- cp, template_name);
- CLEANUP_AND_RETURN(def_template);
+ tp->origin, cp, tp->class);
+ CLEANUP_AND_RETURN();
}
tp->postmaster_subject = hval;
} else {
msg_warn("%s: unknown \"%s\" header label in %s template "
"-- ignoring this template",
- *var_bounce_tmpl ? var_bounce_tmpl : "[built-in]",
- cp, template_name);
- CLEANUP_AND_RETURN(def_template);
+ tp->origin, cp, tp->class);
+ CLEANUP_AND_RETURN();
}
}
@@ -485,9 +329,8 @@ const BOUNCE_TEMPLATE *bounce_template_find(const char *template_name,
if (cp == 0) {
msg_warn("%s: missing message text in %s template "
"-- ignoring this template",
- *var_bounce_tmpl ? var_bounce_tmpl : "[built-in]",
- template_name);
- CLEANUP_AND_RETURN(def_template);
+ tp->origin, tp->class);
+ CLEANUP_AND_RETURN();
}
/*
@@ -497,13 +340,12 @@ const BOUNCE_TEMPLATE *bounce_template_find(const char *template_name,
#define NON_ASCII(p) (*(p) && !allascii((p)))
if (NON_ASCII(cp) || NON_ASCII(tval)) {
- if (strcasecmp(tp->charset, "us-ascii") == 0) {
+ if (strcasecmp(tp->mime_charset, "us-ascii") == 0) {
msg_warn("%s: 8-bit message text in %s template",
- *var_bounce_tmpl ? var_bounce_tmpl : "[built-in]",
- template_name);
+ tp->origin, tp->class);
msg_warn("please specify a charset value other than us-ascii");
msg_warn("-- ignoring this template for now");
- CLEANUP_AND_RETURN(def_template);
+ CLEANUP_AND_RETURN();
}
tp->mime_encoding = MAIL_ATTR_ENC_8BIT;
}
@@ -525,68 +367,115 @@ const BOUNCE_TEMPLATE *bounce_template_find(const char *template_name,
}
cpp[cpp_used] = 0;
tp->message_text = (const char **) cpp;
-
- return (tp);
}
-/* print_template - dump one template */
+/* bounce_template_lookup - lookup $name value */
-static void print_template(VSTREAM *stream, const BOUNCE_TEMPLATE *tp)
+static const char *bounce_template_lookup(const char *key, int unused_mode,
+ char *context)
+{
+ BOUNCE_TEMPLATE *tp = (BOUNCE_TEMPLATE *) context;
+ BOUNCE_TIME_PARAMETER *bp;
+ BOUNCE_TIME_DIVISOR *bd;
+ static VSTRING *buf;
+ int result;
+
+ /*
+ * Look for parameter names that can have a time unit suffix, and scale
+ * the time value according to the suffix.
+ */
+ for (bp = time_parameter; bp->param_name; bp++) {
+ if (strncmp(key, bp->param_name, bp->param_name_len) == 0
+ && key[bp->param_name_len] == '_') {
+ for (bd = time_divisors; bd->suffix; bd++) {
+ if (strcmp(key + bp->param_name_len + 1, bd->suffix) == 0) {
+ result = bp->value[0] / bd->divisor;
+ if (result > 999 && bd->divisor < 86400) {
+ msg_warn("%s: excessive result \"%d\" in %s "
+ "template conversion of parameter \"%s\"",
+ tp->origin, result, tp->class, key);
+ msg_warn("please increase time unit \"%s\" of \"%s\" "
+ "in %s template", bd->suffix, key, tp->class);
+ } else if (result == 0 && bp->value[0] && bd->divisor > 1) {
+ msg_warn("%s: zero result in %s template "
+ "conversion of parameter \"%s\"",
+ tp->origin, tp->class, key);
+ msg_warn("please reduce time unit \"%s\" of \"%s\" "
+ "in %s template", bd->suffix, key, tp->class);
+ }
+ if (buf == 0)
+ buf = vstring_alloc(10);
+ vstring_sprintf(buf, "%d", result);
+ return (STR(buf));
+ }
+ }
+ msg_fatal("%s: unrecognized suffix \"%s\" in parameter \"%s\"",
+ tp->origin,
+ key + bp->param_name_len + 1, key);
+ }
+ }
+ return (mail_conf_lookup_eval(key));
+}
+
+/* bounce_template_headers - send template headers */
+
+void bounce_template_headers(BOUNCE_XP_PRN_FN out_fn, VSTREAM *fp,
+ BOUNCE_TEMPLATE *tp,
+ const char *rcpt,
+ int postmaster_copy)
+{
+ if (tp->flags & BOUNCE_TMPL_FLAG_NEW_BUFFER)
+ bounce_template_parse_buffer(tp);
+
+ out_fn(fp, "From: %s", tp->from);
+ out_fn(fp, "Subject: %s", tp->postmaster_subject && postmaster_copy ?
+ tp->postmaster_subject : tp->subject);
+ out_fn(fp, "To: %s", rcpt);
+}
+
+/* bounce_template_expand - expand template to stream */
+
+void bounce_template_expand(BOUNCE_XP_PUT_FN out_fn, VSTREAM *fp,
+ BOUNCE_TEMPLATE *tp)
+{
+ VSTRING *buf = vstring_alloc(100);
+ const char **cpp;
+ int stat;
+ const char *filter = "\t !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~";
+
+ if (tp->flags & BOUNCE_TMPL_FLAG_NEW_BUFFER)
+ bounce_template_parse_buffer(tp);
+
+ for (cpp = tp->message_text; *cpp; cpp++) {
+ stat = mac_expand(buf, *cpp, MAC_EXP_FLAG_NONE, filter,
+ bounce_template_lookup, (char *) tp);
+ if (stat & MAC_PARSE_ERROR)
+ msg_fatal("%s: bad $name syntax in %s template: %s",
+ tp->origin, tp->class, *cpp);
+ if (stat & MAC_PARSE_UNDEF)
+ msg_fatal("%s: undefined $name in %s template: %s",
+ tp->origin, tp->class, *cpp);
+ out_fn(fp, STR(buf));
+ }
+ vstring_free(buf);
+}
+
+/* bounce_template_dump - dump template to stream */
+
+void bounce_template_dump(VSTREAM *fp, BOUNCE_TEMPLATE *tp)
{
const char **cpp;
- vstream_fprintf(stream, "%s_template = <class);
- vstream_fprintf(stream, "Charset: %s\n", tp->charset);
- vstream_fprintf(stream, "From: %s\n", tp->from);
- vstream_fprintf(stream, "Subject: %s\n", tp->subject);
+ if (tp->flags & BOUNCE_TMPL_FLAG_NEW_BUFFER)
+ bounce_template_parse_buffer(tp);
+
+ vstream_fprintf(fp, "Charset: %s\n", tp->mime_charset);
+ vstream_fprintf(fp, "From: %s\n", tp->from);
+ vstream_fprintf(fp, "Subject: %s\n", tp->subject);
if (tp->postmaster_subject)
- vstream_fprintf(stream, "Postmaster-Subject: %s\n",
+ vstream_fprintf(fp, "Postmaster-Subject: %s\n",
tp->postmaster_subject);
- vstream_fprintf(stream, "\n");
+ vstream_fprintf(fp, "\n");
for (cpp = tp->message_text; *cpp; cpp++)
- vstream_fprintf(stream, "%s\n", *cpp);
- vstream_fprintf(stream, "EOF\n");
- vstream_fflush(stream);
-}
-
-/* bounce_template_dump_all - dump bounce templates to stream */
-
-void bounce_template_dump_all(VSTREAM *stream)
-{
- print_template(VSTREAM_OUT, FAIL_TEMPLATE());
- vstream_fprintf(stream, "\n");
- print_template(VSTREAM_OUT, DELAY_TEMPLATE());
- vstream_fprintf(stream, "\n");
- print_template(VSTREAM_OUT, SUCCESS_TEMPLATE());
- vstream_fprintf(stream, "\n");
- print_template(VSTREAM_OUT, VERIFY_TEMPLATE());
-}
-
-/* bounce_plain_out - output line as plain text */
-
-static int bounce_plain_out(VSTREAM *stream, const char *text)
-{
- vstream_fprintf(stream, "%s\n", text);
- return (0);
-}
-
-/* bounce_template_expand_all - dump expanded template text to stream */
-
-void bounce_template_expand_all(VSTREAM *stream)
-{
- const BOUNCE_TEMPLATE *tp;
-
- tp = FAIL_TEMPLATE();
- vstream_fprintf(VSTREAM_OUT, "expanded_%s_text = <class);
- bounce_template_expand(bounce_plain_out, VSTREAM_OUT, tp);
- tp = DELAY_TEMPLATE();
- vstream_fprintf(VSTREAM_OUT, "EOF\n\nexpanded_%s_text = <class);
- bounce_template_expand(bounce_plain_out, VSTREAM_OUT, tp);
- tp = SUCCESS_TEMPLATE();
- vstream_fprintf(VSTREAM_OUT, "EOF\n\nexpanded_%s_text = <class);
- bounce_template_expand(bounce_plain_out, VSTREAM_OUT, tp);
- tp = VERIFY_TEMPLATE();
- vstream_fprintf(VSTREAM_OUT, "EOF\n\nexpanded_%s_text = <class);
- bounce_template_expand(bounce_plain_out, VSTREAM_OUT, tp);
- vstream_fprintf(VSTREAM_OUT, "EOF\n");
+ vstream_fprintf(fp, "%s\n", *cpp);
}
diff --git a/postfix/src/bounce/bounce_template.h b/postfix/src/bounce/bounce_template.h
new file mode 100644
index 000000000..fe6c65524
--- /dev/null
+++ b/postfix/src/bounce/bounce_template.h
@@ -0,0 +1,94 @@
+#ifndef _BOUNCE_TEMPLATE_H_INCLUDED_
+#define _BOUNCE_TEMPLATE_H_INCLUDED_
+
+/*++
+/* NAME
+/* bounce_template 3h
+/* SUMMARY
+/* bounce template support
+/* SYNOPSIS
+/* #include
+/* DESCRIPTION
+/* .nf
+
+ /*
+ * Utility library.
+ */
+#include
+
+ /*
+ * Structure of a single bounce template. Each template is manipulated by
+ * itself, without any external markers and delimiters. Applications are not
+ * supposed to access BOUNCE_TEMPLATE attributes directly.
+ */
+typedef struct BOUNCE_TEMPLATE {
+ int flags;
+ const char *class; /* for diagnostics (fixed) */
+ const char *origin; /* built-in or pathname */
+ const char *mime_charset; /* character set (configurable) */
+ const char *mime_encoding; /* 7bit or 8bit (derived) */
+ const char *from; /* originator (configurable) */
+ const char *subject; /* general subject (configurable) */
+ const char *postmaster_subject; /* postmaster subject (configurable) */
+ const char **message_text; /* message text (configurable) */
+ const struct BOUNCE_TEMPLATE *prototype; /* defaults */
+ char *buffer; /* ripped text */
+} BOUNCE_TEMPLATE;
+
+#define BOUNCE_TMPL_FLAG_NEW_BUFFER (1<<0)
+
+#define BOUNCE_TMPL_CLASS_FAILURE "failure"
+#define BOUNCE_TMPL_CLASS_DELAY "delay"
+#define BOUNCE_TMPL_CLASS_SUCCESS "success"
+#define BOUNCE_TMPL_CLASS_VERIFY "verify"
+
+#define IS_FAILURE_TEMPLATE(t) ((t)->class[0] == BOUNCE_TMPL_CLASS_FAILURE[0])
+#define IS_DELAY_TEMPLATE(t) ((t)->class[0] == BOUNCE_TMPL_CLASS_DELAY[0])
+#define IS_SUCCESS_TEMPLATE(t) ((t)->class[0] == BOUNCE_TMPL_CLASS_SUCCESS[0])
+#define IS_VERIFY_TEMPLATE(t) ((t)->class[0] == BOUNCE_TMPL_CLASS_verify[0])
+
+#define bounce_template_encoding(t) ((t)->mime_encoding)
+#define bounce_template_charset(t) ((t)->mime_charset)
+
+typedef int (*BOUNCE_XP_PRN_FN) (VSTREAM *, const char *, ...);
+typedef int (*BOUNCE_XP_PUT_FN) (VSTREAM *, const char *);
+
+extern BOUNCE_TEMPLATE *bounce_template_create(const BOUNCE_TEMPLATE *);
+extern void bounce_template_free(BOUNCE_TEMPLATE *);
+extern void bounce_template_load(BOUNCE_TEMPLATE *, const char *, const char *);
+extern void bounce_template_headers(BOUNCE_XP_PRN_FN, VSTREAM *, BOUNCE_TEMPLATE *, const char *, int);
+extern void bounce_template_expand(BOUNCE_XP_PUT_FN, VSTREAM *, BOUNCE_TEMPLATE *);
+extern void bounce_template_dump(VSTREAM *, BOUNCE_TEMPLATE *);
+
+#define POSTMASTER_COPY 1 /* postmaster copy */
+#define NO_POSTMASTER_COPY 0 /* not postmaster copy */
+
+ /*
+ * Structure of a bounce template collection. These templates are read and
+ * written in their external representation, with markers and delimiters.
+ */
+typedef struct {
+ BOUNCE_TEMPLATE *failure;
+ BOUNCE_TEMPLATE *delay;
+ BOUNCE_TEMPLATE *success;
+ BOUNCE_TEMPLATE *verify;
+} BOUNCE_TEMPLATES;
+
+BOUNCE_TEMPLATES *bounce_templates_create(void);
+void bounce_templates_free(BOUNCE_TEMPLATES *);
+void bounce_templates_load(VSTREAM *, BOUNCE_TEMPLATES *);
+void bounce_templates_expand(VSTREAM *, BOUNCE_TEMPLATES *);
+void bounce_templates_dump(VSTREAM *, BOUNCE_TEMPLATES *);
+
+/* 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
diff --git a/postfix/src/bounce/bounce_templates.c b/postfix/src/bounce/bounce_templates.c
new file mode 100644
index 000000000..7038e3f2d
--- /dev/null
+++ b/postfix/src/bounce/bounce_templates.c
@@ -0,0 +1,390 @@
+/*++
+/* NAME
+/* bounce_templates 3
+/* SUMMARY
+/* bounce template group support
+/* SYNOPSIS
+/* #include
+/*
+/* BOUNCE_TEMPLATES *bounce_templates_create(void)
+/*
+/* void bounce_templates_free(templates)
+/* BOUNCE_TEMPLATES *templates;
+/*
+/* void bounce_templates_load(stream, templates)
+/* VSTREAM *stream;
+/* BOUNCE_TEMPLATES *templates;
+/*
+/* void bounce_templates_expand(stream, templates)
+/* VSTREAM *stream;
+/* BOUNCE_TEMPLATES *templates;
+/*
+/* void bounce_templates_dump(stream, templates)
+/* VSTREAM *stream;
+/* BOUNCE_TEMPLATES *templates;
+/* DESCRIPTION
+/* This module implements support for bounce template groups
+/* (i.e. groups that contain one template of each type).
+/*
+/* bounce_templates_create() creates a bounce template group,
+/* with default settings.
+/*
+/* bounce_templates_free() destroys a bounce template group.
+/*
+/* bounce_templates_load() reads zero or more bounce templates
+/* from the specified file.
+/*
+/* bounce_templates_expand() expands $name macros and writes
+/* the text portions of the specified bounce template group
+/* to the specified stream.
+/*
+/* bounce_templates_dump() writes the complete content of the
+/* specified bounce template group to the specified stream.
+/* The format is compatible with bounce_templates_load().
+/* DIAGNOSTICS
+/* Fatal error: out of memory, undefined macro name in template.
+/* SEE ALSO
+/* bounce_template(3) bounce template support
+/* 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
+/*--*/
+
+/* System library. */
+
+#include
+#include
+#include
+
+/* Utility library. */
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+/* Global library. */
+
+#include
+#include
+
+/* Application-specific. */
+
+#include
+
+ /*
+ * The fail template is for permanent failure.
+ */
+static const char *def_bounce_failure_body[];
+
+static const BOUNCE_TEMPLATE def_bounce_failure_template = {
+ 0,
+ BOUNCE_TMPL_CLASS_FAILURE,
+ "[built-in]",
+ "us-ascii",
+ MAIL_ATTR_ENC_7BIT,
+ MAIL_ADDR_MAIL_DAEMON " (Mail Delivery System)",
+ "Undelivered Mail Returned to Sender",
+ "Postmaster Copy: Undelivered Mail",
+ def_bounce_failure_body,
+ &def_bounce_failure_template,
+};
+
+static const char *def_bounce_failure_body[] = {
+ "This is the $mail_name program at host $myhostname.",
+ "",
+ "I'm sorry to have to inform you that your message could not",
+ "be delivered to one or more recipients. It's attached below.",
+ "",
+ "For further assistance, please send mail to <" MAIL_ADDR_POSTMASTER ">",
+ "",
+ "If you do so, please include this problem report. You can",
+ "delete your own text from the attached returned message.",
+ "",
+ " The $mail_name program",
+ 0,
+};
+
+ /*
+ * The delay template is for delayed mail notifications.
+ */
+static const char *def_bounce_delay_body[];
+
+static const BOUNCE_TEMPLATE def_bounce_delay_template = {
+ 0,
+ BOUNCE_TMPL_CLASS_DELAY,
+ "[built-in]",
+ "us-ascii",
+ MAIL_ATTR_ENC_7BIT,
+ MAIL_ADDR_MAIL_DAEMON " (Mail Delivery System)",
+ "Delayed Mail (still being retried)",
+ "Postmaster Warning: Delayed Mail",
+ def_bounce_delay_body,
+ &def_bounce_delay_template
+};
+
+static const char *def_bounce_delay_body[] = {
+ "This is the $mail_name program at host $myhostname.",
+ "",
+ "####################################################################",
+ "# THIS IS A WARNING ONLY. YOU DO NOT NEED TO RESEND YOUR MESSAGE. #",
+ "####################################################################",
+ "",
+ "Your message could not be delivered for $delay_warning_time_hours hour(s)."
+ ,
+ "It will be retried until it is $maximal_queue_lifetime_days day(s) old.",
+ "",
+ "For further assistance, please send mail to <" MAIL_ADDR_POSTMASTER ">",
+ "",
+ "If you do so, please include this problem report. You can",
+ "delete your own text from the attached returned message.",
+ "",
+ " The $mail_name program",
+ 0,
+};
+
+ /*
+ * The success template is for "delivered", "expanded" and "relayed" success
+ * notifications.
+ */
+static const char *def_bounce_success_body[];
+
+static const BOUNCE_TEMPLATE def_bounce_success_template = {
+ 0,
+ BOUNCE_TMPL_CLASS_SUCCESS,
+ "[built-in]",
+ "us-ascii",
+ MAIL_ATTR_ENC_7BIT,
+ MAIL_ADDR_MAIL_DAEMON " (Mail Delivery System)",
+ "Successful Mail Delivery Report",
+ 0,
+ def_bounce_success_body,
+ &def_bounce_success_template,
+};
+
+static const char *def_bounce_success_body[] = {
+ "This is the $mail_name program at host $myhostname.",
+ "",
+ "Your message was successfully delivered to the destination(s)",
+ "listed below. If the message was delivered to mailbox you will",
+ "receive no further notifications. Otherwise you may still receive",
+ "notifications of mail delivery errors from other systems.",
+ "",
+ " The $mail_name program",
+ 0,
+};
+
+ /*
+ * The "verify" template is for verbose delivery (sendmail -v) and for
+ * address verification (sendmail -bv).
+ */
+static const char *def_bounce_verify_body[];
+
+static const BOUNCE_TEMPLATE def_bounce_verify_template = {
+ 0,
+ BOUNCE_TMPL_CLASS_VERIFY,
+ "[built-in]",
+ "us-ascii",
+ MAIL_ATTR_ENC_7BIT,
+ MAIL_ADDR_MAIL_DAEMON " (Mail Delivery System)",
+ "Mail Delivery Status Report",
+ 0,
+ def_bounce_verify_body,
+ &def_bounce_verify_template,
+};
+
+static const char *def_bounce_verify_body[] = {
+ "This is the $mail_name program at host $myhostname.",
+ "",
+ "Enclosed is the mail delivery report that you requested.",
+ "",
+ " The $mail_name program",
+ 0,
+};
+
+ /*
+ * SLMs.
+ */
+#define STR(x) vstring_str(x)
+
+/* bounce_templates_create - create template group */
+
+BOUNCE_TEMPLATES *bounce_templates_create(void)
+{
+ BOUNCE_TEMPLATES *bs;
+
+ bs = (BOUNCE_TEMPLATES *) mymalloc(sizeof(*bs));
+ bs->failure = bounce_template_create(&def_bounce_failure_template);
+ bs->delay = bounce_template_create(&def_bounce_delay_template);
+ bs->success = bounce_template_create(&def_bounce_success_template);
+ bs->verify = bounce_template_create(&def_bounce_verify_template);
+ return (bs);
+}
+
+/* bounce_templates_free - destroy template group */
+
+void bounce_templates_free(BOUNCE_TEMPLATES *bs)
+{
+ bounce_template_free(bs->failure);
+ bounce_template_free(bs->delay);
+ bounce_template_free(bs->success);
+ bounce_template_free(bs->verify);
+ myfree((char *) bs);
+}
+
+/* bounce_templates_load - load template or group from stream */
+
+void bounce_templates_load(VSTREAM *fp, BOUNCE_TEMPLATES *ts)
+{
+ VSTRING *line_buf;
+ char *member_name;
+ VSTRING *multi_line_buf = 0;
+ VSTRING *saved_member_name = 0;
+ VSTRING *saved_end_marker = 0;
+ char *value;
+ int lineno;
+ const char *err;
+ char *cp;
+ int len; /* Grr... */
+
+ /*
+ * XXX That's a lot of non-reusable code to parse a configuration file.
+ * Unfortunately, much of the "name = value" infrastructure is married to
+ * the dict(3) class which doesn't really help here.
+ */
+ line_buf = vstring_alloc(100);
+ lineno = 1;
+ while (vstring_get_nonl(line_buf, fp) > 0) {
+ lineno++;
+ cp = STR(line_buf) + strspn(STR(line_buf), " \t\n\v\f\r");
+ if (*cp == 0 || *cp == '#')
+ continue;
+ if ((err = split_nameval(STR(line_buf), &member_name, &value)) != 0)
+ msg_fatal("%s, line %d: %s: \"%s\"",
+ VSTREAM_PATH(fp), lineno, err, STR(line_buf));
+ if (value[0] == '<' && value[1] == '<') {
+ value += 2;
+ while (ISSPACE(*value))
+ value++;
+ if (*value == 0)
+ msg_fatal("%s, line %d: missing end marker after <<",
+ VSTREAM_PATH(fp), lineno);
+ if (!ISALNUM(*value))
+ msg_fatal("%s, line %d: malformed end marker after <<",
+ VSTREAM_PATH(fp), lineno);
+ if (multi_line_buf == 0) {
+ saved_member_name = vstring_alloc(100);
+ saved_end_marker = vstring_alloc(100);
+ multi_line_buf = vstring_alloc(100);
+ } else
+ VSTRING_RESET(multi_line_buf);
+ vstring_strcpy(saved_member_name, member_name);
+ vstring_strcpy(saved_end_marker, value);
+ while (vstring_get_nonl(line_buf, fp) > 0) {
+ lineno++;
+ if (strcmp(STR(line_buf), STR(saved_end_marker)) == 0)
+ break;
+ if (VSTRING_LEN(multi_line_buf) > 0)
+ vstring_strcat(multi_line_buf, "\n");
+ vstring_strcat(multi_line_buf, STR(line_buf));
+ }
+ if (vstream_feof(fp))
+ msg_warn("%s, line %d: missing \"%s\" end marker",
+ VSTREAM_PATH(fp), lineno, value);
+ member_name = STR(saved_member_name);
+ value = STR(multi_line_buf);
+ }
+#define MATCH_TMPL_NAME(tname, tname_len, mname) \
+ (strncmp(tname, mname, tname_len = strlen(tname)) == 0 \
+ && strcmp(mname + tname_len, "_template") == 0)
+
+ if (MATCH_TMPL_NAME(ts->failure->class, len, member_name))
+ bounce_template_load(ts->failure, VSTREAM_PATH(fp), value);
+ else if (MATCH_TMPL_NAME(ts->delay->class, len, member_name))
+ bounce_template_load(ts->delay, VSTREAM_PATH(fp), value);
+ else if (MATCH_TMPL_NAME(ts->success->class, len, member_name))
+ bounce_template_load(ts->success, VSTREAM_PATH(fp), value);
+ else if (MATCH_TMPL_NAME(ts->verify->class, len, member_name))
+ bounce_template_load(ts->verify, VSTREAM_PATH(fp), value);
+ else
+ msg_warn("%s, line %d: unknown template name: %s "
+ "-- ignoring this template",
+ VSTREAM_PATH(fp), lineno, member_name);
+ }
+ vstring_free(line_buf);
+ if (multi_line_buf) {
+ vstring_free(saved_member_name);
+ vstring_free(saved_end_marker);
+ vstring_free(multi_line_buf);
+ }
+}
+
+/* bounce_plain_out - output line as plain text */
+
+static int bounce_plain_out(VSTREAM *fp, const char *text)
+{
+ vstream_fprintf(fp, "%s\n", text);
+ return (0);
+}
+
+/* bounce_templates_expand - dump expanded template group text to stream */
+
+void bounce_templates_expand(VSTREAM *fp, BOUNCE_TEMPLATES *ts)
+{
+ BOUNCE_TEMPLATE *tp;
+
+ tp = ts->failure;
+ vstream_fprintf(fp, "expanded_%s_text = <class);
+ bounce_template_expand(bounce_plain_out, fp, tp);
+ vstream_fprintf(fp, "EOF\n\n");
+
+ tp = ts->delay;
+ vstream_fprintf(fp, "expanded_%s_text = <class);
+ bounce_template_expand(bounce_plain_out, fp, tp);
+ vstream_fprintf(fp, "EOF\n\n");
+
+ tp = ts->success;
+ vstream_fprintf(fp, "expanded_%s_text = <class);
+ bounce_template_expand(bounce_plain_out, fp, tp);
+ vstream_fprintf(fp, "EOF\n\n");
+
+ tp = ts->verify;
+ vstream_fprintf(fp, "expanded_%s_text = <class);
+ bounce_template_expand(bounce_plain_out, fp, tp);
+ vstream_fprintf(fp, "EOF\n");
+}
+
+/* bounce_templates_dump - dump bounce template group to stream */
+
+void bounce_templates_dump(VSTREAM *fp, BOUNCE_TEMPLATES *ts)
+{
+ BOUNCE_TEMPLATE *tp;
+
+ tp = ts->failure;
+ vstream_fprintf(fp, "%s_template = <class);
+ bounce_template_dump(fp, tp);
+ vstream_fprintf(fp, "EOF\n\n");
+
+ tp = ts->delay;
+ vstream_fprintf(fp, "%s_template = <class);
+ bounce_template_dump(fp, tp);
+ vstream_fprintf(fp, "EOF\n\n");
+
+ tp = ts->success;
+ vstream_fprintf(fp, "%s_template = <class);
+ bounce_template_dump(fp, tp);
+ vstream_fprintf(fp, "EOF\n\n");
+
+ tp = ts->verify;
+ vstream_fprintf(fp, "%s_template = <class);
+ bounce_template_dump(fp, tp);
+ vstream_fprintf(fp, "EOF\n");
+}
diff --git a/postfix/src/bounce/bounce_trace_service.c b/postfix/src/bounce/bounce_trace_service.c
index c760f1618..a1f9fd532 100644
--- a/postfix/src/bounce/bounce_trace_service.c
+++ b/postfix/src/bounce/bounce_trace_service.c
@@ -7,7 +7,7 @@
/* #include "bounce_service.h"
/*
/* int bounce_trace_service(flags, queue_name, queue_id, encoding,
-/* sender, char *envid, int ret)
+/* sender, char *envid, int ret, templates)
/* int flags;
/* char *queue_name;
/* char *queue_id;
@@ -15,6 +15,7 @@
/* char *sender;
/* char *envid;
/* int ret;
+/* BOUNCE_TEMPLATES *templates;
/* DESCRIPTION
/* This module implements the server side of the trace_flush()
/* (send delivery notice) request. The logfile
@@ -80,7 +81,8 @@
int bounce_trace_service(int flags, char *service, char *queue_name,
char *queue_id, char *encoding,
char *recipient, char *dsn_envid,
- int unused_dsn_ret)
+ int unused_dsn_ret,
+ BOUNCE_TEMPLATES *ts)
{
BOUNCE_INFO *bounce_info;
int bounce_status = 1;
@@ -106,8 +108,7 @@ int bounce_trace_service(int flags, char *service, char *queue_name,
bounce_info = bounce_mail_init(service, queue_name, queue_id,
encoding, dsn_envid,
flags & NON_DSN_FLAGS ?
- VERIFY_TEMPLATE() :
- SUCCESS_TEMPLATE());
+ ts->verify : ts->success);
/*
* XXX With multi-recipient mail some queue file recipients may have
@@ -145,7 +146,8 @@ int bounce_trace_service(int flags, char *service, char *queue_name,
CLEANUP_FLAG_MASK_INTERNAL,
NULL_TRACE_FLAGS)) != 0) {
count = -1;
- if (bounce_header(bounce, bounce_info, recipient) == 0
+ if (bounce_header(bounce, bounce_info, recipient,
+ NO_POSTMASTER_COPY) == 0
&& bounce_boilerplate(bounce, bounce_info) == 0
&& (count = bounce_diagnostic_log(bounce, bounce_info,
DSN_NOTIFY_OVERRIDE)) > 0
diff --git a/postfix/src/bounce/bounce_warn_service.c b/postfix/src/bounce/bounce_warn_service.c
index 229965fd8..f446dd6d5 100644
--- a/postfix/src/bounce/bounce_warn_service.c
+++ b/postfix/src/bounce/bounce_warn_service.c
@@ -7,7 +7,7 @@
/* #include "bounce_service.h"
/*
/* int bounce_warn_service(flags, queue_name, queue_id, encoding,
-/* sender, envid, dsn_ret)
+/* sender, envid, dsn_ret, templates)
/* int flags;
/* char *queue_name;
/* char *queue_id;
@@ -15,6 +15,7 @@
/* char *sender;
/* char *envid;
/* int dsn_ret;
+/* BOUNCE_TEMPLATES *ts;
/* DESCRIPTION
/* This module implements the server side of the bounce_warn()
/* (send delay notice) request. The logfile
@@ -83,7 +84,7 @@
int bounce_warn_service(int unused_flags, char *service, char *queue_name,
char *queue_id, char *encoding,
char *recipient, char *dsn_envid,
- int dsn_ret)
+ int dsn_ret, BOUNCE_TEMPLATES *ts)
{
BOUNCE_INFO *bounce_info;
int bounce_status = 1;
@@ -117,7 +118,7 @@ int bounce_warn_service(int unused_flags, char *service, char *queue_name,
* notify_classes restrictions.
*/
bounce_info = bounce_mail_init(service, queue_name, queue_id,
- encoding, dsn_envid, DELAY_TEMPLATE());
+ encoding, dsn_envid, ts->delay);
#define NULL_SENDER MAIL_ADDR_EMPTY /* special address */
#define NULL_TRACE_FLAGS 0
@@ -172,7 +173,8 @@ int bounce_warn_service(int unused_flags, char *service, char *queue_name,
* message. Don't bother sending the boiler-plate text.
*/
count = -1;
- if (!bounce_header(bounce, bounce_info, postmaster)
+ if (!bounce_header(bounce, bounce_info, postmaster,
+ POSTMASTER_COPY)
&& (count = bounce_diagnostic_log(bounce, bounce_info,
DSN_NOTIFY_OVERRIDE)) > 0
&& bounce_header_dsn(bounce, bounce_info) == 0
@@ -204,7 +206,8 @@ int bounce_warn_service(int unused_flags, char *service, char *queue_name,
* reason for the bounce, and a copy of the original message.
*/
count = -1;
- if (bounce_header(bounce, bounce_info, recipient) == 0
+ if (bounce_header(bounce, bounce_info, recipient,
+ NO_POSTMASTER_COPY) == 0
&& bounce_boilerplate(bounce, bounce_info) == 0
&& (count = bounce_diagnostic_log(bounce, bounce_info,
DSN_NOTIFY_DELAY)) > 0
@@ -243,7 +246,8 @@ int bounce_warn_service(int unused_flags, char *service, char *queue_name,
CLEANUP_FLAG_MASK_INTERNAL,
NULL_TRACE_FLAGS)) != 0) {
count = -1;
- if (bounce_header(bounce, bounce_info, postmaster) == 0
+ if (bounce_header(bounce, bounce_info, postmaster,
+ POSTMASTER_COPY) == 0
&& (count = bounce_diagnostic_log(bounce, bounce_info,
DSN_NOTIFY_OVERRIDE)) > 0
&& bounce_header_dsn(bounce, bounce_info) == 0
diff --git a/postfix/src/bounce/dict_ml.c b/postfix/src/bounce/dict_ml.c
deleted file mode 100644
index d7be3f149..000000000
--- a/postfix/src/bounce/dict_ml.c
+++ /dev/null
@@ -1,179 +0,0 @@
-/*++
-/* NAME
-/* dict 3
-/* SUMMARY
-/* dictionary manager, multi-line entry support
-/* SYNOPSIS
-/* #include
-/*
-/* void dict_ml_load_file(dict_name, path)
-/* const char *dict_name;
-/* const char *path;
-/*
-/* void dict_ml_load_fp(dict_name, fp)
-/* const char *dict_name;
-/* VSTREAM *fp;
-/* DESCRIPTION
-/* This module implements input routines for dictionaries
-/* with single-line and multi-line values.
-/* .IP \(bu
-/* Single-line values are specified as "name = value".
-/* Like dict_load_file() and dict_load_fp(), leading and
-/* trailing whitespace is stripped from name and value.
-/* .IP \(bu
-/* Multi-line values are specified as:
-/*
-/* .na
-/* .nf
-/* .in +4
-/* name = <
-#include
-#include
-#include
-#include
-
-/* Utility library. */
-
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-#define STR(x) vstring_str(x)
-
-/* dict_ml_load_file - load table from file */
-
-void dict_ml_load_file(const char *dict_name, const char *path)
-{
- VSTREAM *fp;
- struct stat st;
- time_t before;
- time_t after;
-
- /*
- * Read the file again if it is hot. This may result in reading a partial
- * parameter name when a file changes in the middle of a read.
- */
- for (before = time((time_t *) 0); /* see below */ ; before = after) {
- if ((fp = vstream_fopen(path, O_RDONLY, 0)) == 0)
- msg_fatal("open %s: %m", path);
- dict_ml_load_fp(dict_name, fp);
- if (fstat(vstream_fileno(fp), &st) < 0)
- msg_fatal("fstat %s: %m", path);
- if (vstream_ferror(fp) || vstream_fclose(fp))
- msg_fatal("read %s: %m", path);
- after = time((time_t *) 0);
- if (st.st_mtime < before - 1 || st.st_mtime > after)
- break;
- if (msg_verbose)
- msg_info("pausing to let %s cool down", path);
- doze(300000);
- }
-}
-
-/* dict_ml_load_fp - load table from stream */
-
-void dict_ml_load_fp(const char *dict_name, VSTREAM *fp)
-{
- VSTRING *line_buf;
- char *member_name;
- VSTRING *multi_line_buf = 0;
- VSTRING *saved_member_name = 0;
- VSTRING *saved_end_marker = 0;
- char *value;
- int lineno;
- const char *err;
- char *cp;
-
- line_buf = vstring_alloc(100);
- lineno = 1;
- while (vstring_get_nonl(line_buf, fp) > 0) {
- lineno++;
- cp = STR(line_buf) + strspn(STR(line_buf), " \t\n\v\f\r");
- if (*cp == 0 || *cp == '#')
- continue;
- if ((err = split_nameval(STR(line_buf), &member_name, &value)) != 0)
- msg_fatal("%s, line %d: %s: \"%s\"",
- VSTREAM_PATH(fp), lineno, err, STR(line_buf));
- if (value[0] == '<' && value[1] == '<') {
- value += 2;
- while (ISSPACE(*value))
- value++;
- if (*value == 0)
- msg_fatal("%s, line %d: missing end marker after <<",
- VSTREAM_PATH(fp), lineno);
- if (!ISALNUM(*value))
- msg_fatal("%s, line %d: malformed end marker after <<",
- VSTREAM_PATH(fp), lineno);
- if (multi_line_buf == 0) {
- saved_member_name = vstring_alloc(100);
- saved_end_marker = vstring_alloc(100);
- multi_line_buf = vstring_alloc(100);
- } else
- VSTRING_RESET(multi_line_buf);
- vstring_strcpy(saved_member_name, member_name);
- vstring_strcpy(saved_end_marker, value);
- while (vstring_get_nonl(line_buf, fp) > 0) {
- lineno++;
- if (strcmp(STR(line_buf), STR(saved_end_marker)) == 0)
- break;
- if (VSTRING_LEN(multi_line_buf) > 0)
- vstring_strcat(multi_line_buf, "\n");
- vstring_strcat(multi_line_buf, STR(line_buf));
- }
- if (vstream_feof(fp))
- msg_fatal("%s, line %d: missing \"%s\" end marker",
- VSTREAM_PATH(fp), lineno, value);
- member_name = STR(saved_member_name);
- value = STR(multi_line_buf);
- }
- dict_update(dict_name, member_name, value);
- }
- vstring_free(line_buf);
- if (multi_line_buf) {
- vstring_free(saved_member_name);
- vstring_free(saved_end_marker);
- vstring_free(multi_line_buf);
- }
-}
diff --git a/postfix/src/bounce/dict_ml.h b/postfix/src/bounce/dict_ml.h
deleted file mode 100644
index b7f47dc19..000000000
--- a/postfix/src/bounce/dict_ml.h
+++ /dev/null
@@ -1,37 +0,0 @@
-#ifndef _DICT_ML_H_INCLUDED_
-#define _DICT_ML_H_INCLUDED_
-
-/*++
-/* NAME
-/* dict_ml 3h
-/* SUMMARY
-/* dictionary manager, multi-line entry support
-/* SYNOPSIS
-/* #include
-/* DESCRIPTION
-/* .nf
-
- /*
- * Utility library.
- */
-#include
-#include
-
- /*
- * External interface.
- */
-extern void dict_ml_load_file(const char *, const char *);
-extern void dict_ml_load_fp(const char *, VSTREAM *);
-
-/* 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
diff --git a/postfix/src/bounce/template_test.ref b/postfix/src/bounce/template_test.ref
new file mode 100644
index 000000000..3fac4d489
--- /dev/null
+++ b/postfix/src/bounce/template_test.ref
@@ -0,0 +1,68 @@
+failure_template = <
+
+If you do so, please include this problem report. You can
+delete your own text from the attached returned message.
+
+ The $mail_name program
+EOF
+
+delay_template = <
+
+If you do so, please include this problem report. You can
+delete your own text from the attached returned message.
+
+ The $mail_name program
+EOF
+
+success_template = <
#endif
+#ifdef RESOLVE_H_NEEDS_NAMESER8_COMPAT_H
+#include
+#endif
#include
/*
diff --git a/postfix/src/global/mail_version.h b/postfix/src/global/mail_version.h
index 0485ca136..e78f0833d 100644
--- a/postfix/src/global/mail_version.h
+++ b/postfix/src/global/mail_version.h
@@ -20,7 +20,7 @@
* Patches change both the patchlevel and the release date. Snapshots have no
* patchlevel; they change the release date only.
*/
-#define MAIL_RELEASE_DATE "20051114"
+#define MAIL_RELEASE_DATE "20051117"
#define MAIL_VERSION_NUMBER "2.3"
#ifdef SNAPSHOT
diff --git a/postfix/src/postconf/postconf.c b/postfix/src/postconf/postconf.c
index 42bad2ef6..ed3796d4d 100644
--- a/postfix/src/postconf/postconf.c
+++ b/postfix/src/postconf/postconf.c
@@ -171,7 +171,7 @@
/* FILES
/* /etc/postfix/main.cf, Postfix configuration parameters
/* SEE ALSO
-/* bounce(5), bouce template file format
+/* bounce(5), bounce template file format
/* postconf(5), configuration parameters
/* README FILES
/* .ad
diff --git a/postfix/src/util/Makefile.in b/postfix/src/util/Makefile.in
index 182d8eb27..153836e0d 100644
--- a/postfix/src/util/Makefile.in
+++ b/postfix/src/util/Makefile.in
@@ -30,7 +30,7 @@ SRCS = alldig.c allprint.c argv.c argv_split.c attr_clnt.c attr_print0.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 sane_basename.c format_tv.c allspace.c \
- allascii.c
+ allascii.c load_file.c
OBJS = alldig.o allprint.o argv.o argv_split.o attr_clnt.o attr_print0.o \
attr_print64.o attr_print_plain.o attr_scan0.o attr_scan64.o \
attr_scan_plain.o auto_clnt.o base64_code.o basename.o binhash.o \
@@ -62,7 +62,7 @@ OBJS = alldig.o allprint.o argv.o argv_split.o attr_clnt.o attr_print0.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 sane_basename.o format_tv.o allspace.o \
- allascii.o
+ allascii.o load_file.o
HDRS = argv.h attr.h attr_clnt.h auto_clnt.h base64_code.h binhash.h \
chroot_uid.h cidr_match.h clean_env.h connect.h ctable.h dict.h \
dict_cdb.h dict_cidr.h dict_db.h dict_dbm.h dict_env.h dict_ht.h \
@@ -81,7 +81,7 @@ HDRS = argv.h attr.h attr_clnt.h auto_clnt.h base64_code.h binhash.h \
sigdelay.h sock_addr.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 format_tv.h
+ vstring_vstream.h watchdog.h format_tv.h load_file.h
TESTSRC = fifo_open.c fifo_rdwr_bug.c fifo_rdonly_bug.c select_bug.c \
stream_test.c dup2_pass_on_exec.c
DEFS = -I. -D$(SYSTYPE)
@@ -1112,6 +1112,13 @@ inet_trigger.o: trigger.h
line_wrap.o: line_wrap.c
line_wrap.o: line_wrap.h
line_wrap.o: sys_defs.h
+load_file.o: iostuff.h
+load_file.o: load_file.c
+load_file.o: load_file.h
+load_file.o: msg.h
+load_file.o: sys_defs.h
+load_file.o: vbuf.h
+load_file.o: vstream.h
lowercase.o: lowercase.c
lowercase.o: stringops.h
lowercase.o: sys_defs.h
diff --git a/postfix/src/util/load_file.c b/postfix/src/util/load_file.c
new file mode 100644
index 000000000..59af3453c
--- /dev/null
+++ b/postfix/src/util/load_file.c
@@ -0,0 +1,79 @@
+/*++
+/* NAME
+/* load_file 3
+/* SUMMARY
+/* load file with some prejudice
+/* SYNOPSIS
+/* #include
+/*
+/* void load_file(path, action, context)
+/* const char *path;
+/* void (*action)(VSTREAM, void *);
+/* void *context;
+/* DESCRIPTION
+/* This routine reads a file and reads it again when the
+/* file changed recently.
+/*
+/* Arguments:
+/* .IP path
+/* The file to be opened, read-only.
+/* .IP action
+/* The function that presumably reads the file.
+/* .IP context
+/* Application-specific context for the action routine.
+/* DIAGNOSTICS
+/* Fatal errors: out of memory, cannot open file.
+/* 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
+/*--*/
+
+/* System library. */
+
+#include
+#include
+#include
+
+/* Utility library. */
+
+#include
+#include
+#include
+#include
+
+/* load_file - load file with some prejudice */
+
+void load_file(const char *path, LOAD_FILE_FN action, void *context)
+{
+ VSTREAM *fp;
+ struct stat st;
+ time_t before;
+ time_t after;
+
+ /*
+ * Read the file again if it is hot. This may result in reading a partial
+ * parameter name or missing end marker when a file changes in the middle
+ * of a read.
+ */
+ for (before = time((time_t *) 0); /* see below */ ; before = after) {
+ if ((fp = vstream_fopen(path, O_RDONLY, 0)) == 0)
+ msg_fatal("open %s: %m", path);
+ action(fp, context);
+ if (fstat(vstream_fileno(fp), &st) < 0)
+ msg_fatal("fstat %s: %m", path);
+ if (vstream_ferror(fp) || vstream_fclose(fp))
+ msg_fatal("read %s: %m", path);
+ after = time((time_t *) 0);
+ if (st.st_mtime < before - 1 || st.st_mtime > after)
+ break;
+ if (msg_verbose)
+ msg_info("pausing to let %s cool down", path);
+ doze(300000);
+ }
+}
diff --git a/postfix/src/util/load_file.h b/postfix/src/util/load_file.h
new file mode 100644
index 000000000..3e635f37f
--- /dev/null
+++ b/postfix/src/util/load_file.h
@@ -0,0 +1,32 @@
+#ifndef LOAD_FILE_H_INCLUDED_
+#define LOAD_FILE_H_INCLUDED_
+
+/*++
+/* NAME
+/* load_file 3h
+/* SUMMARY
+/* load file with some prejudice
+/* SYNOPSIS
+/* #include
+/* DESCRIPTION
+/* .nf
+
+ /*
+ * External interface.
+ */
+typedef void (*LOAD_FILE_FN)(VSTREAM *, void *);
+
+extern void load_file(const char *, LOAD_FILE_FN, void *);
+
+/* 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
diff --git a/postfix/src/util/sys_defs.h b/postfix/src/util/sys_defs.h
index 6c52e02c6..17d7968cf 100644
--- a/postfix/src/util/sys_defs.h
+++ b/postfix/src/util/sys_defs.h
@@ -50,7 +50,7 @@
#endif
#define GETTIMEOFDAY(t) gettimeofday(t,(struct timezone *) 0)
#define ROOT_PATH "/bin:/usr/bin:/sbin:/usr/sbin"
-#if (defined(__NetBSD_Version__) && __NetBSD_Version__ > 200040000)
+#if (defined(__NetBSD_Version__) && __NetBSD_Version__ > 299000900)
# define USE_STATVFS
# define STATVFS_IN_SYS_STATVFS_H
#else
@@ -122,7 +122,7 @@
#define SOCKOPT_SIZE socklen_t
#endif
-#if __NetBSD_Version__ >= 200060000 /* 2.0F */
+#if __NetBSD_Version__ >= 299000900 /* 2.99.9 */
#define HAS_CLOSEFROM
#endif
@@ -155,6 +155,7 @@
#define DEF_DB_TYPE "hash"
#define ALIAS_DB_MAP "hash:/etc/aliases"
#define GETTIMEOFDAY(t) gettimeofday(t,(struct timezone *) 0)
+#define RESOLVE_H_NEEDS_NAMESER8_COMPAT_H
#define ROOT_PATH "/bin:/usr/bin:/sbin:/usr/sbin"
#define USE_STATFS
#define STATFS_IN_SYS_MOUNT_H