270 #define STR(x) vstring_str(x)
276 const char myname[] =
"milter_macro_defaults_create";
277 char *saved_defaults =
mystrdup(macro_defaults);
278 char *cp = saved_defaults;
300 msg_fatal(
"malformed default macro entry: %s in \"%s\"",
301 err, macro_defaults);
303 msg_fatal(
"malformed default macro entry: %s in \"%s\"",
304 err, macro_defaults);
311 msg_warn(
"ignoring multiple default macro entries for %s in \"%s\"",
312 name, macro_defaults);
316 msg_info(
"%s: add name=%s default=%s", myname, name, value);
327 static ARGV *milter_macro_lookup(
MILTERS *milters,
const char *macro_names)
329 const char *myname =
"milter_macro_lookup";
330 char *saved_names =
mystrdup(macro_names);
331 char *cp = saved_names;
340 msg_info(
"%s: \"%s\"", myname, name);
347 msg_info(
"%s: result \"%s\"", myname, value);
348 argv_add(argv, name, value, (
char *) 0);
352 msg_info(
"%s: using default \"%s\"", myname, value);
353 argv_add(argv, name, value, (
char *) 0);
364 const char *(*mac_lookup) (
const char *,
void *),
400 const char *client_name,
401 const char *client_addr,
402 const char *client_port,
403 unsigned addr_family)
407 ARGV *global_macros = 0;
410 #define MILTER_MACRO_EVAL(global_macros, m, milters, member) \
411 ((m->macros && m->macros->member[0]) ? \
412 milter_macro_lookup(milters, m->macros->member) : \
413 global_macros ? global_macros : \
415 milter_macro_lookup(milters, milters->macros->member)))
418 msg_info(
"report connect to all milters");
419 for (resp = 0, m = milters->
milter_list; resp == 0 && m != 0; m = m->
next) {
421 resp = m->
conn_event(m, client_name, client_addr, client_port,
422 addr_family, any_macros);
423 if (any_macros != global_macros)
438 ARGV *global_macros = 0;
442 msg_info(
"report helo to all milters");
443 for (resp = 0, m = milters->
milter_list; resp == 0 && m != 0; m = m->
next) {
445 resp = m->
helo_event(m, helo_name, esmtp_flag, any_macros);
446 if (any_macros != global_macros)
460 ARGV *global_macros = 0;
464 msg_info(
"report sender to all milters");
465 for (resp = 0, m = milters->
milter_list; resp == 0 && m != 0; m = m->
next) {
468 if (any_macros != global_macros)
482 ARGV *global_macros = 0;
486 msg_info(
"report recipient to all milters (flags=0x%x)", flags);
487 for (resp = 0, m = milters->
milter_list; resp == 0 && m != 0; m = m->
next) {
489 || (m->
flags & MILTER_FLAG_WANT_RCPT_REJ) != 0) {
493 if (any_macros != global_macros)
508 ARGV *global_macros = 0;
512 msg_info(
"report data to all milters");
513 for (resp = 0, m = milters->
milter_list; resp == 0 && m != 0; m = m->
next) {
516 if (any_macros != global_macros)
530 ARGV *global_macros = 0;
534 msg_info(
"report unknown command to all milters");
535 for (resp = 0, m = milters->
milter_list; resp == 0 && m != 0; m = m->
next) {
538 if (any_macros != global_macros)
554 msg_info(
"query milter states for other event");
555 for (resp = 0, m = milters->
milter_list; resp == 0 && m != 0; m = m->
next)
567 ARGV *global_eoh_macros = 0;
568 ARGV *global_eod_macros = 0;
569 ARGV *any_eoh_macros;
570 ARGV *any_eod_macros;
573 msg_info(
"inspect content by all milters");
574 for (resp = 0, m = milters->
milter_list; resp == 0 && m != 0; m = m->
next) {
577 resp = m->
message(m, fp, data_offset, any_eoh_macros, any_eod_macros,
579 if (any_eoh_macros != global_eoh_macros)
581 if (any_eod_macros != global_eod_macros)
584 if (global_eoh_macros)
586 if (global_eod_macros)
610 msg_info(
"disconnect event to all milters");
632 #define link_override_table_to_variable(table, var) \
633 do { table[var##_offset].target = &var; } while (0)
635 #define my_conn_timeout_offset 0
636 #define my_cmd_timeout_offset 1
637 #define my_msg_timeout_offset 2
639 #define my_protocol_offset 0
640 #define my_def_action_offset 1
648 const char *protocol,
649 const char *def_action,
663 const char *my_protocol;
664 const char *my_def_action;
679 if (names != 0 && *names != 0) {
680 char *saved_names =
mystrdup(names);
681 char *cp = saved_names;
688 while ((name =
mystrtokq(&cp, sep, parens)) != 0) {
689 my_conn_timeout = conn_timeout;
690 my_cmd_timeout = cmd_timeout;
691 my_msg_timeout = msg_timeout;
692 my_protocol = protocol;
693 my_def_action = def_action;
694 if (name[0] == parens[0]) {
697 msg_fatal(
"milter service syntax error: %s", err);
698 if ((name =
mystrtok(&op, sep)) == 0)
699 msg_fatal(
"empty milter definition: \"%s\"", names);
706 my_msg_timeout, my_protocol,
707 my_def_action, milters);
799 (
void *) milters->
macros),
818 if (m->
active(m) && (status = m->
send(m, stream)) != 0)
843 int macro_default_count;
846 msg_info(
"receive %d milters", count);
853 #define NO_MILTERS ((char *) 0)
854 #define NO_TIMEOUTS 0, 0, 0
855 #define NO_PROTOCOL ((char *) 0)
856 #define NO_ACTION ((char *) 0)
857 #define NO_MACROS ((MILTER_MACROS *) 0)
858 #define NO_MACRO_DEFLTS ((HTABLE *) 0)
876 (
void *) milters->
macros),
888 || (macro_default_count > 0
900 for (; count > 0; count--) {
902 msg_warn(
"cannot receive milters via service %s socket",
934 #include <sys/socket.h>
953 static void usage(
void)
956 " create names... create and connect\n"
958 " conn_macros names... define connect macros\n"
959 " helo_macros names... define helo command macros\n"
960 " mail_macros names... define mail command macros\n"
961 " rcpt_macros names... define rcpt command macros\n"
962 " data_macros names... define data command macros\n"
963 " unk_macros names... unknown command macros\n"
964 " message_macros names... define message macros\n"
966 " free disconnect and destroy\n"
967 " connect name addr port family\n"
970 " mail from sender...\n"
971 " rcpt to recipient...\n"
974 " unknown command\n");
978 int main(
int argc,
char **argv)
981 char *conn_macros, *helo_macros, *mail_macros, *rcpt_macros;
982 char *data_macros, *eoh_macros, *eod_macros, *unk_macros;
990 conn_macros = helo_macros = mail_macros = rcpt_macros = data_macros
991 = eoh_macros = eod_macros = unk_macros = macro_deflts =
"";
994 while ((ch =
GETOPT(argc, argv,
"V:v")) > 0) {
997 msg_fatal(
"usage: %s [-a action] [-p protocol] [-v]", argv[0]);
999 var_milt_def_action = optarg;
1002 var_milt_protocol = optarg;
1012 const char *resp = 0;
1036 if (strcmp(cmd,
"create") == 0 && argv->
argc == 1) {
1038 msg_warn(
"deleting existing milters");
1042 var_milt_cmd_time, var_milt_msg_time,
1043 var_milt_protocol, var_milt_def_action,
1044 conn_macros, helo_macros, mail_macros,
1045 rcpt_macros, data_macros, eoh_macros,
1046 eod_macros, unk_macros, macro_deflts);
1047 }
else if (strcmp(cmd,
"free") == 0 && argv->
argc == 0) {
1054 }
else if (strcmp(cmd,
"connect") == 0 && argv->
argc == 4) {
1060 strcmp(args[3],
"AF_INET") == 0 ? AF_INET :
1061 strcmp(args[3],
"AF_INET6") == 0 ? AF_INET6 :
1062 strcmp(args[3],
"AF_UNIX") == 0 ? AF_UNIX :
1064 }
else if (strcmp(cmd,
"helo") == 0 && argv->
argc == 1) {
1070 }
else if (strcmp(cmd,
"ehlo") == 0 && argv->
argc == 1) {
1076 }
else if (strcmp(cmd,
"mail") == 0 && argv->
argc > 0) {
1082 }
else if (strcmp(cmd,
"rcpt") == 0 && argv->
argc > 0) {
1088 }
else if (strcmp(cmd,
"unknown") == 0 && argv->
argc > 0) {
1094 }
else if (strcmp(cmd,
"data") == 0 && argv->
argc == 0) {
1100 }
else if (strcmp(cmd,
"disconnect") == 0 && argv->
argc == 0) {
MILTER_EDIT_BODY_FN repl_body
void htable_free(HTABLE *table, void(*free_fn)(void *))
#define vstring_fgets_nonl(s, p)
MILTER_EDIT_RCPT_FN del_rcpt
const char *(* conn_event)(struct MILTER *, const char *, const char *, const char *, unsigned, ARGV *)
char * mystrdup(const char *str)
char * extpar(char **bp, const char *parens, int flags)
const char *(* MILTER_EDIT_BODY_FN)(void *, int, VSTRING *)
#define SEND_ATTR_HASH(val)
ARGV * argv_free(ARGV *argvp)
MILTER_EDIT_HEADER_FN ins_header
const char *(* helo_event)(struct MILTER *, const char *, int, ARGV *)
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, HTABLE *macro_defaults)
const char *(* MILTER_EDIT_RCPT_FN)(void *, const char *)
const char * milter_other_event(MILTERS *milters)
MILTER_EDIT_RCPT_PAR_FN add_rcpt_par
#define DEF_MILT_DEF_ACTION
#define VAR_MILT_PROTOCOL
int main(int argc, char **argv)
void attr_override(char *cp, const char *sep, const char *parens,...)
int milter_macros_print(ATTR_PRINT_MASTER_FN, VSTREAM *, int, void *)
void milter_macros_free(MILTER_MACROS *)
#define DEF_MILT_MSG_TIME
#define DEF_MILT_CONN_TIME
#define DEF_MILT_CMD_TIME
const char *(* MILTER_EDIT_FROM_FN)(void *, const char *, const char *)
#define RECV_ATTR_INT(name, val)
void argv_add(ARGV *argvp,...)
MILTER_EDIT_FROM_FN chg_from
char * mystrtokq(char **src, const char *sep, const char *parens)
#define RECV_ATTR_HASH(val)
#define DEF_MILT_PROTOCOL
void(* free)(struct MILTER *)
const char * milter_message(MILTERS *milters, VSTREAM *fp, off_t data_offset, ARGV *auto_hdrs)
char * mystrtok(char **src, const char *sep)
ARGV * argv_alloc(ssize_t len)
#define CA_ATTR_OVER_TIME_TABLE(v)
const char * split_nameval(char *buf, char **name, char **value)
#define REC_TYPE_MILT_COUNT
const char *(* MILTER_ADD_HEADER_FN)(void *, const char *, const char *, const char *)
char * del_rcpt[MAX_RCPT]
const char * milter_helo_event(MILTERS *milters, const char *helo_name, int esmtp_flag)
MILTERS * milter_receive(VSTREAM *stream, int count)
MILTER_ADD_HEADER_FN add_header
HTABLE * htable_create(ssize_t size)
MILTER_EDIT_RCPT_FN add_rcpt
HTABLE * milter_macro_defaults_create(const char *macro_defaults)
#define MILTER_FLAG_WANT_RCPT_REJ
const char * milter_unknown_event(MILTERS *milters, const char *command)
const char *(* MILTER_EDIT_HEADER_FN)(void *, ssize_t, const char *, const char *, const char *)
int milter_dummy(MILTERS *milters, VSTREAM *stream)
const char *(* other_event)(struct MILTER *)
char * add_rcpt[MAX_RCPT]
const char * milter_mail_event(MILTERS *milters, const char **argv)
#define VAR_MILT_CMD_TIME
VSTREAM * vstream_fprintf(VSTREAM *stream, const char *fmt,...)
int(* active)(struct MILTER *)
int milter_macros_scan(ATTR_SCAN_MASTER_FN, VSTREAM *, int, void *)
void milter_abort(MILTERS *milters)
const char *(* mail_event)(struct MILTER *, const char **, ARGV *)
VSTREAM * vstream_printf(const char *fmt,...)
#define VAR_MILT_MSG_TIME
#define VAR_MILT_CONN_TIME
#define CA_ATTR_OVER_STR_TABLE(v)
void msg_warn(const char *fmt,...)
const char *(* message)(struct MILTER *, VSTREAM *, off_t, ARGV *, ARGV *, ARGV *)
MILTER * milter8_receive(VSTREAM *, struct MILTERS *)
VSTRING * vstring_alloc(ssize_t len)
void milter_disc_event(MILTERS *milters)
const char * milter_rcpt_event(MILTERS *milters, int flags, const char **argv)
void * htable_find(HTABLE *table, const char *key)
const char *(* MILTER_DEL_HEADER_FN)(void *, ssize_t, const char *)
VSTRING * vstring_sprintf(VSTRING *vp, const char *format,...)
#define SEND_ATTR_INT(name, val)
void milter_free(MILTERS *milters)
NORETURN msg_fatal(const char *fmt,...)
const char * milter_data_event(MILTERS *milters)
int vstream_fflush(VSTREAM *stream)
#define link_override_table_to_variable(table, var)
ARGV * argv_split(const char *, const char *)
struct MILTER_MACROS * macros
#define GETOPT(argc, argv, str)
void milter_edit_callback(MILTERS *milters, MILTER_ADD_HEADER_FN add_header, MILTER_EDIT_HEADER_FN upd_header, MILTER_EDIT_HEADER_FN ins_header, MILTER_DEL_HEADER_FN del_header, MILTER_EDIT_FROM_FN chg_from, MILTER_EDIT_RCPT_FN add_rcpt, MILTER_EDIT_RCPT_PAR_FN add_rcpt_par, MILTER_EDIT_RCPT_FN del_rcpt, MILTER_EDIT_BODY_FN repl_body, void *chg_context)
#define SEND_ATTR_FUNC(func, val)
int(* send)(struct MILTER *, VSTREAM *)
char * var_milt_def_action
size_t balpar(const char *string, const char *parens)
VSTRING * vstring_free(VSTRING *vp)
#define vstream_fileno(vp)
const char * milter_conn_event(MILTERS *milters, const char *client_name, const char *client_addr, const char *client_port, unsigned addr_family)
void msg_vstream_init(const char *name, VSTREAM *vp)
#define VAR_MILT_DEF_ACTION
#define RECV_ATTR_FUNC(func, val)
const char *(* MILTER_EDIT_RCPT_PAR_FN)(void *, const char *, const char *)
MILTER_DEL_HEADER_FN del_header
MILTER_EDIT_HEADER_FN upd_header
MILTER_MACROS * milter_macros_alloc(int)
const char *(* data_event)(struct MILTER *, ARGV *)
void milter_macro_callback(MILTERS *milters, const char *(*mac_lookup)(const char *, void *), void *mac_context)
const char *(* unknown_event)(struct MILTER *, const char *, ARGV *)
void(* disc_event)(struct MILTER *)
int rec_fprintf(VSTREAM *stream, int type, const char *format,...)
void(* abort)(struct MILTER *)
const char *(* rcpt_event)(struct MILTER *, const char **, ARGV *)
#define MILTER_MACROS_ALLOC_ZERO
#define MILTER_MACRO_EVAL(global_macros, m, milters, member)
int milter_send(MILTERS *milters, VSTREAM *stream)
void * mymalloc(ssize_t len)
MILTER_MAC_LOOKUP_FN mac_lookup
MILTER * milter8_create(const char *, int, int, int, const char *, const char *, struct MILTERS *)
struct HTABLE * macro_defaults
HTABLE_INFO * htable_enter(HTABLE *table, const char *key, void *value)
void msg_info(const char *fmt,...)
#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, macro_deflts)