mirror of
https://github.com/vdukhovni/postfix
synced 2025-08-30 13:48:06 +00:00
postfix-2.5-20071224
This commit is contained in:
committed by
Viktor Dukhovni
parent
a82a55628d
commit
54a1b6ce1f
@@ -14057,8 +14057,17 @@ Apologies for any names omitted.
|
||||
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
|
||||
Milter can now update its own macros instead of clobbering
|
||||
the global copy that 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.
|
||||
|
||||
20071224
|
||||
|
||||
Further polishing of the Milter code. Eliminated unnecessary
|
||||
steps from the initial smtpd/cleanup Milter handshake. Files:
|
||||
milter/milter.c, milter/milter8.c, milter/milter_macros.c.
|
||||
|
||||
Cleanup: name_code(3) and name_mask(3) now support read-only
|
||||
tables. Files: util/name_code.[hc] util/name_mask.[hc].
|
||||
|
@@ -11,6 +11,17 @@ instead, a new snapshot is released.
|
||||
The mail_release_date configuration parameter (format: yyyymmdd)
|
||||
specifies the release date of a stable release or snapshot release.
|
||||
|
||||
Incompatibility with Postfix snapshot 20071224
|
||||
==============================================
|
||||
|
||||
The protocol to send Milter information from smtpd(8) to cleanup(8)
|
||||
processes was cleaned up. If you use the Milter feature, and upgrade
|
||||
a live Postfix system, you may see an "unexpected record type"
|
||||
warning from a cleanup(8) server process. To prevent this, execute
|
||||
the command "postfix reload". The incompatibility affects only
|
||||
systems that use the Milter feature. It does not cause loss of mail,
|
||||
just a minor delay until the remote SMTP client retries.
|
||||
|
||||
Major changes with Postfix snapshot 20071221
|
||||
============================================
|
||||
|
||||
|
@@ -264,7 +264,7 @@ SMTPD(8) SMTPD(8)
|
||||
|
||||
<b><a href="postconf.5.html#milter_end_of_header_macros">milter_end_of_header_macros</a> (see postconf -n output)</b>
|
||||
The macros that are sent to Milter (mail filter)
|
||||
applications after the message header.
|
||||
applications after the end of the message header.
|
||||
|
||||
<b><a href="postconf.5.html#milter_end_of_data_macros">milter_end_of_data_macros</a> (see postconf -n output)</b>
|
||||
The macros that are sent to Milter (mail filter)
|
||||
|
@@ -235,7 +235,7 @@ The macros that are sent to version 3 or higher Milter (mail
|
||||
filter) applications after an unknown SMTP command.
|
||||
.IP "\fBmilter_end_of_header_macros (see postconf -n output)\fR"
|
||||
The macros that are sent to Milter (mail filter) applications
|
||||
after the message header.
|
||||
after the end of the message header.
|
||||
.IP "\fBmilter_end_of_data_macros (see postconf -n output)\fR"
|
||||
The macros that are sent to Milter (mail filter) applications
|
||||
after the message end-of-data.
|
||||
|
@@ -146,6 +146,14 @@ static void cleanup_envelope_process(CLEANUP_STATE *state, int type,
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* XXX We instantiate a MILTERS structure even when the filter count is
|
||||
* zero (for example, all filters are in ACCEPT state, or the SMTP server
|
||||
* sends a dummy MILTERS structure without any filters), otherwise the
|
||||
* cleanup server would apply the non_smtpd_milters setting
|
||||
* inappropriately.
|
||||
*/
|
||||
if (type == REC_TYPE_MILT_COUNT) {
|
||||
/* Not part of queue file format. */
|
||||
if ((milter_count = atoi(buf)) >= 0)
|
||||
|
@@ -1332,6 +1332,8 @@ void cleanup_milter_receive(CLEANUP_STATE *state, int count)
|
||||
state->milters = milter_receive(state->src, count);
|
||||
if (state->milters == 0)
|
||||
msg_fatal("cleanup_milter_receive: milter receive failed");
|
||||
if (count <= 0)
|
||||
return;
|
||||
milter_macro_callback(state->milters, cleanup_milter_eval, (void *) state);
|
||||
milter_edit_callback(state->milters,
|
||||
cleanup_add_header, cleanup_upd_header,
|
||||
|
@@ -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 "20071223"
|
||||
#define MAIL_RELEASE_DATE "20071224"
|
||||
#define MAIL_VERSION_NUMBER "2.5"
|
||||
|
||||
#ifdef SNAPSHOT
|
||||
|
@@ -603,6 +603,10 @@ int milter_send(MILTERS *milters, VSTREAM *stream)
|
||||
* to a cleanup server. For now we skip only the filters that are known
|
||||
* to be disabled (either in global error state or in global accept
|
||||
* state).
|
||||
*
|
||||
* XXX We must send *some* information, even when there are no active
|
||||
* filters, otherwise the cleanup server would try to apply its own
|
||||
* non_smtpd_milters settings.
|
||||
*/
|
||||
if (milters != 0)
|
||||
for (m = milters->milter_list; m != 0; m = m->next)
|
||||
@@ -611,7 +615,14 @@ int milter_send(MILTERS *milters, VSTREAM *stream)
|
||||
(void) rec_fprintf(stream, REC_TYPE_MILT_COUNT, "%d", count);
|
||||
|
||||
/*
|
||||
* Send the filter macro names.
|
||||
* XXX Optimization: don't send or receive further information when there
|
||||
* aren't any active filters.
|
||||
*/
|
||||
if (count <= 0)
|
||||
return (0);
|
||||
|
||||
/*
|
||||
* Send the filter macro name lists.
|
||||
*/
|
||||
(void) attr_print(stream, ATTR_FLAG_MORE,
|
||||
ATTR_TYPE_FUNC, milter_macros_print,
|
||||
@@ -624,6 +635,10 @@ int milter_send(MILTERS *milters, VSTREAM *stream)
|
||||
for (m = milters->milter_list; m != 0; m = m->next)
|
||||
if (m->active(m) && (status = m->send(m, stream)) != 0)
|
||||
break;
|
||||
|
||||
/*
|
||||
* Over to you.
|
||||
*/
|
||||
if (status != 0
|
||||
|| attr_scan(stream, ATTR_FLAG_STRICT,
|
||||
ATTR_TYPE_INT, MAIL_ATTR_STATUS, &status,
|
||||
@@ -643,20 +658,39 @@ MILTERS *milter_receive(VSTREAM *stream, int count)
|
||||
MILTER *head = 0;
|
||||
MILTER *tail = 0;
|
||||
MILTER *milter = 0;
|
||||
MILTER_MACROS *macros = milter_macros_alloc(MILTER_MACROS_ALLOC_ZERO);
|
||||
|
||||
if (attr_scan(stream, ATTR_FLAG_STRICT | ATTR_FLAG_MORE,
|
||||
ATTR_TYPE_FUNC, milter_macros_scan, (void *) macros,
|
||||
ATTR_TYPE_END) != 1) {
|
||||
milter_macros_free(macros);
|
||||
return (0);
|
||||
}
|
||||
/*
|
||||
* XXX We must instantiate a MILTERS structure even when the sender has
|
||||
* no active filters, otherwise the cleanup server would try to use its
|
||||
* own non_smtpd_milters settings.
|
||||
*/
|
||||
#define NO_MILTERS ((char *) 0)
|
||||
#define NO_TIMEOUTS 0, 0, 0
|
||||
#define NO_PROTOCOL ((char *) 0)
|
||||
#define NO_ACTION ((char *) 0)
|
||||
#define NO_MACROS ((MILTER_MACROS *) 0)
|
||||
|
||||
milters = milter_new(NO_MILTERS, NO_TIMEOUTS, NO_PROTOCOL, NO_ACTION, macros);
|
||||
milters = milter_new(NO_MILTERS, NO_TIMEOUTS, NO_PROTOCOL, NO_ACTION,
|
||||
NO_MACROS);
|
||||
|
||||
/*
|
||||
* XXX Optimization: don't send or receive further information when there
|
||||
* aren't any active filters.
|
||||
*/
|
||||
if (count <= 0)
|
||||
return (milters);
|
||||
|
||||
/*
|
||||
* Receive the global macro name lists.
|
||||
*/
|
||||
milters->macros = milter_macros_alloc(MILTER_MACROS_ALLOC_ZERO);
|
||||
if (attr_scan(stream, ATTR_FLAG_STRICT | ATTR_FLAG_MORE,
|
||||
ATTR_TYPE_FUNC, milter_macros_scan,
|
||||
(void *) milters->macros,
|
||||
ATTR_TYPE_END) != 1) {
|
||||
milter_free(milters);
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Receive the filters.
|
||||
@@ -677,6 +711,9 @@ MILTERS *milter_receive(VSTREAM *stream, int count)
|
||||
tail = milter;
|
||||
}
|
||||
|
||||
/*
|
||||
* Over to you.
|
||||
*/
|
||||
(void) attr_print(stream, ATTR_FLAG_NONE,
|
||||
ATTR_TYPE_INT, MAIL_ATTR_STATUS, 0,
|
||||
ATTR_TYPE_END);
|
||||
|
@@ -80,42 +80,6 @@ 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.
|
||||
*/
|
||||
|
@@ -123,7 +123,7 @@
|
||||
/* Introduced with Sendmail 8.14. */
|
||||
#define SMFIC_QUIT_NC 'K' /* Quit + new connection */
|
||||
|
||||
static NAME_CODE smfic_table[] = {
|
||||
static const NAME_CODE smfic_table[] = {
|
||||
"SMFIC_ABORT", SMFIC_ABORT,
|
||||
"SMFIC_BODY", SMFIC_BODY,
|
||||
"SMFIC_CONNECT", SMFIC_CONNECT,
|
||||
@@ -168,7 +168,7 @@ static NAME_CODE smfic_table[] = {
|
||||
#define SMFIR_ADDRCPT_PAR '2' /* add recipient (incl. ESMTP args) */
|
||||
#define SMFIR_SETSYMLIST 'l' /* set list of symbols (macros) */
|
||||
|
||||
static NAME_CODE smfir_table[] = {
|
||||
static const NAME_CODE smfir_table[] = {
|
||||
"SMFIR_ADDRCPT", SMFIR_ADDRCPT,
|
||||
"SMFIR_DELRCPT", SMFIR_DELRCPT,
|
||||
"SMFIR_ACCEPT", SMFIR_ACCEPT,
|
||||
@@ -231,7 +231,7 @@ static NAME_CODE smfir_table[] = {
|
||||
| SMFIP_NR_DATA | SMFIP_NR_UNKN | SMFIP_NR_HDR | SMFIP_NR_EOH | \
|
||||
SMFIP_NR_BODY)
|
||||
|
||||
static NAME_MASK smfip_table[] = {
|
||||
static const NAME_MASK smfip_table[] = {
|
||||
"SMFIP_NOCONNECT", SMFIP_NOCONNECT,
|
||||
"SMFIP_NOHELO", SMFIP_NOHELO,
|
||||
"SMFIP_NOMAIL", SMFIP_NOMAIL,
|
||||
@@ -272,7 +272,7 @@ static NAME_MASK smfip_table[] = {
|
||||
#define SMFIF_ADDRCPT_PAR (1L<<7) /* filter may add recipients + args */
|
||||
#define SMFIF_SETSYMLIST (1L<<8) /* filter may send macro names */
|
||||
|
||||
static NAME_MASK smfif_table[] = {
|
||||
static const NAME_MASK smfif_table[] = {
|
||||
"SMFIF_ADDHDRS", SMFIF_ADDHDRS,
|
||||
"SMFIF_CHGBODY", SMFIF_CHGBODY,
|
||||
"SMFIF_ADDRCPT", SMFIF_ADDRCPT,
|
||||
@@ -306,7 +306,7 @@ static NAME_MASK smfif_table[] = {
|
||||
#define SMFIM_EOM 5 /* macros for end-of-message */
|
||||
#define SMFIM_EOH 6 /* macros for end-of-header */
|
||||
|
||||
static NAME_CODE smfim_table[] = {
|
||||
static const NAME_CODE smfim_table[] = {
|
||||
"SMFIM_CONNECT", SMFIM_CONNECT,
|
||||
"SMFIM_HELO", SMFIM_HELO,
|
||||
"SMFIM_ENVFROM", SMFIM_ENVFROM,
|
||||
@@ -318,10 +318,10 @@ static NAME_CODE smfim_table[] = {
|
||||
};
|
||||
|
||||
/*
|
||||
* Mapping from external macro set numbers to our internal MILTERS structure
|
||||
* members, without using a switch statement.
|
||||
* Mapping from external macro set numbers to our internal MILTER_MACROS
|
||||
* structure members, without using an array or switch statement.
|
||||
*/
|
||||
static size_t milter8_macro_offsets[] = {
|
||||
static const size_t milter8_macro_offsets[] = {
|
||||
offsetof(MILTER_MACROS, conn_macros), /* SMFIM_CONNECT */
|
||||
offsetof(MILTER_MACROS, helo_macros), /* SMFIM_HELO */
|
||||
offsetof(MILTER_MACROS, mail_macros), /* SMFIM_ENVFROM */
|
||||
@@ -445,7 +445,7 @@ typedef struct {
|
||||
* XXX Is this still needed? Sendmail 8.14 provides a proper way to negotiate
|
||||
* what replies the mail filter will send.
|
||||
*/
|
||||
static NAME_CODE milter8_event_masks[] = {
|
||||
static const NAME_CODE milter8_event_masks[] = {
|
||||
"2", MILTER8_V2_PROTO_MASK,
|
||||
"3", MILTER8_V3_PROTO_MASK,
|
||||
"4", MILTER8_V4_PROTO_MASK,
|
||||
@@ -460,7 +460,7 @@ static NAME_CODE milter8_event_masks[] = {
|
||||
* protocol extensions such as "no_header_reply", and require that exactly
|
||||
* one version number is specified.
|
||||
*/
|
||||
static NAME_CODE milter8_versions[] = {
|
||||
static const NAME_CODE milter8_versions[] = {
|
||||
"2", 2,
|
||||
"3", 3,
|
||||
"4", 4,
|
||||
@@ -1750,8 +1750,7 @@ static void milter8_connect(MILTER8 *milter)
|
||||
msg_info("override %s macro list with \"%s\"",
|
||||
smfim_name, STR(buf));
|
||||
mac_value_ptr = MILTER8_MACRO_PTR(milter->m.macros, mac_type);
|
||||
if (*mac_value_ptr != 0)
|
||||
myfree(*mac_value_ptr);
|
||||
myfree(*mac_value_ptr);
|
||||
*mac_value_ptr = mystrdup(STR(buf));
|
||||
}
|
||||
}
|
||||
@@ -2536,7 +2535,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 */
|
||||
|
||||
@@ -2712,7 +2711,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
|
||||
|
@@ -38,47 +38,52 @@
|
||||
/* 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.
|
||||
/* macro name=value pairs with each SMTP or content event.
|
||||
/* In Postfix, these macro names are stored in MILTER_MACROS
|
||||
/* structures, as one list for each event type. 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. Postfix implements this by giving the Milter
|
||||
/* its own MILTER_MACROS structure and by storing the per-Milter
|
||||
/* information there.
|
||||
/*
|
||||
/* 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.
|
||||
/* This module maintains per-event macro name lists as
|
||||
/* mystrdup()'ed values. The user is explicitly allowed to
|
||||
/* update these values directly, as long as the result is
|
||||
/* compatible with mystrdup().
|
||||
/*
|
||||
/* milter_macros_create() creates a MILTER_MACROS structure
|
||||
/* and initializes it with copies of its string arguments.
|
||||
/* Null pointers are not valid as input.
|
||||
/*
|
||||
/* milter_macros_alloc() creates a MILTER_MACROS structure
|
||||
/* milter_macros_alloc() creates am empty 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().
|
||||
/* Initialize all structure members as null pointers. This
|
||||
/* mode must be used with milter_macros_scan(), because that
|
||||
/* function blindly overwrites all structure members. No other
|
||||
/* function except milter_macros_free() allows structure members
|
||||
/* with null pointer values.
|
||||
/* .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.
|
||||
/* Initialize all structure members with mystrdup(""). This
|
||||
/* is not as expensive as it appears to be.
|
||||
/* .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
|
||||
/* 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:
|
||||
/* No attempt is made to free the memory of existing structure
|
||||
/* members. 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
|
||||
@@ -121,7 +126,7 @@
|
||||
#define MAIL_ATTR_MILT_MAC_EOD "eod_macros"
|
||||
#define MAIL_ATTR_MILT_MAC_UNK "unk_macros"
|
||||
|
||||
/* milter_macros_print - write recipient to stream */
|
||||
/* milter_macros_print - write macros structure to stream */
|
||||
|
||||
int milter_macros_print(ATTR_PRINT_MASTER_FN print_fn, VSTREAM *fp,
|
||||
int flags, void *ptr)
|
||||
@@ -146,13 +151,17 @@ int milter_macros_print(ATTR_PRINT_MASTER_FN print_fn, VSTREAM *fp,
|
||||
return (ret);
|
||||
}
|
||||
|
||||
/* milter_macros_scan - receive milter macro name list */
|
||||
/* milter_macros_scan - receive macros structure from stream */
|
||||
|
||||
int milter_macros_scan(ATTR_SCAN_MASTER_FN scan_fn, VSTREAM *fp,
|
||||
int flags, void *ptr)
|
||||
{
|
||||
MILTER_MACROS *mp = (MILTER_MACROS *) ptr;
|
||||
int ret;
|
||||
|
||||
/*
|
||||
* We could simplify this by moving memory allocation into attr_scan*().
|
||||
*/
|
||||
VSTRING *conn_macros = vstring_alloc(10);
|
||||
VSTRING *helo_macros = vstring_alloc(10);
|
||||
VSTRING *mail_macros = vstring_alloc(10);
|
||||
@@ -218,12 +227,28 @@ MILTER_MACROS *milter_macros_create(const char *conn_macros,
|
||||
return (mp);
|
||||
}
|
||||
|
||||
/* milter_macros_alloc - allocate memory for structure with simple initialization */
|
||||
/* milter_macros_alloc - allocate macros structure with simple initialization */
|
||||
|
||||
MILTER_MACROS *milter_macros_alloc(int mode)
|
||||
{
|
||||
MILTER_MACROS *mp;
|
||||
|
||||
/*
|
||||
* This macro was originally in milter.h, but no-one else needed it.
|
||||
*/
|
||||
#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)
|
||||
|
||||
mp = (MILTER_MACROS *) mymalloc(sizeof(*mp));
|
||||
switch (mode) {
|
||||
case MILTER_MACROS_ALLOC_ZERO:
|
||||
@@ -242,6 +267,30 @@ MILTER_MACROS *milter_macros_alloc(int mode)
|
||||
|
||||
void milter_macros_free(MILTER_MACROS *mp)
|
||||
{
|
||||
|
||||
/*
|
||||
* This macro was originally in milter.h, but no-one else needed it.
|
||||
*/
|
||||
#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)
|
||||
|
||||
milter_macros_wipe(mp);
|
||||
myfree((char *) mp);
|
||||
}
|
||||
|
@@ -18,7 +18,7 @@
|
||||
/* Arguments (multiple alternatives are separated by "\fB|\fR"):
|
||||
/* .IP "\fB-a accept|tempfail|reject|discard|skip|\fIddd x.y.z text\fR"
|
||||
/* Specifies a non-default reply for the MTA command specified
|
||||
/* with \fB-a\fR. The default is \fBtempfail\fR.
|
||||
/* with \fB-c\fR. The default is \fBtempfail\fR.
|
||||
/* .IP "\fB-d\fI level\fR"
|
||||
/* Enable libmilter debugging at the specified level.
|
||||
/* .IP "\fB-c connect|helo|mail|rcpt|data|header|eoh|body|eom|unknown|close|abort\fR"
|
||||
@@ -28,6 +28,9 @@
|
||||
/* Terminate after \fIcount\fR connections.
|
||||
/* .IP "\fB-i \fI'index header-label header-value'\fR"
|
||||
/* Insert header at specified position.
|
||||
/* .IP "\fB-l\fR"
|
||||
/* Header values include leading space. Specify this option
|
||||
/* before \fB-i\fR or \fB-r\fR.
|
||||
/* .IP "\fB-m connect|helo|mail|rcpt|data|eoh|eom\fR"
|
||||
/* The protocol stage that receives the list of macros specified
|
||||
/* with \fB-M\fR. The default protocol stage is \fBconnect\fR.
|
||||
@@ -100,7 +103,7 @@ struct command_map {
|
||||
int *reply;
|
||||
};
|
||||
|
||||
static struct command_map command_map[] = {
|
||||
static const struct command_map command_map[] = {
|
||||
"connect", &test_connect_reply,
|
||||
"helo", &test_helo_reply,
|
||||
"mail", &test_mail_reply,
|
||||
@@ -387,7 +390,7 @@ struct noproto_map {
|
||||
FILTER_ACTION *action;
|
||||
};
|
||||
|
||||
static struct noproto_map noproto_map[] = {
|
||||
static const struct noproto_map noproto_map[] = {
|
||||
"connect", SMFIP_NOCONNECT, SMFIP_NR_CONN, &test_connect_reply, &smfilter.xxfi_connect,
|
||||
"helo", SMFIP_NOHELO, SMFIP_NR_HELO, &test_helo_reply, &smfilter.xxfi_helo,
|
||||
"mail", SMFIP_NOMAIL, SMFIP_NR_MAIL, &test_mail_reply, &smfilter.xxfi_envfrom,
|
||||
@@ -402,6 +405,7 @@ static struct noproto_map noproto_map[] = {
|
||||
|
||||
static int nosend_mask;
|
||||
static int noreply_mask;
|
||||
static int misc_mask;
|
||||
|
||||
static sfsistat test_negotiate(SMFICTX *ctx,
|
||||
unsigned long f0,
|
||||
@@ -420,10 +424,10 @@ static sfsistat test_negotiate(SMFICTX *ctx,
|
||||
smfi_setsymlist(ctx, set_macro_state, set_macro_list);
|
||||
}
|
||||
if (verbose)
|
||||
printf("negotiate f0=%lx *pf0 = %lx f1=%lx *pf1=%lx nosend=%lx noreply=%lx\n",
|
||||
f0, *pf0, f1, *pf1, (long) nosend_mask, (long) noreply_mask);
|
||||
printf("negotiate f0=%lx *pf0 = %lx f1=%lx *pf1=%lx nosend=%lx noreply=%lx misc=%lx\n",
|
||||
f0, *pf0, f1, *pf1, (long) nosend_mask, (long) noreply_mask, (long) misc_mask);
|
||||
*pf0 = f0;
|
||||
*pf1 = f1 & (nosend_mask | noreply_mask);
|
||||
*pf1 = f1 & (nosend_mask | noreply_mask | misc_mask);
|
||||
return (SMFIS_CONTINUE);
|
||||
}
|
||||
|
||||
@@ -439,7 +443,9 @@ static void parse_hdr_info(const char *optarg, int *idx,
|
||||
fprintf(stderr, "out of memory\n");
|
||||
exit(1);
|
||||
}
|
||||
if (sscanf(optarg, "%d %s %[^\n]", idx, *hdr, *value) != 3) {
|
||||
if ((misc_mask & SMFIP_HDR_LEADSPC) == 0 ?
|
||||
sscanf(optarg, "%d %s %[^\n]", idx, *hdr, *value) != 3 :
|
||||
sscanf(optarg, "%d %[^ ]%[^\n]", idx, *hdr, *value) != 3) {
|
||||
fprintf(stderr, "bad header info: %s\n", optarg);
|
||||
exit(1);
|
||||
}
|
||||
@@ -449,16 +455,16 @@ int main(int argc, char **argv)
|
||||
{
|
||||
char *action = 0;
|
||||
char *command = 0;
|
||||
struct command_map *cp;
|
||||
const struct command_map *cp;
|
||||
int ch;
|
||||
int code;
|
||||
const char **cpp;
|
||||
char *set_macro_state_arg = 0;
|
||||
char *nosend = 0;
|
||||
char *noreply = 0;
|
||||
struct noproto_map *np;
|
||||
const struct noproto_map *np;
|
||||
|
||||
while ((ch = getopt(argc, argv, "a:c:C:d:i:m:M:n:N:p:r:R:v")) > 0) {
|
||||
while ((ch = getopt(argc, argv, "a:c:C:d:i:lm:M:n:N:p:r:R:v")) > 0) {
|
||||
switch (ch) {
|
||||
case 'a':
|
||||
action = optarg;
|
||||
@@ -482,6 +488,18 @@ int main(int argc, char **argv)
|
||||
#else
|
||||
fprintf(stderr, "no libmilter support to insert header\n");
|
||||
exit(1);
|
||||
#endif
|
||||
break;
|
||||
case 'l':
|
||||
#if SMFI_VERSION > 5
|
||||
if (ins_hdr || chg_hdr) {
|
||||
fprintf(stderr, "specify -l before -i or -r\n");
|
||||
exit(1);
|
||||
}
|
||||
misc_mask |= SMFIP_HDR_LEADSPC;
|
||||
#else
|
||||
fprintf(stderr, "no libmilter support for leading space\n");
|
||||
exit(1);
|
||||
#endif
|
||||
break;
|
||||
case 'm':
|
||||
@@ -493,6 +511,7 @@ int main(int argc, char **argv)
|
||||
set_macro_state_arg = optarg;
|
||||
#else
|
||||
fprintf(stderr, "no libmilter support to specify macro list\n");
|
||||
exit(1);
|
||||
#endif
|
||||
break;
|
||||
case 'M':
|
||||
|
@@ -211,7 +211,7 @@
|
||||
/* filter) applications after an unknown SMTP command.
|
||||
/* .IP "\fBmilter_end_of_header_macros (see postconf -n output)\fR"
|
||||
/* The macros that are sent to Milter (mail filter) applications
|
||||
/* after the message header.
|
||||
/* after the end of the message header.
|
||||
/* .IP "\fBmilter_end_of_data_macros (see postconf -n output)\fR"
|
||||
/* The macros that are sent to Milter (mail filter) applications
|
||||
/* after the message end-of-data.
|
||||
@@ -1654,6 +1654,11 @@ static int mail_open_stream(SMTPD_STATE *state)
|
||||
* XXX Send Milter information first, because this will hang when cleanup
|
||||
* goes into "throw away" mode. Also, cleanup needs to know early on
|
||||
* whether or not it has to do its own SMTP event emulation.
|
||||
*
|
||||
* XXX At this point we send only dummy information to keep the cleanup
|
||||
* server from using its non_smtpd_milters settings. We have to send
|
||||
* up-to-date Milter information after DATA so that the cleanup server
|
||||
* knows the actual Milter state.
|
||||
*/
|
||||
if (state->dest) {
|
||||
state->cleanup = state->dest->stream;
|
||||
|
@@ -14,12 +14,12 @@
|
||||
/* } NAME_CODE;
|
||||
/*
|
||||
/* int name_code(table, flags, name)
|
||||
/* NAME_CODE *table;
|
||||
/* const NAME_CODE *table;
|
||||
/* int flags;
|
||||
/* const char *name;
|
||||
/*
|
||||
/* const char *str_name_code(table, code)
|
||||
/* NAME_CODE *table;
|
||||
/* const NAME_CODE *table;
|
||||
/* int code;
|
||||
/* DESCRIPTION
|
||||
/* This module does simple name<->number mapping. The process
|
||||
@@ -66,9 +66,9 @@
|
||||
|
||||
/* name_code - look up code by name */
|
||||
|
||||
int name_code(NAME_CODE *table, int flags, const char *name)
|
||||
int name_code(const NAME_CODE *table, int flags, const char *name)
|
||||
{
|
||||
NAME_CODE *np;
|
||||
const NAME_CODE *np;
|
||||
int (*lookup) (const char *, const char *);
|
||||
|
||||
if (flags & NAME_CODE_FLAG_STRICT_CASE)
|
||||
@@ -84,9 +84,9 @@ int name_code(NAME_CODE *table, int flags, const char *name)
|
||||
|
||||
/* str_name_code - look up name by code */
|
||||
|
||||
const char *str_name_code(NAME_CODE *table, int code)
|
||||
const char *str_name_code(const NAME_CODE *table, int code)
|
||||
{
|
||||
NAME_CODE *np;
|
||||
const NAME_CODE *np;
|
||||
|
||||
for (np = table; np->name; np++)
|
||||
if (code == np->code)
|
||||
|
@@ -22,8 +22,8 @@ typedef struct {
|
||||
#define NAME_CODE_FLAG_NONE 0
|
||||
#define NAME_CODE_FLAG_STRICT_CASE (1<<0)
|
||||
|
||||
extern int name_code(NAME_CODE *, int, const char *);
|
||||
extern const char *str_name_code(NAME_CODE *, int);
|
||||
extern int name_code(const NAME_CODE *, int, const char *);
|
||||
extern const char *str_name_code(const NAME_CODE *, int);
|
||||
|
||||
/* LICENSE
|
||||
/* .ad
|
||||
|
@@ -8,23 +8,23 @@
|
||||
/*
|
||||
/* int name_mask(context, table, names)
|
||||
/* const char *context;
|
||||
/* NAME_MASK *table;
|
||||
/* const NAME_MASK *table;
|
||||
/* const char *names;
|
||||
/*
|
||||
/* const char *str_name_mask(context, table, mask)
|
||||
/* const char *context;
|
||||
/* NAME_MASK *table;
|
||||
/* const NAME_MASK *table;
|
||||
/* int mask;
|
||||
/*
|
||||
/* int name_mask_opt(context, table, names, flags)
|
||||
/* const char *context;
|
||||
/* NAME_MASK *table;
|
||||
/* const NAME_MASK *table;
|
||||
/* const char *names;
|
||||
/* int flags;
|
||||
/*
|
||||
/* int name_mask_delim_opt(context, table, names, delim, flags)
|
||||
/* const char *context;
|
||||
/* NAME_MASK *table;
|
||||
/* const NAME_MASK *table;
|
||||
/* const char *names;
|
||||
/* const char *delim;
|
||||
/* int flags;
|
||||
@@ -32,7 +32,7 @@
|
||||
/* const char *str_name_mask_opt(buf, context, table, mask, flags)
|
||||
/* VSTRING *buf;
|
||||
/* const char *context;
|
||||
/* NAME_MASK *table;
|
||||
/* const NAME_MASK *table;
|
||||
/* int mask;
|
||||
/* int flags;
|
||||
/* DESCRIPTION
|
||||
@@ -129,14 +129,14 @@
|
||||
|
||||
/* name_mask_delim_opt - compute mask corresponding to list of names */
|
||||
|
||||
int name_mask_delim_opt(const char *context, NAME_MASK *table,
|
||||
int name_mask_delim_opt(const char *context, const NAME_MASK *table,
|
||||
const char *names, const char *delim, int flags)
|
||||
{
|
||||
const char *myname = "name_mask";
|
||||
char *saved_names = mystrdup(names);
|
||||
char *bp = saved_names;
|
||||
int result = 0;
|
||||
NAME_MASK *np;
|
||||
const NAME_MASK *np;
|
||||
char *name;
|
||||
int (*lookup) (const char *, const char *);
|
||||
|
||||
@@ -177,11 +177,11 @@ int name_mask_delim_opt(const char *context, NAME_MASK *table,
|
||||
/* str_name_mask_opt - mask to string */
|
||||
|
||||
const char *str_name_mask_opt(VSTRING *buf, const char *context,
|
||||
NAME_MASK *table,
|
||||
const NAME_MASK *table,
|
||||
int mask, int flags)
|
||||
{
|
||||
const char *myname = "name_mask";
|
||||
NAME_MASK *np;
|
||||
const NAME_MASK *np;
|
||||
int len;
|
||||
static VSTRING *my_buf = 0;
|
||||
int delim = (flags & NAME_MASK_COMMA ? ',' :
|
||||
@@ -230,7 +230,7 @@ const char *str_name_mask_opt(VSTRING *buf, const char *context,
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
static NAME_MASK table[] = {
|
||||
static const NAME_MASK table[] = {
|
||||
"zero", 1 << 0,
|
||||
"one", 1 << 1,
|
||||
"two", 1 << 2,
|
||||
|
@@ -45,8 +45,8 @@ typedef struct {
|
||||
#define str_name_mask(tag, table, mask) \
|
||||
str_name_mask_opt(((VSTRING *) 0), (tag), (table), (mask), NAME_MASK_DEFAULT)
|
||||
|
||||
extern int name_mask_delim_opt(const char *, NAME_MASK *, const char *, const char *, int);
|
||||
extern const char *str_name_mask_opt(VSTRING *, const char *, NAME_MASK *, int, int);
|
||||
extern int name_mask_delim_opt(const char *, const NAME_MASK *, const char *, const char *, int);
|
||||
extern const char *str_name_mask_opt(VSTRING *, const char *, const NAME_MASK *, int, int);
|
||||
|
||||
/* LICENSE
|
||||
/* .ad
|
||||
|
Reference in New Issue
Block a user