mirror of
https://github.com/vdukhovni/postfix
synced 2025-08-30 13:48:06 +00:00
postfix-2.3-20051117
This commit is contained in:
parent
8f6da00739
commit
946a1ba20d
1
postfix/.indent.pro
vendored
1
postfix/.indent.pro
vendored
@ -22,6 +22,7 @@
|
||||
-TBOUNCE_LOG_RCPT_BUF
|
||||
-TBOUNCE_STAT
|
||||
-TBOUNCE_TEMPLATE
|
||||
-TBOUNCE_TEMPLATES
|
||||
-TBOUNCE_TIME_DIVISOR
|
||||
-TBOUNCE_TIME_PARAMETER
|
||||
-TCFG_PARSER
|
||||
|
@ -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,
|
||||
|
@ -217,7 +217,7 @@ POSTCONF(1) POSTCONF(1)
|
||||
/etc/postfix/main.cf, Postfix configuration parameters
|
||||
|
||||
<b>SEE ALSO</b>
|
||||
<a href="bounce.5.html">bounce(5)</a>, bouce template file format
|
||||
<a href="bounce.5.html">bounce(5)</a>, bounce template file format
|
||||
<a href="postconf.5.html">postconf(5)</a>, configuration parameters
|
||||
|
||||
<b>README FILES</b>
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -142,6 +142,7 @@
|
||||
#include <vstring.h>
|
||||
#include <vstream.h>
|
||||
#include <stringops.h>
|
||||
#include <load_file.h>
|
||||
|
||||
/* Global library. */
|
||||
|
||||
@ -160,7 +161,7 @@
|
||||
|
||||
/* Application-specific. */
|
||||
|
||||
#include "bounce_service.h"
|
||||
#include <bounce_service.h>
|
||||
|
||||
/*
|
||||
* 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.
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -18,6 +18,11 @@
|
||||
*/
|
||||
#include <bounce_log.h>
|
||||
|
||||
/*
|
||||
* Application-specific.
|
||||
*/
|
||||
#include <bounce_template.h>
|
||||
|
||||
/*
|
||||
* 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);
|
||||
|
@ -2,61 +2,90 @@
|
||||
/* NAME
|
||||
/* bounce_template 3
|
||||
/* SUMMARY
|
||||
/* bounce template processing
|
||||
/* bounce template support
|
||||
/* SYNOPSIS
|
||||
/* #include "bounce_service.h"
|
||||
/* #include <bounce_template.h>
|
||||
/*
|
||||
/* 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 <split_at.h>
|
||||
#include <stringops.h>
|
||||
#include <mymalloc.h>
|
||||
#include <dict_ml.h>
|
||||
|
||||
/* Global library. */
|
||||
|
||||
#include <mail_params.h>
|
||||
#include <mail_conf.h>
|
||||
#include <mail_addr.h>
|
||||
#include <post_mail.h>
|
||||
#include <is_header.h>
|
||||
#include <mail_proto.h>
|
||||
#include <mail_conf.h>
|
||||
#include <is_header.h>
|
||||
|
||||
/* Application-specific. */
|
||||
|
||||
#include <bounce_service.h>
|
||||
|
||||
/*
|
||||
* 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 <bounce_template.h>
|
||||
|
||||
/*
|
||||
* 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 = <<EOF\n", tp->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 = <<EOF\n", tp->class);
|
||||
bounce_template_expand(bounce_plain_out, VSTREAM_OUT, tp);
|
||||
tp = DELAY_TEMPLATE();
|
||||
vstream_fprintf(VSTREAM_OUT, "EOF\n\nexpanded_%s_text = <<EOF\n", tp->class);
|
||||
bounce_template_expand(bounce_plain_out, VSTREAM_OUT, tp);
|
||||
tp = SUCCESS_TEMPLATE();
|
||||
vstream_fprintf(VSTREAM_OUT, "EOF\n\nexpanded_%s_text = <<EOF\n", tp->class);
|
||||
bounce_template_expand(bounce_plain_out, VSTREAM_OUT, tp);
|
||||
tp = VERIFY_TEMPLATE();
|
||||
vstream_fprintf(VSTREAM_OUT, "EOF\n\nexpanded_%s_text = <<EOF\n", tp->class);
|
||||
bounce_template_expand(bounce_plain_out, VSTREAM_OUT, tp);
|
||||
vstream_fprintf(VSTREAM_OUT, "EOF\n");
|
||||
vstream_fprintf(fp, "%s\n", *cpp);
|
||||
}
|
||||
|
94
postfix/src/bounce/bounce_template.h
Normal file
94
postfix/src/bounce/bounce_template.h
Normal file
@ -0,0 +1,94 @@
|
||||
#ifndef _BOUNCE_TEMPLATE_H_INCLUDED_
|
||||
#define _BOUNCE_TEMPLATE_H_INCLUDED_
|
||||
|
||||
/*++
|
||||
/* NAME
|
||||
/* bounce_template 3h
|
||||
/* SUMMARY
|
||||
/* bounce template support
|
||||
/* SYNOPSIS
|
||||
/* #include <bounce_template.h>
|
||||
/* DESCRIPTION
|
||||
/* .nf
|
||||
|
||||
/*
|
||||
* Utility library.
|
||||
*/
|
||||
#include <vstream.h>
|
||||
|
||||
/*
|
||||
* 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
|
390
postfix/src/bounce/bounce_templates.c
Normal file
390
postfix/src/bounce/bounce_templates.c
Normal file
@ -0,0 +1,390 @@
|
||||
/*++
|
||||
/* NAME
|
||||
/* bounce_templates 3
|
||||
/* SUMMARY
|
||||
/* bounce template group support
|
||||
/* SYNOPSIS
|
||||
/* #include <bounce_template.h>
|
||||
/*
|
||||
/* 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 <sys_defs.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
|
||||
/* Utility library. */
|
||||
|
||||
#include <msg.h>
|
||||
#include <mymalloc.h>
|
||||
#include <stringops.h>
|
||||
#include <vstring.h>
|
||||
#include <vstream.h>
|
||||
#include <vstring_vstream.h>
|
||||
|
||||
/* Global library. */
|
||||
|
||||
#include <mail_addr.h>
|
||||
#include <mail_proto.h>
|
||||
|
||||
/* Application-specific. */
|
||||
|
||||
#include <bounce_template.h>
|
||||
|
||||
/*
|
||||
* 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 = <<EOF\n", tp->class);
|
||||
bounce_template_expand(bounce_plain_out, fp, tp);
|
||||
vstream_fprintf(fp, "EOF\n\n");
|
||||
|
||||
tp = ts->delay;
|
||||
vstream_fprintf(fp, "expanded_%s_text = <<EOF\n", tp->class);
|
||||
bounce_template_expand(bounce_plain_out, fp, tp);
|
||||
vstream_fprintf(fp, "EOF\n\n");
|
||||
|
||||
tp = ts->success;
|
||||
vstream_fprintf(fp, "expanded_%s_text = <<EOF\n", tp->class);
|
||||
bounce_template_expand(bounce_plain_out, fp, tp);
|
||||
vstream_fprintf(fp, "EOF\n\n");
|
||||
|
||||
tp = ts->verify;
|
||||
vstream_fprintf(fp, "expanded_%s_text = <<EOF\n", tp->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 = <<EOF\n", tp->class);
|
||||
bounce_template_dump(fp, tp);
|
||||
vstream_fprintf(fp, "EOF\n\n");
|
||||
|
||||
tp = ts->delay;
|
||||
vstream_fprintf(fp, "%s_template = <<EOF\n", tp->class);
|
||||
bounce_template_dump(fp, tp);
|
||||
vstream_fprintf(fp, "EOF\n\n");
|
||||
|
||||
tp = ts->success;
|
||||
vstream_fprintf(fp, "%s_template = <<EOF\n", tp->class);
|
||||
bounce_template_dump(fp, tp);
|
||||
vstream_fprintf(fp, "EOF\n\n");
|
||||
|
||||
tp = ts->verify;
|
||||
vstream_fprintf(fp, "%s_template = <<EOF\n", tp->class);
|
||||
bounce_template_dump(fp, tp);
|
||||
vstream_fprintf(fp, "EOF\n");
|
||||
}
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -1,179 +0,0 @@
|
||||
/*++
|
||||
/* NAME
|
||||
/* dict 3
|
||||
/* SUMMARY
|
||||
/* dictionary manager, multi-line entry support
|
||||
/* SYNOPSIS
|
||||
/* #include <dict_ml.h>
|
||||
/*
|
||||
/* 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 = <<EOF
|
||||
/* text here...
|
||||
/* EOF
|
||||
/* .in -4
|
||||
/* .ad
|
||||
/* .fi
|
||||
/*
|
||||
/* Leading or trailing white space is not stripped from
|
||||
/* multi-line values.
|
||||
/* .IP \(bu
|
||||
/* The following input is ignored outside "<<" context: empty
|
||||
/* lines, all whitespace lines, and lines whose first
|
||||
/* non-whitespace character is "#".
|
||||
/* .PP
|
||||
/* dict_ml_load_file() enters (name, value) pairs from the
|
||||
/* specified file to the specified dictionary.
|
||||
/*
|
||||
/* dict_ml_load_fp() reads (name, value) pairs from an open
|
||||
/* stream. It has the same semantics as dict_ml_load_file().
|
||||
/* SEE ALSO
|
||||
/* dict(3)
|
||||
/* DIAGNOSTICS
|
||||
/* Fatal errors: out of memory, malformed macro name, missing
|
||||
/* or mal-formed end marker.
|
||||
/* 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 <sys_defs.h>
|
||||
#include <sys/stat.h>
|
||||
#include <time.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
|
||||
/* Utility library. */
|
||||
|
||||
#include <msg.h>
|
||||
#include <vstring.h>
|
||||
#include <vstream.h>
|
||||
#include <vstring_vstream.h>
|
||||
#include <iostuff.h>
|
||||
#include <stringops.h>
|
||||
#include <dict.h>
|
||||
#include <dict_ml.h>
|
||||
|
||||
#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);
|
||||
}
|
||||
}
|
@ -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 <dict_ml.h>
|
||||
/* DESCRIPTION
|
||||
/* .nf
|
||||
|
||||
/*
|
||||
* Utility library.
|
||||
*/
|
||||
#include <vstream.h>
|
||||
#include <dict.h>
|
||||
|
||||
/*
|
||||
* 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
|
68
postfix/src/bounce/template_test.ref
Normal file
68
postfix/src/bounce/template_test.ref
Normal file
@ -0,0 +1,68 @@
|
||||
failure_template = <<EOF
|
||||
Charset: us-ascii
|
||||
From: MAILER-DAEMON (Mail Delivery System)
|
||||
Subject: Undelivered Mail Returned to Sender
|
||||
Postmaster-Subject: Postmaster Copy: Undelivered Mail
|
||||
|
||||
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 <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
|
||||
EOF
|
||||
|
||||
delay_template = <<EOF
|
||||
Charset: us-ascii
|
||||
From: MAILER-DAEMON (Mail Delivery System)
|
||||
Subject: Delayed Mail (still being retried)
|
||||
Postmaster-Subject: Postmaster Warning: Delayed Mail
|
||||
|
||||
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 <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
|
||||
EOF
|
||||
|
||||
success_template = <<EOF
|
||||
Charset: us-ascii
|
||||
From: MAILER-DAEMON (Mail Delivery System)
|
||||
Subject: Successful Mail Delivery Report
|
||||
|
||||
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
|
||||
EOF
|
||||
|
||||
verify_template = <<EOF
|
||||
Charset: us-ascii
|
||||
From: MAILER-DAEMON (Mail Delivery System)
|
||||
Subject: Mail Delivery Status Report
|
||||
|
||||
This is the $mail_name program at host $myhostname.
|
||||
|
||||
Enclosed is the mail delivery report that you requested.
|
||||
|
||||
The $mail_name program
|
||||
EOF
|
@ -19,6 +19,9 @@
|
||||
#ifdef RESOLVE_H_NEEDS_STDIO_H
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
#ifdef RESOLVE_H_NEEDS_NAMESER8_COMPAT_H
|
||||
#include <nameser8_compat.h>
|
||||
#endif
|
||||
#include <resolv.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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
79
postfix/src/util/load_file.c
Normal file
79
postfix/src/util/load_file.c
Normal file
@ -0,0 +1,79 @@
|
||||
/*++
|
||||
/* NAME
|
||||
/* load_file 3
|
||||
/* SUMMARY
|
||||
/* load file with some prejudice
|
||||
/* SYNOPSIS
|
||||
/* #include <load_file.h>
|
||||
/*
|
||||
/* 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 <sys_defs.h>
|
||||
#include <sys/stat.h>
|
||||
#include <time.h>
|
||||
|
||||
/* Utility library. */
|
||||
|
||||
#include <msg.h>
|
||||
#include <vstream.h>
|
||||
#include <iostuff.h>
|
||||
#include <load_file.h>
|
||||
|
||||
/* 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);
|
||||
}
|
||||
}
|
32
postfix/src/util/load_file.h
Normal file
32
postfix/src/util/load_file.h
Normal file
@ -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 <load_file.h>
|
||||
/* 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
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user