mirror of
https://github.com/vdukhovni/postfix
synced 2025-08-31 14:17:41 +00:00
postfix-2.5-20071223
This commit is contained in:
committed by
Viktor Dukhovni
parent
99dd94c9fd
commit
a82a55628d
1
postfix/.indent.pro
vendored
1
postfix/.indent.pro
vendored
@@ -143,6 +143,7 @@
|
||||
-TMILTER
|
||||
-TMILTER8
|
||||
-TMILTERS
|
||||
-TMILTER_MACROS
|
||||
-TMILTER_MSG_CONTEXT
|
||||
-TMIME_ENCODING
|
||||
-TMIME_INFO
|
||||
|
@@ -14053,3 +14053,12 @@ Apologies for any names omitted.
|
||||
|
||||
Further polishing of the Milter code and logging. File:
|
||||
milter/milter8.c.
|
||||
|
||||
20071123
|
||||
|
||||
Further polishing of the Milter code. With SETSYMLIST, each
|
||||
Milter can update its own macros instead of clobbering
|
||||
the global copy is shared with other Milters. Also an
|
||||
opportunity to clean up some ad-hoc code for sending macro
|
||||
lists from smtp(8) to cleanup(8). Files: milter/milter.c,
|
||||
milter/milter8.c, milter/milter_macros.c.
|
||||
|
@@ -16,7 +16,7 @@
|
||||
/* specified attribute scan routine. dsb_scan() is meant
|
||||
/* to be passed as a call-back to attr_scan(), thusly:
|
||||
/*
|
||||
/* ... ATTR_SCAN_FUNC, dsb_scan, (void *) &dsbuf, ...
|
||||
/* ... ATTR_TYPE_FUNC, dsb_scan, (void *) &dsbuf, ...
|
||||
/* DIAGNOSTICS
|
||||
/* Fatal: out of memory.
|
||||
/* LICENSE
|
||||
|
@@ -16,7 +16,7 @@
|
||||
/* the specified attribute print routine. dsn_print() is meant
|
||||
/* to be passed as a call-back to attr_print(), thusly:
|
||||
/*
|
||||
/* ... ATTR_PRINT_FUNC, dsn_print, (void *) dsn, ...
|
||||
/* ... ATTR_TYPE_FUNC, dsn_print, (void *) dsn, ...
|
||||
/* DIAGNOSTICS
|
||||
/* Fatal: out of memory.
|
||||
/* LICENSE
|
||||
|
@@ -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 "20071222"
|
||||
#define MAIL_RELEASE_DATE "20071223"
|
||||
#define MAIL_VERSION_NUMBER "2.5"
|
||||
|
||||
#ifdef SNAPSHOT
|
||||
|
@@ -17,7 +17,7 @@
|
||||
/* msg_stats_print() is meant to be passed as a call-back to
|
||||
/* attr_print(), thusly:
|
||||
/*
|
||||
/* ... ATTR_PRINT_FUNC, msg_stats_print, (void *) stats, ...
|
||||
/* ... ATTR_TYPE_FUNC, msg_stats_print, (void *) stats, ...
|
||||
/* DIAGNOSTICS
|
||||
/* Fatal: out of memory.
|
||||
/* LICENSE
|
||||
|
@@ -41,7 +41,7 @@
|
||||
/* using the specified attribute scan routine. rcpb_scan()
|
||||
/* is meant to be passed as a call-back to attr_scan(), thusly:
|
||||
/*
|
||||
/* ... ATTR_SCAN_FUNC, rcpb_scan, (void *) rcpt_buf, ...
|
||||
/* ... ATTR_TYPE_FUNC, rcpb_scan, (void *) rcpt_buf, ...
|
||||
/*
|
||||
/* rcpb_create(), rcpb_reset() and rcpb_free() create, wipe
|
||||
/* and destroy recipient buffer instances.
|
||||
|
@@ -17,7 +17,7 @@
|
||||
/* routine. rcpt_print() is meant to be passed as a call-back
|
||||
/* to attr_print(), thusly:
|
||||
/*
|
||||
/* ... ATTR_PRINT_FUNC, rcpt_print, (void *) recipient, ...
|
||||
/* ... ATTR_TYPE_FUNC, rcpt_print, (void *) recipient, ...
|
||||
/* DIAGNOSTICS
|
||||
/* Fatal: out of memory.
|
||||
/* LICENSE
|
||||
|
@@ -1,6 +1,6 @@
|
||||
SHELL = /bin/sh
|
||||
SRCS = milter.c milter8.c
|
||||
OBJS = milter.o milter8.o
|
||||
SRCS = milter.c milter8.c milter_macros.c
|
||||
OBJS = milter.o milter8.o milter_macros.o
|
||||
HDRS = milter.h
|
||||
TESTSRC =
|
||||
DEFS = -I. -I$(INC_DIR) -D$(SYSTYPE)
|
||||
@@ -117,4 +117,15 @@ milter8.o: ../../include/vstream.h
|
||||
milter8.o: ../../include/vstring.h
|
||||
milter8.o: milter.h
|
||||
milter8.o: milter8.c
|
||||
milter_macros.o: ../../include/argv.h
|
||||
milter_macros.o: ../../include/attr.h
|
||||
milter_macros.o: ../../include/iostuff.h
|
||||
milter_macros.o: ../../include/mail_proto.h
|
||||
milter_macros.o: ../../include/mymalloc.h
|
||||
milter_macros.o: ../../include/sys_defs.h
|
||||
milter_macros.o: ../../include/vbuf.h
|
||||
milter_macros.o: ../../include/vstream.h
|
||||
milter_macros.o: ../../include/vstring.h
|
||||
milter_macros.o: milter.h
|
||||
milter_macros.o: milter_macros.c
|
||||
test-milter.o: test-milter.c
|
||||
|
@@ -310,15 +310,27 @@ const char *milter_conn_event(MILTERS *milters,
|
||||
{
|
||||
const char *resp;
|
||||
MILTER *m;
|
||||
ARGV *macros;
|
||||
ARGV *global_macros = 0;
|
||||
ARGV *any_macros;
|
||||
|
||||
#define MILTER_MACRO_EVAL(global_macros, m, milters, member) \
|
||||
((m->macros && m->macros->member[0]) ? \
|
||||
milter_macro_lookup(milters, m->macros->member) : \
|
||||
global_macros ? global_macros : \
|
||||
(global_macros = \
|
||||
milter_macro_lookup(milters, milters->macros->member)))
|
||||
|
||||
if (msg_verbose)
|
||||
msg_info("report connect to all milters");
|
||||
macros = milter_macro_lookup(milters, milters->conn_macros);
|
||||
for (resp = 0, m = milters->milter_list; resp == 0 && m != 0; m = m->next)
|
||||
for (resp = 0, m = milters->milter_list; resp == 0 && m != 0; m = m->next) {
|
||||
any_macros = MILTER_MACRO_EVAL(global_macros, m, milters, conn_macros);
|
||||
resp = m->conn_event(m, client_name, client_addr, client_port,
|
||||
addr_family, macros);
|
||||
argv_free(macros);
|
||||
addr_family, any_macros);
|
||||
if (any_macros != global_macros)
|
||||
argv_free(any_macros);
|
||||
}
|
||||
if (global_macros)
|
||||
argv_free(global_macros);
|
||||
return (resp);
|
||||
}
|
||||
|
||||
@@ -329,16 +341,19 @@ const char *milter_helo_event(MILTERS *milters, const char *helo_name,
|
||||
{
|
||||
const char *resp;
|
||||
MILTER *m;
|
||||
ARGV *macros;
|
||||
ARGV *global_macros = 0;
|
||||
ARGV *any_macros;
|
||||
|
||||
if (msg_verbose)
|
||||
msg_info("report helo to all milters");
|
||||
macros = milters->helo_macros == 0 ? 0 :
|
||||
milter_macro_lookup(milters, milters->helo_macros);
|
||||
for (resp = 0, m = milters->milter_list; resp == 0 && m != 0; m = m->next)
|
||||
resp = m->helo_event(m, helo_name, esmtp_flag, macros);
|
||||
if (macros)
|
||||
argv_free(macros);
|
||||
for (resp = 0, m = milters->milter_list; resp == 0 && m != 0; m = m->next) {
|
||||
any_macros = MILTER_MACRO_EVAL(global_macros, m, milters, helo_macros);
|
||||
resp = m->helo_event(m, helo_name, esmtp_flag, any_macros);
|
||||
if (any_macros != global_macros)
|
||||
argv_free(any_macros);
|
||||
}
|
||||
if (global_macros)
|
||||
argv_free(global_macros);
|
||||
return (resp);
|
||||
}
|
||||
|
||||
@@ -348,16 +363,19 @@ const char *milter_mail_event(MILTERS *milters, const char **argv)
|
||||
{
|
||||
const char *resp;
|
||||
MILTER *m;
|
||||
ARGV *macros;
|
||||
ARGV *global_macros = 0;
|
||||
ARGV *any_macros;
|
||||
|
||||
if (msg_verbose)
|
||||
msg_info("report sender to all milters");
|
||||
macros = milters->mail_macros == 0 ? 0 :
|
||||
milter_macro_lookup(milters, milters->mail_macros);
|
||||
for (resp = 0, m = milters->milter_list; resp == 0 && m != 0; m = m->next)
|
||||
resp = m->mail_event(m, argv, macros);
|
||||
if (macros)
|
||||
argv_free(macros);
|
||||
for (resp = 0, m = milters->milter_list; resp == 0 && m != 0; m = m->next) {
|
||||
any_macros = MILTER_MACRO_EVAL(global_macros, m, milters, mail_macros);
|
||||
resp = m->mail_event(m, argv, any_macros);
|
||||
if (any_macros != global_macros)
|
||||
argv_free(any_macros);
|
||||
}
|
||||
if (global_macros)
|
||||
argv_free(global_macros);
|
||||
return (resp);
|
||||
}
|
||||
|
||||
@@ -367,16 +385,19 @@ const char *milter_rcpt_event(MILTERS *milters, const char **argv)
|
||||
{
|
||||
const char *resp;
|
||||
MILTER *m;
|
||||
ARGV *macros;
|
||||
ARGV *global_macros = 0;
|
||||
ARGV *any_macros;
|
||||
|
||||
if (msg_verbose)
|
||||
msg_info("report recipient to all milters");
|
||||
macros = milters->rcpt_macros == 0 ? 0 :
|
||||
milter_macro_lookup(milters, milters->rcpt_macros);
|
||||
for (resp = 0, m = milters->milter_list; resp == 0 && m != 0; m = m->next)
|
||||
resp = m->rcpt_event(m, argv, macros);
|
||||
if (macros)
|
||||
argv_free(macros);
|
||||
for (resp = 0, m = milters->milter_list; resp == 0 && m != 0; m = m->next) {
|
||||
any_macros = MILTER_MACRO_EVAL(global_macros, m, milters, rcpt_macros);
|
||||
resp = m->rcpt_event(m, argv, any_macros);
|
||||
if (any_macros != global_macros)
|
||||
argv_free(any_macros);
|
||||
}
|
||||
if (global_macros)
|
||||
argv_free(global_macros);
|
||||
return (resp);
|
||||
}
|
||||
|
||||
@@ -384,26 +405,21 @@ const char *milter_rcpt_event(MILTERS *milters, const char **argv)
|
||||
|
||||
const char *milter_data_event(MILTERS *milters)
|
||||
{
|
||||
const char *myname = "milter_data_event";
|
||||
const char *resp;
|
||||
MILTER *m;
|
||||
ARGV *macros = 0;
|
||||
ARGV *global_macros = 0;
|
||||
ARGV *any_macros;
|
||||
|
||||
if (msg_verbose)
|
||||
msg_info("report data to all milters");
|
||||
for (resp = 0, m = milters->milter_list; resp == 0 && m != 0; m = m->next) {
|
||||
if (m->data_event) {
|
||||
if (macros == 0 && milters->data_macros)
|
||||
macros = milter_macro_lookup(milters, milters->data_macros);
|
||||
resp = m->data_event(m, macros);
|
||||
} else {
|
||||
if (msg_verbose)
|
||||
msg_info("%s: skip milter %s (command unimplemented)",
|
||||
myname, m->name);
|
||||
}
|
||||
any_macros = MILTER_MACRO_EVAL(global_macros, m, milters, data_macros);
|
||||
resp = m->data_event(m, any_macros);
|
||||
if (any_macros != global_macros)
|
||||
argv_free(any_macros);
|
||||
}
|
||||
if (macros)
|
||||
argv_free(macros);
|
||||
if (global_macros)
|
||||
argv_free(global_macros);
|
||||
return (resp);
|
||||
}
|
||||
|
||||
@@ -411,26 +427,21 @@ const char *milter_data_event(MILTERS *milters)
|
||||
|
||||
const char *milter_unknown_event(MILTERS *milters, const char *command)
|
||||
{
|
||||
const char *myname = "milter_unknown_event";
|
||||
const char *resp;
|
||||
MILTER *m;
|
||||
ARGV *macros = 0;
|
||||
ARGV *global_macros = 0;
|
||||
ARGV *any_macros;
|
||||
|
||||
if (msg_verbose)
|
||||
msg_info("report unknown command to all milters");
|
||||
for (resp = 0, m = milters->milter_list; resp == 0 && m != 0; m = m->next) {
|
||||
if (m->unknown_event) {
|
||||
if (macros == 0 && milters->unk_macros)
|
||||
macros = milter_macro_lookup(milters, milters->unk_macros);
|
||||
resp = m->unknown_event(m, command, macros);
|
||||
} else {
|
||||
if (msg_verbose)
|
||||
msg_info("%s: skip milter %s (command unimplemented)",
|
||||
myname, m->name);
|
||||
}
|
||||
any_macros = MILTER_MACRO_EVAL(global_macros, m, milters, unk_macros);
|
||||
resp = m->unknown_event(m, command, any_macros);
|
||||
if (any_macros != global_macros)
|
||||
argv_free(any_macros);
|
||||
}
|
||||
if (macros)
|
||||
argv_free(macros);
|
||||
if (global_macros)
|
||||
argv_free(global_macros);
|
||||
return (resp);
|
||||
}
|
||||
|
||||
@@ -454,21 +465,26 @@ const char *milter_message(MILTERS *milters, VSTREAM *fp, off_t data_offset)
|
||||
{
|
||||
const char *resp;
|
||||
MILTER *m;
|
||||
ARGV *eoh_macros;
|
||||
ARGV *eod_macros;
|
||||
ARGV *global_eoh_macros = 0;
|
||||
ARGV *global_eod_macros = 0;
|
||||
ARGV *any_eoh_macros;
|
||||
ARGV *any_eod_macros;
|
||||
|
||||
if (msg_verbose)
|
||||
msg_info("inspect content by all milters");
|
||||
eoh_macros = milters->eoh_macros == 0 ? 0 :
|
||||
milter_macro_lookup(milters, milters->eoh_macros);
|
||||
eod_macros = milters->eod_macros == 0 ? 0 :
|
||||
milter_macro_lookup(milters, milters->eod_macros);
|
||||
for (resp = 0, m = milters->milter_list; resp == 0 && m != 0; m = m->next)
|
||||
resp = m->message(m, fp, data_offset, eoh_macros, eod_macros);
|
||||
if (eoh_macros)
|
||||
argv_free(eoh_macros);
|
||||
if (eod_macros)
|
||||
argv_free(eod_macros);
|
||||
for (resp = 0, m = milters->milter_list; resp == 0 && m != 0; m = m->next) {
|
||||
any_eoh_macros = MILTER_MACRO_EVAL(global_eoh_macros, m, milters, eoh_macros);
|
||||
any_eod_macros = MILTER_MACRO_EVAL(global_eod_macros, m, milters, eod_macros);
|
||||
resp = m->message(m, fp, data_offset, any_eoh_macros, any_eod_macros);
|
||||
if (any_eoh_macros != global_eoh_macros)
|
||||
argv_free(any_eoh_macros);
|
||||
if (any_eod_macros != global_eod_macros)
|
||||
argv_free(any_eod_macros);
|
||||
}
|
||||
if (global_eoh_macros)
|
||||
argv_free(global_eoh_macros);
|
||||
if (global_eod_macros)
|
||||
argv_free(global_eod_macros);
|
||||
return (resp);
|
||||
}
|
||||
|
||||
@@ -496,22 +512,15 @@ void milter_disc_event(MILTERS *milters)
|
||||
m->disc_event(m);
|
||||
}
|
||||
|
||||
/* milter_create - create milter list */
|
||||
/* milter_new - create milter list */
|
||||
|
||||
MILTERS *milter_create(const char *names,
|
||||
int conn_timeout,
|
||||
int cmd_timeout,
|
||||
int msg_timeout,
|
||||
const char *protocol,
|
||||
const char *def_action,
|
||||
const char *conn_macros,
|
||||
const char *helo_macros,
|
||||
const char *mail_macros,
|
||||
const char *rcpt_macros,
|
||||
const char *data_macros,
|
||||
const char *eoh_macros,
|
||||
const char *eod_macros,
|
||||
const char *unk_macros)
|
||||
MILTERS *milter_new(const char *names,
|
||||
int conn_timeout,
|
||||
int cmd_timeout,
|
||||
int msg_timeout,
|
||||
const char *protocol,
|
||||
const char *def_action,
|
||||
MILTER_MACROS *macros)
|
||||
{
|
||||
MILTERS *milters;
|
||||
MILTER *head = 0;
|
||||
@@ -544,14 +553,7 @@ MILTERS *milter_create(const char *names,
|
||||
milters->milter_list = head;
|
||||
milters->mac_lookup = 0;
|
||||
milters->mac_context = 0;
|
||||
milters->conn_macros = mystrdup(conn_macros);
|
||||
milters->helo_macros = mystrdup(helo_macros);
|
||||
milters->mail_macros = mystrdup(mail_macros);
|
||||
milters->rcpt_macros = mystrdup(rcpt_macros);
|
||||
milters->data_macros = mystrdup(data_macros);
|
||||
milters->eoh_macros = mystrdup(eoh_macros);
|
||||
milters->eod_macros = mystrdup(eod_macros);
|
||||
milters->unk_macros = mystrdup(unk_macros);
|
||||
milters->macros = macros;
|
||||
milters->add_header = 0;
|
||||
milters->upd_header = milters->ins_header = 0;
|
||||
milters->del_header = 0;
|
||||
@@ -572,39 +574,11 @@ void milter_free(MILTERS *milters)
|
||||
msg_info("free all milters");
|
||||
for (m = milters->milter_list; m != 0; m = next)
|
||||
next = m->next, m->free(m);
|
||||
if (milters->conn_macros)
|
||||
myfree(milters->conn_macros);
|
||||
if (milters->helo_macros)
|
||||
myfree(milters->helo_macros);
|
||||
if (milters->mail_macros)
|
||||
myfree(milters->mail_macros);
|
||||
if (milters->rcpt_macros)
|
||||
myfree(milters->rcpt_macros);
|
||||
if (milters->rcpt_macros)
|
||||
myfree(milters->data_macros);
|
||||
if (milters->eoh_macros)
|
||||
myfree(milters->eoh_macros);
|
||||
if (milters->eod_macros)
|
||||
myfree(milters->eod_macros);
|
||||
if (milters->unk_macros)
|
||||
myfree(milters->unk_macros);
|
||||
if (milters->macros)
|
||||
milter_macros_free(milters->macros);
|
||||
myfree((char *) milters);
|
||||
}
|
||||
|
||||
/*
|
||||
* Temporary protocol to send /receive milter instances. This needs to be
|
||||
* extended with type information when we support both Sendmail8 and
|
||||
* Sendmail X protocols.
|
||||
*/
|
||||
#define MAIL_ATTR_MILT_CONN "conn_macros"
|
||||
#define MAIL_ATTR_MILT_HELO "helo_macros"
|
||||
#define MAIL_ATTR_MILT_MAIL "mail_macros"
|
||||
#define MAIL_ATTR_MILT_RCPT "rcpt_macros"
|
||||
#define MAIL_ATTR_MILT_DATA "data_macros"
|
||||
#define MAIL_ATTR_MILT_EOH "eoh_macros"
|
||||
#define MAIL_ATTR_MILT_EOD "eod_macros"
|
||||
#define MAIL_ATTR_MILT_UNK "unk_macros"
|
||||
|
||||
/* milter_dummy - send empty milter list */
|
||||
|
||||
int milter_dummy(MILTERS *milters, VSTREAM *stream)
|
||||
@@ -640,14 +614,8 @@ int milter_send(MILTERS *milters, VSTREAM *stream)
|
||||
* Send the filter macro names.
|
||||
*/
|
||||
(void) attr_print(stream, ATTR_FLAG_MORE,
|
||||
ATTR_TYPE_STR, MAIL_ATTR_MILT_CONN, milters->conn_macros,
|
||||
ATTR_TYPE_STR, MAIL_ATTR_MILT_HELO, milters->helo_macros,
|
||||
ATTR_TYPE_STR, MAIL_ATTR_MILT_MAIL, milters->mail_macros,
|
||||
ATTR_TYPE_STR, MAIL_ATTR_MILT_RCPT, milters->rcpt_macros,
|
||||
ATTR_TYPE_STR, MAIL_ATTR_MILT_DATA, milters->data_macros,
|
||||
ATTR_TYPE_STR, MAIL_ATTR_MILT_EOH, milters->eoh_macros,
|
||||
ATTR_TYPE_STR, MAIL_ATTR_MILT_EOD, milters->eod_macros,
|
||||
ATTR_TYPE_STR, MAIL_ATTR_MILT_UNK, milters->unk_macros,
|
||||
ATTR_TYPE_FUNC, milter_macros_print,
|
||||
(void *) milters->macros,
|
||||
ATTR_TYPE_END);
|
||||
|
||||
/*
|
||||
@@ -675,44 +643,12 @@ MILTERS *milter_receive(VSTREAM *stream, int count)
|
||||
MILTER *head = 0;
|
||||
MILTER *tail = 0;
|
||||
MILTER *milter = 0;
|
||||
VSTRING *conn_macros;
|
||||
VSTRING *helo_macros;
|
||||
VSTRING *mail_macros;
|
||||
VSTRING *rcpt_macros;
|
||||
VSTRING *data_macros;
|
||||
VSTRING *eoh_macros;
|
||||
VSTRING *eod_macros;
|
||||
VSTRING *unk_macros;
|
||||
MILTER_MACROS *macros = milter_macros_alloc(MILTER_MACROS_ALLOC_ZERO);
|
||||
|
||||
/*
|
||||
* Receive filter macros.
|
||||
*/
|
||||
#define FREE_BUFFERS() do { \
|
||||
vstring_free(conn_macros); vstring_free(helo_macros); \
|
||||
vstring_free(mail_macros); vstring_free(rcpt_macros); \
|
||||
vstring_free(data_macros); vstring_free(eoh_macros); \
|
||||
vstring_free(eod_macros); vstring_free(unk_macros); \
|
||||
} while (0)
|
||||
|
||||
conn_macros = vstring_alloc(10);
|
||||
helo_macros = vstring_alloc(10);
|
||||
mail_macros = vstring_alloc(10);
|
||||
rcpt_macros = vstring_alloc(10);
|
||||
data_macros = vstring_alloc(10);
|
||||
eoh_macros = vstring_alloc(10);
|
||||
eod_macros = vstring_alloc(10);
|
||||
unk_macros = vstring_alloc(10);
|
||||
if (attr_scan(stream, ATTR_FLAG_STRICT | ATTR_FLAG_MORE,
|
||||
ATTR_TYPE_STR, MAIL_ATTR_MILT_CONN, conn_macros,
|
||||
ATTR_TYPE_STR, MAIL_ATTR_MILT_HELO, helo_macros,
|
||||
ATTR_TYPE_STR, MAIL_ATTR_MILT_MAIL, mail_macros,
|
||||
ATTR_TYPE_STR, MAIL_ATTR_MILT_RCPT, rcpt_macros,
|
||||
ATTR_TYPE_STR, MAIL_ATTR_MILT_DATA, data_macros,
|
||||
ATTR_TYPE_STR, MAIL_ATTR_MILT_EOH, eoh_macros,
|
||||
ATTR_TYPE_STR, MAIL_ATTR_MILT_EOD, eod_macros,
|
||||
ATTR_TYPE_STR, MAIL_ATTR_MILT_UNK, unk_macros,
|
||||
ATTR_TYPE_END) != 8) {
|
||||
FREE_BUFFERS();
|
||||
ATTR_TYPE_FUNC, milter_macros_scan, (void *) macros,
|
||||
ATTR_TYPE_END) != 1) {
|
||||
milter_macros_free(macros);
|
||||
return (0);
|
||||
}
|
||||
#define NO_MILTERS ((char *) 0)
|
||||
@@ -720,12 +656,7 @@ MILTERS *milter_receive(VSTREAM *stream, int count)
|
||||
#define NO_PROTOCOL ((char *) 0)
|
||||
#define NO_ACTION ((char *) 0)
|
||||
|
||||
milters = milter_create(NO_MILTERS, NO_TIMEOUTS, NO_PROTOCOL, NO_ACTION,
|
||||
STR(conn_macros), STR(helo_macros),
|
||||
STR(mail_macros), STR(rcpt_macros),
|
||||
STR(data_macros), STR(eoh_macros),
|
||||
STR(eod_macros), STR(unk_macros));
|
||||
FREE_BUFFERS();
|
||||
milters = milter_new(NO_MILTERS, NO_TIMEOUTS, NO_PROTOCOL, NO_ACTION, macros);
|
||||
|
||||
/*
|
||||
* Receive the filters.
|
||||
|
@@ -18,6 +18,11 @@
|
||||
#include <vstream.h>
|
||||
#include <argv.h>
|
||||
|
||||
/*
|
||||
* Global library.
|
||||
*/
|
||||
#include <attr.h>
|
||||
|
||||
/*
|
||||
* Each Milter handle is an element of a null-terminated linked list. The
|
||||
* functions are virtual so that we can support multiple MTA-side Milter
|
||||
@@ -28,6 +33,7 @@ typedef struct MILTER {
|
||||
char *name; /* full name including transport */
|
||||
struct MILTER *next; /* linkage */
|
||||
struct MILTERS *parent; /* parent information */
|
||||
struct MILTER_MACROS *macros; /* private macros */
|
||||
const char *(*conn_event) (struct MILTER *, const char *, const char *, const char *, unsigned, ARGV *);
|
||||
const char *(*helo_event) (struct MILTER *, const char *, int, ARGV *);
|
||||
const char *(*mail_event) (struct MILTER *, const char **, ARGV *);
|
||||
@@ -46,6 +52,70 @@ typedef struct MILTER {
|
||||
extern MILTER *milter8_create(const char *, int, int, int, const char *, const char *, struct MILTERS *);
|
||||
extern MILTER *milter8_receive(VSTREAM *, struct MILTERS *);
|
||||
|
||||
/*
|
||||
* As of Sendmail 8.14 each milter can override the default macro list. If a
|
||||
* Milter has its own macro list, a null member means use the global
|
||||
* definition.
|
||||
*/
|
||||
typedef struct MILTER_MACROS {
|
||||
char *conn_macros; /* macros for connect event */
|
||||
char *helo_macros; /* macros for HELO/EHLO command */
|
||||
char *mail_macros; /* macros for MAIL FROM command */
|
||||
char *rcpt_macros; /* macros for RCPT TO command */
|
||||
char *data_macros; /* macros for DATA command */
|
||||
char *eoh_macros; /* macros for end-of-headers */
|
||||
char *eod_macros; /* macros for END-OF-DATA command */
|
||||
char *unk_macros; /* macros for unknown command */
|
||||
} MILTER_MACROS;
|
||||
|
||||
extern MILTER_MACROS *milter_macros_create(const char *, const char *,
|
||||
const char *, const char *,
|
||||
const char *, const char *,
|
||||
const char *, const char *);
|
||||
extern MILTER_MACROS *milter_macros_alloc(int);
|
||||
extern void milter_macros_free(MILTER_MACROS *);
|
||||
extern int milter_macros_print(ATTR_PRINT_MASTER_FN, VSTREAM *, int, void *);
|
||||
extern int milter_macros_scan(ATTR_SCAN_MASTER_FN, VSTREAM *, int, void *);
|
||||
|
||||
#define MILTER_MACROS_ALLOC_ZERO 1 /* null pointer */
|
||||
#define MILTER_MACROS_ALLOC_EMPTY 2 /* mystrdup(""); */
|
||||
|
||||
#define milter_macros_wipe(mp) do { \
|
||||
MILTER_MACROS *__mp = mp; \
|
||||
if (__mp->conn_macros) \
|
||||
myfree(__mp->conn_macros); \
|
||||
if (__mp->helo_macros) \
|
||||
myfree(__mp->helo_macros); \
|
||||
if (__mp->mail_macros) \
|
||||
myfree(__mp->mail_macros); \
|
||||
if (__mp->rcpt_macros) \
|
||||
myfree(__mp->rcpt_macros); \
|
||||
if (__mp->data_macros) \
|
||||
myfree(__mp->data_macros); \
|
||||
if (__mp->eoh_macros) \
|
||||
myfree(__mp->eoh_macros); \
|
||||
if (__mp->eod_macros) \
|
||||
myfree(__mp->eod_macros); \
|
||||
if (__mp->unk_macros) \
|
||||
myfree(__mp->unk_macros); \
|
||||
} while (0)
|
||||
|
||||
#define milter_macros_zero(mp) milter_macros_init(mp, 0)
|
||||
|
||||
#define milter_macros_init(mp, expr) do { \
|
||||
MILTER_MACROS *__mp = (mp); \
|
||||
char *__expr = (expr); \
|
||||
__mp->conn_macros = __expr; \
|
||||
__mp->helo_macros = __expr; \
|
||||
__mp->mail_macros = __expr; \
|
||||
__mp->rcpt_macros = __expr; \
|
||||
__mp->data_macros = __expr; \
|
||||
__mp->eoh_macros = __expr; \
|
||||
__mp->eod_macros = __expr; \
|
||||
__mp->unk_macros = __expr; \
|
||||
} while (0)
|
||||
|
||||
|
||||
/*
|
||||
* A bunch of Milters.
|
||||
*/
|
||||
@@ -60,14 +130,7 @@ typedef struct MILTERS {
|
||||
MILTER *milter_list; /* linked list of Milters */
|
||||
MILTER_MAC_LOOKUP_FN mac_lookup;
|
||||
void *mac_context; /* macro lookup context */
|
||||
char *conn_macros; /* macros for connect event */
|
||||
char *helo_macros; /* macros for HELO/EHLO command */
|
||||
char *mail_macros; /* macros for MAIL FROM command */
|
||||
char *rcpt_macros; /* macros for RCPT TO command */
|
||||
char *data_macros; /* macros for DATA command */
|
||||
char *eoh_macros; /* macros for end-of-headers */
|
||||
char *eod_macros; /* macros for END-OF-DATA command */
|
||||
char *unk_macros; /* macros for unknown command */
|
||||
struct MILTER_MACROS *macros;
|
||||
void *chg_context; /* context for queue file changes */
|
||||
MILTER_ADD_HEADER_FN add_header;
|
||||
MILTER_EDIT_HEADER_FN upd_header;
|
||||
@@ -78,12 +141,17 @@ typedef struct MILTERS {
|
||||
MILTER_EDIT_BODY_FN repl_body;
|
||||
} MILTERS;
|
||||
|
||||
extern MILTERS *milter_create(const char *, int, int, int,
|
||||
const char *, const char *,
|
||||
const char *, const char *,
|
||||
const char *, const char *,
|
||||
const char *, const char *,
|
||||
const char *, const char *);
|
||||
#define milter_create(milter_names, conn_timeout, cmd_timeout, msg_timeout, \
|
||||
protocol, def_action, conn_macros, helo_macros, \
|
||||
mail_macros, rcpt_macros, data_macros, eoh_macros, \
|
||||
eod_macros, unk_macros) \
|
||||
milter_new(milter_names, conn_timeout, cmd_timeout, msg_timeout, \
|
||||
protocol, def_action, milter_macros_create(conn_macros, \
|
||||
helo_macros, mail_macros, rcpt_macros, data_macros, \
|
||||
eoh_macros, eod_macros, unk_macros))
|
||||
|
||||
extern MILTERS *milter_new(const char *, int, int, int, const char *,
|
||||
const char *, MILTER_MACROS *);
|
||||
extern void milter_macro_callback(MILTERS *, MILTER_MAC_LOOKUP_FN, void *);
|
||||
extern void milter_edit_callback(MILTERS *milters, MILTER_ADD_HEADER_FN,
|
||||
MILTER_EDIT_HEADER_FN, MILTER_EDIT_HEADER_FN,
|
||||
|
@@ -322,17 +322,17 @@ static NAME_CODE smfim_table[] = {
|
||||
* members, without using a switch statement.
|
||||
*/
|
||||
static size_t milter8_macro_offsets[] = {
|
||||
offsetof(MILTERS, conn_macros), /* SMFIM_CONNECT */
|
||||
offsetof(MILTERS, helo_macros), /* SMFIM_HELO */
|
||||
offsetof(MILTERS, mail_macros), /* SMFIM_ENVFROM */
|
||||
offsetof(MILTERS, rcpt_macros), /* SMFIM_ENVRCPT */
|
||||
offsetof(MILTERS, data_macros), /* SMFIM_DATA */
|
||||
offsetof(MILTERS, eod_macros), /* Note: SMFIM_EOM < SMFIM_EOH */
|
||||
offsetof(MILTERS, eoh_macros), /* Note: SMFIM_EOH > SMFIM_EOM */
|
||||
offsetof(MILTER_MACROS, conn_macros), /* SMFIM_CONNECT */
|
||||
offsetof(MILTER_MACROS, helo_macros), /* SMFIM_HELO */
|
||||
offsetof(MILTER_MACROS, mail_macros), /* SMFIM_ENVFROM */
|
||||
offsetof(MILTER_MACROS, rcpt_macros), /* SMFIM_ENVRCPT */
|
||||
offsetof(MILTER_MACROS, data_macros), /* SMFIM_DATA */
|
||||
offsetof(MILTER_MACROS, eod_macros),/* Note: SMFIM_EOM < SMFIM_EOH */
|
||||
offsetof(MILTER_MACROS, eoh_macros),/* Note: SMFIM_EOH > SMFIM_EOM */
|
||||
};
|
||||
|
||||
#define MILTER8_MACRO_PTR(__milters, __type) \
|
||||
((char **) (((char *) (__milters)) + milter8_macro_offsets[(__type)]))
|
||||
#define MILTER8_MACRO_PTR(__macros, __type) \
|
||||
((char **) (((char *) (__macros)) + milter8_macro_offsets[(__type)]))
|
||||
|
||||
/*
|
||||
* How much buffer space is available for sending body content.
|
||||
@@ -1734,6 +1734,8 @@ static void milter8_connect(MILTER8 *milter)
|
||||
const char *smfim_name;
|
||||
char **mac_value_ptr;
|
||||
|
||||
milter->m.macros = milter_macros_alloc(MILTER_MACROS_ALLOC_EMPTY);
|
||||
|
||||
while (data_len > 0
|
||||
&& milter8_read_data(milter, &data_len,
|
||||
MILTER8_DATA_HLONG, &mac_type,
|
||||
@@ -1747,7 +1749,7 @@ static void milter8_connect(MILTER8 *milter)
|
||||
if (msg_verbose)
|
||||
msg_info("override %s macro list with \"%s\"",
|
||||
smfim_name, STR(buf));
|
||||
mac_value_ptr = MILTER8_MACRO_PTR(milter->m.parent, mac_type);
|
||||
mac_value_ptr = MILTER8_MACRO_PTR(milter->m.macros, mac_type);
|
||||
if (*mac_value_ptr != 0)
|
||||
myfree(*mac_value_ptr);
|
||||
*mac_value_ptr = mystrdup(STR(buf));
|
||||
@@ -2467,6 +2469,7 @@ static const char *milter8_message(MILTER *m, VSTREAM *qfile,
|
||||
#define MAIL_ATTR_MILT_CMD "milter_cmd_timeout"
|
||||
#define MAIL_ATTR_MILT_MSG "milter_msg_timeout"
|
||||
#define MAIL_ATTR_MILT_ACT "milter_action"
|
||||
#define MAIL_ATTR_MILT_MAC "milter_macro_list"
|
||||
|
||||
/* milter8_active - report if this milter still wants events */
|
||||
|
||||
@@ -2489,7 +2492,7 @@ static int milter8_send(MILTER *m, VSTREAM *stream)
|
||||
if (msg_verbose)
|
||||
msg_info("%s: milter %s", myname, milter->m.name);
|
||||
|
||||
if (attr_print(stream, ATTR_FLAG_NONE,
|
||||
if (attr_print(stream, ATTR_FLAG_MORE,
|
||||
ATTR_TYPE_STR, MAIL_ATTR_MILT_NAME, milter->m.name,
|
||||
ATTR_TYPE_INT, MAIL_ATTR_MILT_VERS, milter->version,
|
||||
ATTR_TYPE_INT, MAIL_ATTR_MILT_ACTS, milter->rq_mask,
|
||||
@@ -2500,7 +2503,16 @@ static int milter8_send(MILTER *m, VSTREAM *stream)
|
||||
ATTR_TYPE_INT, MAIL_ATTR_MILT_CMD, milter->cmd_timeout,
|
||||
ATTR_TYPE_INT, MAIL_ATTR_MILT_MSG, milter->msg_timeout,
|
||||
ATTR_TYPE_STR, MAIL_ATTR_MILT_ACT, milter->def_action,
|
||||
ATTR_TYPE_INT, MAIL_ATTR_MILT_MAC, milter->m.macros != 0,
|
||||
ATTR_TYPE_END) != 0
|
||||
|| (milter->m.macros != 0
|
||||
&& attr_print(stream, ATTR_FLAG_NONE,
|
||||
ATTR_TYPE_FUNC, milter_macros_print,
|
||||
(void *) milter->m.macros,
|
||||
ATTR_TYPE_END) != 0)
|
||||
|| (milter->m.macros == 0
|
||||
&& attr_print(stream, ATTR_FLAG_NONE,
|
||||
ATTR_TYPE_END) != 0)
|
||||
|| vstream_fflush(stream) != 0) {
|
||||
return (-1);
|
||||
#ifdef CANT_WRITE_BEFORE_SENDING_FD
|
||||
@@ -2524,7 +2536,7 @@ static int milter8_send(MILTER *m, VSTREAM *stream)
|
||||
}
|
||||
|
||||
static MILTER8 *milter8_alloc(const char *, int, int, int, const char *,
|
||||
const char *, MILTERS *);
|
||||
const char *, MILTERS *);
|
||||
|
||||
/* milter8_receive - receive milter instance */
|
||||
|
||||
@@ -2543,12 +2555,20 @@ MILTER *milter8_receive(VSTREAM *stream, MILTERS *parent)
|
||||
int cmd_timeout;
|
||||
int msg_timeout;
|
||||
int fd;
|
||||
int has_macros;
|
||||
MILTER_MACROS *macros = 0;
|
||||
|
||||
#define FREE_MACROS_AND_RETURN(x) do { \
|
||||
if (macros) \
|
||||
milter_macros_free(macros); \
|
||||
return (x); \
|
||||
} while (0)
|
||||
|
||||
if (name_buf == 0) {
|
||||
name_buf = vstring_alloc(10);
|
||||
act_buf = vstring_alloc(10);
|
||||
}
|
||||
if (attr_scan(stream, ATTR_FLAG_STRICT,
|
||||
if (attr_scan(stream, ATTR_FLAG_STRICT | ATTR_FLAG_MORE,
|
||||
ATTR_TYPE_STR, MAIL_ATTR_MILT_NAME, name_buf,
|
||||
ATTR_TYPE_INT, MAIL_ATTR_MILT_VERS, &version,
|
||||
ATTR_TYPE_INT, MAIL_ATTR_MILT_ACTS, &rq_mask,
|
||||
@@ -2559,22 +2579,32 @@ MILTER *milter8_receive(VSTREAM *stream, MILTERS *parent)
|
||||
ATTR_TYPE_INT, MAIL_ATTR_MILT_CMD, &cmd_timeout,
|
||||
ATTR_TYPE_INT, MAIL_ATTR_MILT_MSG, &msg_timeout,
|
||||
ATTR_TYPE_STR, MAIL_ATTR_MILT_ACT, act_buf,
|
||||
ATTR_TYPE_END) < 9) {
|
||||
return (0);
|
||||
ATTR_TYPE_INT, MAIL_ATTR_MILT_MAC, &has_macros,
|
||||
ATTR_TYPE_END) < 10
|
||||
|| (has_macros != 0
|
||||
&& attr_scan(stream, ATTR_FLAG_STRICT,
|
||||
ATTR_TYPE_FUNC, milter_macros_scan,
|
||||
(void *) (macros =
|
||||
milter_macros_alloc(MILTER_MACROS_ALLOC_ZERO)),
|
||||
ATTR_TYPE_END) < 1)
|
||||
|| (has_macros == 0
|
||||
&& attr_scan(stream, ATTR_FLAG_STRICT,
|
||||
ATTR_TYPE_END) < 0)) {
|
||||
FREE_MACROS_AND_RETURN(0);
|
||||
#ifdef CANT_WRITE_BEFORE_SENDING_FD
|
||||
} else if (attr_print(stream, ATTR_FLAG_NONE,
|
||||
ATTR_TYPE_STR, MAIL_ATTR_DUMMY, "",
|
||||
ATTR_TYPE_END) != 0
|
||||
|| vstream_fflush(stream) != 0) {
|
||||
return (0);
|
||||
FREE_MACROS_AND_RETURN(0);
|
||||
#endif
|
||||
} else if ((fd = LOCAL_RECV_FD(vstream_fileno(stream))) < 0) {
|
||||
return (0);
|
||||
FREE_MACROS_AND_RETURN(0);
|
||||
#ifdef MUST_READ_AFTER_SENDING_FD
|
||||
} else if (attr_print(stream, ATTR_FLAG_NONE,
|
||||
ATTR_TYPE_STR, MAIL_ATTR_DUMMY, "",
|
||||
ATTR_TYPE_END) != 0) {
|
||||
return (0);
|
||||
FREE_MACROS_AND_RETURN(0);
|
||||
#endif
|
||||
} else {
|
||||
#define NO_PROTOCOL ((char *) 0)
|
||||
@@ -2585,6 +2615,7 @@ MILTER *milter8_receive(VSTREAM *stream, MILTERS *parent)
|
||||
milter = milter8_alloc(STR(name_buf), conn_timeout, cmd_timeout,
|
||||
msg_timeout, NO_PROTOCOL, STR(act_buf), parent);
|
||||
milter->fp = vstream_fdopen(fd, O_RDWR);
|
||||
milter->m.macros = macros;
|
||||
vstream_control(milter->fp, VSTREAM_CTL_DOUBLE, VSTREAM_CTL_END);
|
||||
/* Avoid poor performance when TCP MSS > VSTREAM_BUFSIZE. */
|
||||
vstream_tweak_sock(milter->fp);
|
||||
@@ -2615,6 +2646,8 @@ static void milter8_free(MILTER *m)
|
||||
myfree(milter->def_action);
|
||||
if (milter->def_reply)
|
||||
myfree(milter->def_reply);
|
||||
if (milter->m.macros)
|
||||
milter_macros_free(milter->m.macros);
|
||||
myfree((char *) milter);
|
||||
}
|
||||
|
||||
@@ -2635,6 +2668,7 @@ static MILTER8 *milter8_alloc(const char *name, int conn_timeout,
|
||||
milter->m.name = mystrdup(name);
|
||||
milter->m.next = 0;
|
||||
milter->m.parent = parent;
|
||||
milter->m.macros = 0;
|
||||
milter->m.conn_event = milter8_conn_event;
|
||||
milter->m.helo_event = milter8_helo_event;
|
||||
milter->m.mail_event = milter8_mail_event;
|
||||
@@ -2678,7 +2712,7 @@ MILTER *milter8_create(const char *name, int conn_timeout, int cmd_timeout,
|
||||
* Fill in the structure.
|
||||
*/
|
||||
milter = milter8_alloc(name, conn_timeout, cmd_timeout, msg_timeout,
|
||||
protocol, def_action, parent);
|
||||
protocol, def_action, parent);
|
||||
|
||||
/*
|
||||
* XXX Sendmail 8 libmilter closes the MTA-to-filter socket when it finds
|
||||
|
247
postfix/src/milter/milter_macros.c
Normal file
247
postfix/src/milter/milter_macros.c
Normal file
@@ -0,0 +1,247 @@
|
||||
/*++
|
||||
/* NAME
|
||||
/* milter_macros
|
||||
/* SUMMARY
|
||||
/* manipulate MILTER_MACROS structures
|
||||
/* SYNOPSIS
|
||||
/* #include <milter.h>
|
||||
/*
|
||||
/* MILTER_MACROS *milter_macros_create(conn_macros, helo_macros,
|
||||
/* mail_macros, rcpt_macros,
|
||||
/* data_macros, eoh_macros,
|
||||
/* eod_macros, unk_macros)
|
||||
/* const char *conn_macros;
|
||||
/* const char *helo_macros;
|
||||
/* const char *mail_macros;
|
||||
/* const char *rcpt_macrps;
|
||||
/* const char *data_macros;
|
||||
/* const char *eoh_macros;
|
||||
/* const char *eod_macros;
|
||||
/* const char *unk_macros;
|
||||
/*
|
||||
/* MILTER_MACROS *milter_macros_alloc(init_mode)
|
||||
/* int init_mode;
|
||||
/*
|
||||
/* void milter_macros_free(mp)
|
||||
/* MILTER_MACROS *mp;
|
||||
/*
|
||||
/* int milter_macros_print(print_fn, stream, flags, ptr)
|
||||
/* ATTR_PRINT_MASTER_FN print_fn;
|
||||
/* VSTREAM *stream;
|
||||
/* int flags;
|
||||
/* void *ptr;
|
||||
/*
|
||||
/* int milter_macros_scan(scan_fn, fp, flags, ptr)
|
||||
/* ATTR_SCAN_MASTER_FN scan_fn;
|
||||
/* VSTREAM *fp;
|
||||
/* int flags;
|
||||
/* void *ptr;
|
||||
/* DESCRIPTION
|
||||
/* Sendmail mail filter (Milter) applications receive sets of
|
||||
/* macro (name=value) pairs with each SMTP or content event.
|
||||
/* In Postfix, the lists of names are stored in MILTER_MACROS
|
||||
/* structures. By default, the same structure is shared by all
|
||||
/* Milter applications; it is initialized with information
|
||||
/* from main.cf. With Sendmail 8.14 a Milter can override one
|
||||
/* or more lists of macro names, and individual filters may
|
||||
/* have their own partial list.
|
||||
/*
|
||||
/* This module maintains the macro name lists as mystrdup()'ed
|
||||
/* values. The user is explicitly allowed to update these
|
||||
/* values directly, as long as they respect the mystrdup()
|
||||
/* interface.
|
||||
/*
|
||||
/* milter_macros_create() creates a MILTER_MACROS structure
|
||||
/* and initializes it with copies of its string arguments.
|
||||
/*
|
||||
/* milter_macros_alloc() creates a MILTER_MACROS structure
|
||||
/* that is initialized according to its init_mode argument.
|
||||
/* .IP MILTER_MACROS_ALLOC_ZERO
|
||||
/* Initialize all members as null pointers. This mode is
|
||||
/* recommended for applications that use milter_macros_scan().
|
||||
/* .IP MILTER_MACROS_ALLOC_EMPTY
|
||||
/* Initialize all members with mystrdup(""). This is not as
|
||||
/* expensive as it appears to be. This mode is recommend for
|
||||
/* applications that update individual MILTER_MACROS members
|
||||
/* directly.
|
||||
/* .PP
|
||||
/* milter_macros_free() destroys a MILTER_MACROS structure and
|
||||
/* frees any strings referenced by it.
|
||||
/*
|
||||
/* milter_macros_print() writes the contents of a MILTER_MACROS
|
||||
/* structure to the named stream using the specified attribute
|
||||
/* print routine. milter_macros_print() is meant to be passed
|
||||
/* as a call-back to attr_print*(), thusly:
|
||||
/*
|
||||
/* ATTR_TYPE_FUNC, milter_macros_print, (void *) macros,
|
||||
/*
|
||||
/* milter_macros_scan() reads a MILTER_MACROS structure from
|
||||
/* the named stream using the specified attribute scan routine.
|
||||
/* milter_macros_scan() is meant to be passed as a call-back
|
||||
/* to attr_scan*(), thusly:
|
||||
/*
|
||||
/* ATTR_TYPE_FUNC, milter_macros_scan, (void *) macros,
|
||||
/* DIAGNOSTICS
|
||||
/* Fatal: out of memory.
|
||||
/* 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>
|
||||
|
||||
/* Utility library. */
|
||||
|
||||
#include <msg.h>
|
||||
#include <attr.h>
|
||||
#include <mymalloc.h>
|
||||
#include <vstring.h>
|
||||
|
||||
/* Global library. */
|
||||
|
||||
#include <mail_proto.h>
|
||||
#include <milter.h>
|
||||
|
||||
/*
|
||||
* Ad-hoc protocol to send/receive milter macro name lists.
|
||||
*/
|
||||
#define MAIL_ATTR_MILT_MAC_CONN "conn_macros"
|
||||
#define MAIL_ATTR_MILT_MAC_HELO "helo_macros"
|
||||
#define MAIL_ATTR_MILT_MAC_MAIL "mail_macros"
|
||||
#define MAIL_ATTR_MILT_MAC_RCPT "rcpt_macros"
|
||||
#define MAIL_ATTR_MILT_MAC_DATA "data_macros"
|
||||
#define MAIL_ATTR_MILT_MAC_EOH "eoh_macros"
|
||||
#define MAIL_ATTR_MILT_MAC_EOD "eod_macros"
|
||||
#define MAIL_ATTR_MILT_MAC_UNK "unk_macros"
|
||||
|
||||
/* milter_macros_print - write recipient to stream */
|
||||
|
||||
int milter_macros_print(ATTR_PRINT_MASTER_FN print_fn, VSTREAM *fp,
|
||||
int flags, void *ptr)
|
||||
{
|
||||
MILTER_MACROS *mp = (MILTER_MACROS *) ptr;
|
||||
int ret;
|
||||
|
||||
/*
|
||||
* The attribute order does not matter, except that it must be the same
|
||||
* as in the milter_macros_scan() function.
|
||||
*/
|
||||
ret = print_fn(fp, flags | ATTR_FLAG_MORE,
|
||||
ATTR_TYPE_STR, MAIL_ATTR_MILT_MAC_CONN, mp->conn_macros,
|
||||
ATTR_TYPE_STR, MAIL_ATTR_MILT_MAC_HELO, mp->helo_macros,
|
||||
ATTR_TYPE_STR, MAIL_ATTR_MILT_MAC_MAIL, mp->mail_macros,
|
||||
ATTR_TYPE_STR, MAIL_ATTR_MILT_MAC_RCPT, mp->rcpt_macros,
|
||||
ATTR_TYPE_STR, MAIL_ATTR_MILT_MAC_DATA, mp->data_macros,
|
||||
ATTR_TYPE_STR, MAIL_ATTR_MILT_MAC_EOH, mp->eoh_macros,
|
||||
ATTR_TYPE_STR, MAIL_ATTR_MILT_MAC_EOD, mp->eod_macros,
|
||||
ATTR_TYPE_STR, MAIL_ATTR_MILT_MAC_UNK, mp->unk_macros,
|
||||
ATTR_TYPE_END);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
/* milter_macros_scan - receive milter macro name list */
|
||||
|
||||
int milter_macros_scan(ATTR_SCAN_MASTER_FN scan_fn, VSTREAM *fp,
|
||||
int flags, void *ptr)
|
||||
{
|
||||
MILTER_MACROS *mp = (MILTER_MACROS *) ptr;
|
||||
int ret;
|
||||
VSTRING *conn_macros = vstring_alloc(10);
|
||||
VSTRING *helo_macros = vstring_alloc(10);
|
||||
VSTRING *mail_macros = vstring_alloc(10);
|
||||
VSTRING *rcpt_macros = vstring_alloc(10);
|
||||
VSTRING *data_macros = vstring_alloc(10);
|
||||
VSTRING *eoh_macros = vstring_alloc(10);
|
||||
VSTRING *eod_macros = vstring_alloc(10);
|
||||
VSTRING *unk_macros = vstring_alloc(10);
|
||||
|
||||
/*
|
||||
* The attribute order does not matter, except that it must be the same
|
||||
* as in the milter_macros_print() function.
|
||||
*/
|
||||
ret = scan_fn(fp, flags | ATTR_FLAG_MORE,
|
||||
ATTR_TYPE_STR, MAIL_ATTR_MILT_MAC_CONN, conn_macros,
|
||||
ATTR_TYPE_STR, MAIL_ATTR_MILT_MAC_HELO, helo_macros,
|
||||
ATTR_TYPE_STR, MAIL_ATTR_MILT_MAC_MAIL, mail_macros,
|
||||
ATTR_TYPE_STR, MAIL_ATTR_MILT_MAC_RCPT, rcpt_macros,
|
||||
ATTR_TYPE_STR, MAIL_ATTR_MILT_MAC_DATA, data_macros,
|
||||
ATTR_TYPE_STR, MAIL_ATTR_MILT_MAC_EOH, eoh_macros,
|
||||
ATTR_TYPE_STR, MAIL_ATTR_MILT_MAC_EOD, eod_macros,
|
||||
ATTR_TYPE_STR, MAIL_ATTR_MILT_MAC_UNK, unk_macros,
|
||||
ATTR_TYPE_END);
|
||||
|
||||
/*
|
||||
* Don't optimize for error.
|
||||
*/
|
||||
mp->conn_macros = vstring_export(conn_macros);
|
||||
mp->helo_macros = vstring_export(helo_macros);
|
||||
mp->mail_macros = vstring_export(mail_macros);
|
||||
mp->rcpt_macros = vstring_export(rcpt_macros);
|
||||
mp->data_macros = vstring_export(data_macros);
|
||||
mp->eoh_macros = vstring_export(eoh_macros);
|
||||
mp->eod_macros = vstring_export(eod_macros);
|
||||
mp->unk_macros = vstring_export(unk_macros);
|
||||
|
||||
return (ret == 8 ? 1 : -1);
|
||||
}
|
||||
|
||||
/* milter_macros_create - create and initialize macros structure */
|
||||
|
||||
MILTER_MACROS *milter_macros_create(const char *conn_macros,
|
||||
const char *helo_macros,
|
||||
const char *mail_macros,
|
||||
const char *rcpt_macros,
|
||||
const char *data_macros,
|
||||
const char *eoh_macros,
|
||||
const char *eod_macros,
|
||||
const char *unk_macros)
|
||||
{
|
||||
MILTER_MACROS *mp;
|
||||
|
||||
mp = (MILTER_MACROS *) mymalloc(sizeof(*mp));
|
||||
mp->conn_macros = mystrdup(conn_macros);
|
||||
mp->helo_macros = mystrdup(helo_macros);
|
||||
mp->mail_macros = mystrdup(mail_macros);
|
||||
mp->rcpt_macros = mystrdup(rcpt_macros);
|
||||
mp->data_macros = mystrdup(data_macros);
|
||||
mp->eoh_macros = mystrdup(eoh_macros);
|
||||
mp->eod_macros = mystrdup(eod_macros);
|
||||
mp->unk_macros = mystrdup(unk_macros);
|
||||
|
||||
return (mp);
|
||||
}
|
||||
|
||||
/* milter_macros_alloc - allocate memory for structure with simple initialization */
|
||||
|
||||
MILTER_MACROS *milter_macros_alloc(int mode)
|
||||
{
|
||||
MILTER_MACROS *mp;
|
||||
|
||||
mp = (MILTER_MACROS *) mymalloc(sizeof(*mp));
|
||||
switch (mode) {
|
||||
case MILTER_MACROS_ALLOC_ZERO:
|
||||
milter_macros_init(mp, 0);
|
||||
break;
|
||||
case MILTER_MACROS_ALLOC_EMPTY:
|
||||
milter_macros_init(mp, mystrdup(""));
|
||||
break;
|
||||
default:
|
||||
msg_panic("milter_macros_alloc: unknown mode %d", mode);
|
||||
}
|
||||
return (mp);
|
||||
}
|
||||
|
||||
/* milter_macros_free - destroy memory for MILTER_MACROS structure */
|
||||
|
||||
void milter_macros_free(MILTER_MACROS *mp)
|
||||
{
|
||||
milter_macros_wipe(mp);
|
||||
myfree((char *) mp);
|
||||
}
|
Reference in New Issue
Block a user