2
0
mirror of https://github.com/vdukhovni/postfix synced 2025-08-30 05:38:06 +00:00

postfix-2.3-20051117

This commit is contained in:
Wietse Venema 2005-11-17 00:00:00 -05:00 committed by Viktor Dukhovni
parent 8f6da00739
commit 946a1ba20d
26 changed files with 1105 additions and 781 deletions

1
postfix/.indent.pro vendored
View File

@ -22,6 +22,7 @@
-TBOUNCE_LOG_RCPT_BUF
-TBOUNCE_STAT
-TBOUNCE_TEMPLATE
-TBOUNCE_TEMPLATES
-TBOUNCE_TIME_DIVISOR
-TBOUNCE_TIME_PARAMETER
-TCFG_PARSER

View File

@ -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,

View File

@ -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>

View File

@ -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

View File

@ -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

View File

@ -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.

View File

@ -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

View File

@ -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);

View File

@ -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)

View File

@ -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)

View File

@ -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);

View File

@ -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);
}

View 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

View 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");
}

View File

@ -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

View File

@ -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

View File

@ -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);
}
}

View File

@ -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

View 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

View File

@ -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>
/*

View File

@ -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

View File

@ -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

View File

@ -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

View 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);
}
}

View 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

View File

@ -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