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