mirror of
https://github.com/vdukhovni/postfix
synced 2025-08-31 06:05:37 +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
|
20071123
|
||||||
|
|
||||||
Further polishing of the Milter code. With SETSYMLIST, each
|
Further polishing of the Milter code. With SETSYMLIST, each
|
||||||
Milter can update its own macros instead of clobbering
|
Milter can now update its own macros instead of clobbering
|
||||||
the global copy is shared with other Milters. Also an
|
the global copy that is shared with other Milters. Also an
|
||||||
opportunity to clean up some ad-hoc code for sending macro
|
opportunity to clean up some ad-hoc code for sending macro
|
||||||
lists from smtp(8) to cleanup(8). Files: milter/milter.c,
|
lists from smtp(8) to cleanup(8). Files: milter/milter.c,
|
||||||
milter/milter8.c, milter/milter_macros.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)
|
The mail_release_date configuration parameter (format: yyyymmdd)
|
||||||
specifies the release date of a stable release or snapshot release.
|
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
|
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>
|
<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)
|
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>
|
<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)
|
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.
|
filter) applications after an unknown SMTP command.
|
||||||
.IP "\fBmilter_end_of_header_macros (see postconf -n output)\fR"
|
.IP "\fBmilter_end_of_header_macros (see postconf -n output)\fR"
|
||||||
The macros that are sent to Milter (mail filter) applications
|
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"
|
.IP "\fBmilter_end_of_data_macros (see postconf -n output)\fR"
|
||||||
The macros that are sent to Milter (mail filter) applications
|
The macros that are sent to Milter (mail filter) applications
|
||||||
after the message end-of-data.
|
after the message end-of-data.
|
||||||
|
@@ -146,6 +146,14 @@ static void cleanup_envelope_process(CLEANUP_STATE *state, int type,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif
|
#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) {
|
if (type == REC_TYPE_MILT_COUNT) {
|
||||||
/* Not part of queue file format. */
|
/* Not part of queue file format. */
|
||||||
if ((milter_count = atoi(buf)) >= 0)
|
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);
|
state->milters = milter_receive(state->src, count);
|
||||||
if (state->milters == 0)
|
if (state->milters == 0)
|
||||||
msg_fatal("cleanup_milter_receive: milter receive failed");
|
msg_fatal("cleanup_milter_receive: milter receive failed");
|
||||||
|
if (count <= 0)
|
||||||
|
return;
|
||||||
milter_macro_callback(state->milters, cleanup_milter_eval, (void *) state);
|
milter_macro_callback(state->milters, cleanup_milter_eval, (void *) state);
|
||||||
milter_edit_callback(state->milters,
|
milter_edit_callback(state->milters,
|
||||||
cleanup_add_header, cleanup_upd_header,
|
cleanup_add_header, cleanup_upd_header,
|
||||||
|
@@ -20,7 +20,7 @@
|
|||||||
* Patches change both the patchlevel and the release date. Snapshots have no
|
* Patches change both the patchlevel and the release date. Snapshots have no
|
||||||
* patchlevel; they change the release date only.
|
* patchlevel; they change the release date only.
|
||||||
*/
|
*/
|
||||||
#define MAIL_RELEASE_DATE "20071223"
|
#define MAIL_RELEASE_DATE "20071224"
|
||||||
#define MAIL_VERSION_NUMBER "2.5"
|
#define MAIL_VERSION_NUMBER "2.5"
|
||||||
|
|
||||||
#ifdef SNAPSHOT
|
#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 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
|
* to be disabled (either in global error state or in global accept
|
||||||
* state).
|
* 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)
|
if (milters != 0)
|
||||||
for (m = milters->milter_list; m != 0; m = m->next)
|
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);
|
(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,
|
(void) attr_print(stream, ATTR_FLAG_MORE,
|
||||||
ATTR_TYPE_FUNC, milter_macros_print,
|
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)
|
for (m = milters->milter_list; m != 0; m = m->next)
|
||||||
if (m->active(m) && (status = m->send(m, stream)) != 0)
|
if (m->active(m) && (status = m->send(m, stream)) != 0)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Over to you.
|
||||||
|
*/
|
||||||
if (status != 0
|
if (status != 0
|
||||||
|| attr_scan(stream, ATTR_FLAG_STRICT,
|
|| attr_scan(stream, ATTR_FLAG_STRICT,
|
||||||
ATTR_TYPE_INT, MAIL_ATTR_STATUS, &status,
|
ATTR_TYPE_INT, MAIL_ATTR_STATUS, &status,
|
||||||
@@ -643,20 +658,39 @@ MILTERS *milter_receive(VSTREAM *stream, int count)
|
|||||||
MILTER *head = 0;
|
MILTER *head = 0;
|
||||||
MILTER *tail = 0;
|
MILTER *tail = 0;
|
||||||
MILTER *milter = 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,
|
* XXX We must instantiate a MILTERS structure even when the sender has
|
||||||
ATTR_TYPE_END) != 1) {
|
* no active filters, otherwise the cleanup server would try to use its
|
||||||
milter_macros_free(macros);
|
* own non_smtpd_milters settings.
|
||||||
return (0);
|
*/
|
||||||
}
|
|
||||||
#define NO_MILTERS ((char *) 0)
|
#define NO_MILTERS ((char *) 0)
|
||||||
#define NO_TIMEOUTS 0, 0, 0
|
#define NO_TIMEOUTS 0, 0, 0
|
||||||
#define NO_PROTOCOL ((char *) 0)
|
#define NO_PROTOCOL ((char *) 0)
|
||||||
#define NO_ACTION ((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.
|
* Receive the filters.
|
||||||
@@ -677,6 +711,9 @@ MILTERS *milter_receive(VSTREAM *stream, int count)
|
|||||||
tail = milter;
|
tail = milter;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Over to you.
|
||||||
|
*/
|
||||||
(void) attr_print(stream, ATTR_FLAG_NONE,
|
(void) attr_print(stream, ATTR_FLAG_NONE,
|
||||||
ATTR_TYPE_INT, MAIL_ATTR_STATUS, 0,
|
ATTR_TYPE_INT, MAIL_ATTR_STATUS, 0,
|
||||||
ATTR_TYPE_END);
|
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_ZERO 1 /* null pointer */
|
||||||
#define MILTER_MACROS_ALLOC_EMPTY 2 /* mystrdup(""); */
|
#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.
|
* A bunch of Milters.
|
||||||
*/
|
*/
|
||||||
|
@@ -123,7 +123,7 @@
|
|||||||
/* Introduced with Sendmail 8.14. */
|
/* Introduced with Sendmail 8.14. */
|
||||||
#define SMFIC_QUIT_NC 'K' /* Quit + new connection */
|
#define SMFIC_QUIT_NC 'K' /* Quit + new connection */
|
||||||
|
|
||||||
static NAME_CODE smfic_table[] = {
|
static const NAME_CODE smfic_table[] = {
|
||||||
"SMFIC_ABORT", SMFIC_ABORT,
|
"SMFIC_ABORT", SMFIC_ABORT,
|
||||||
"SMFIC_BODY", SMFIC_BODY,
|
"SMFIC_BODY", SMFIC_BODY,
|
||||||
"SMFIC_CONNECT", SMFIC_CONNECT,
|
"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_ADDRCPT_PAR '2' /* add recipient (incl. ESMTP args) */
|
||||||
#define SMFIR_SETSYMLIST 'l' /* set list of symbols (macros) */
|
#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_ADDRCPT", SMFIR_ADDRCPT,
|
||||||
"SMFIR_DELRCPT", SMFIR_DELRCPT,
|
"SMFIR_DELRCPT", SMFIR_DELRCPT,
|
||||||
"SMFIR_ACCEPT", SMFIR_ACCEPT,
|
"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_DATA | SMFIP_NR_UNKN | SMFIP_NR_HDR | SMFIP_NR_EOH | \
|
||||||
SMFIP_NR_BODY)
|
SMFIP_NR_BODY)
|
||||||
|
|
||||||
static NAME_MASK smfip_table[] = {
|
static const NAME_MASK smfip_table[] = {
|
||||||
"SMFIP_NOCONNECT", SMFIP_NOCONNECT,
|
"SMFIP_NOCONNECT", SMFIP_NOCONNECT,
|
||||||
"SMFIP_NOHELO", SMFIP_NOHELO,
|
"SMFIP_NOHELO", SMFIP_NOHELO,
|
||||||
"SMFIP_NOMAIL", SMFIP_NOMAIL,
|
"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_ADDRCPT_PAR (1L<<7) /* filter may add recipients + args */
|
||||||
#define SMFIF_SETSYMLIST (1L<<8) /* filter may send macro names */
|
#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_ADDHDRS", SMFIF_ADDHDRS,
|
||||||
"SMFIF_CHGBODY", SMFIF_CHGBODY,
|
"SMFIF_CHGBODY", SMFIF_CHGBODY,
|
||||||
"SMFIF_ADDRCPT", SMFIF_ADDRCPT,
|
"SMFIF_ADDRCPT", SMFIF_ADDRCPT,
|
||||||
@@ -306,7 +306,7 @@ static NAME_MASK smfif_table[] = {
|
|||||||
#define SMFIM_EOM 5 /* macros for end-of-message */
|
#define SMFIM_EOM 5 /* macros for end-of-message */
|
||||||
#define SMFIM_EOH 6 /* macros for end-of-header */
|
#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_CONNECT", SMFIM_CONNECT,
|
||||||
"SMFIM_HELO", SMFIM_HELO,
|
"SMFIM_HELO", SMFIM_HELO,
|
||||||
"SMFIM_ENVFROM", SMFIM_ENVFROM,
|
"SMFIM_ENVFROM", SMFIM_ENVFROM,
|
||||||
@@ -318,10 +318,10 @@ static NAME_CODE smfim_table[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Mapping from external macro set numbers to our internal MILTERS structure
|
* Mapping from external macro set numbers to our internal MILTER_MACROS
|
||||||
* members, without using a switch statement.
|
* 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, conn_macros), /* SMFIM_CONNECT */
|
||||||
offsetof(MILTER_MACROS, helo_macros), /* SMFIM_HELO */
|
offsetof(MILTER_MACROS, helo_macros), /* SMFIM_HELO */
|
||||||
offsetof(MILTER_MACROS, mail_macros), /* SMFIM_ENVFROM */
|
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
|
* XXX Is this still needed? Sendmail 8.14 provides a proper way to negotiate
|
||||||
* what replies the mail filter will send.
|
* 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,
|
"2", MILTER8_V2_PROTO_MASK,
|
||||||
"3", MILTER8_V3_PROTO_MASK,
|
"3", MILTER8_V3_PROTO_MASK,
|
||||||
"4", MILTER8_V4_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
|
* protocol extensions such as "no_header_reply", and require that exactly
|
||||||
* one version number is specified.
|
* one version number is specified.
|
||||||
*/
|
*/
|
||||||
static NAME_CODE milter8_versions[] = {
|
static const NAME_CODE milter8_versions[] = {
|
||||||
"2", 2,
|
"2", 2,
|
||||||
"3", 3,
|
"3", 3,
|
||||||
"4", 4,
|
"4", 4,
|
||||||
@@ -1750,8 +1750,7 @@ static void milter8_connect(MILTER8 *milter)
|
|||||||
msg_info("override %s macro list with \"%s\"",
|
msg_info("override %s macro list with \"%s\"",
|
||||||
smfim_name, STR(buf));
|
smfim_name, STR(buf));
|
||||||
mac_value_ptr = MILTER8_MACRO_PTR(milter->m.macros, mac_type);
|
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));
|
*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 *,
|
static MILTER8 *milter8_alloc(const char *, int, int, int, const char *,
|
||||||
const char *, MILTERS *);
|
const char *, MILTERS *);
|
||||||
|
|
||||||
/* milter8_receive - receive milter instance */
|
/* 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.
|
* Fill in the structure.
|
||||||
*/
|
*/
|
||||||
milter = milter8_alloc(name, conn_timeout, cmd_timeout, msg_timeout,
|
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
|
* XXX Sendmail 8 libmilter closes the MTA-to-filter socket when it finds
|
||||||
|
@@ -38,47 +38,52 @@
|
|||||||
/* void *ptr;
|
/* void *ptr;
|
||||||
/* DESCRIPTION
|
/* DESCRIPTION
|
||||||
/* Sendmail mail filter (Milter) applications receive sets of
|
/* Sendmail mail filter (Milter) applications receive sets of
|
||||||
/* macro (name=value) pairs with each SMTP or content event.
|
/* macro name=value pairs with each SMTP or content event.
|
||||||
/* In Postfix, the lists of names are stored in MILTER_MACROS
|
/* In Postfix, these macro names are stored in MILTER_MACROS
|
||||||
/* structures. By default, the same structure is shared by all
|
/* structures, as one list for each event type. By default,
|
||||||
/* Milter applications; it is initialized with information
|
/* the same structure is shared by all Milter applications;
|
||||||
/* from main.cf. With Sendmail 8.14 a Milter can override one
|
/* it is initialized with information from main.cf. With
|
||||||
/* or more lists of macro names, and individual filters may
|
/* Sendmail 8.14 a Milter can override one or more lists of
|
||||||
/* have their own partial list.
|
/* 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
|
/* This module maintains per-event macro name lists as
|
||||||
/* values. The user is explicitly allowed to update these
|
/* mystrdup()'ed values. The user is explicitly allowed to
|
||||||
/* values directly, as long as they respect the mystrdup()
|
/* update these values directly, as long as the result is
|
||||||
/* interface.
|
/* compatible with mystrdup().
|
||||||
/*
|
/*
|
||||||
/* milter_macros_create() creates a MILTER_MACROS structure
|
/* milter_macros_create() creates a MILTER_MACROS structure
|
||||||
/* and initializes it with copies of its string arguments.
|
/* 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.
|
/* that is initialized according to its init_mode argument.
|
||||||
/* .IP MILTER_MACROS_ALLOC_ZERO
|
/* .IP MILTER_MACROS_ALLOC_ZERO
|
||||||
/* Initialize all members as null pointers. This mode is
|
/* Initialize all structure members as null pointers. This
|
||||||
/* recommended for applications that use milter_macros_scan().
|
/* 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
|
/* .IP MILTER_MACROS_ALLOC_EMPTY
|
||||||
/* Initialize all members with mystrdup(""). This is not as
|
/* Initialize all structure members with mystrdup(""). This
|
||||||
/* expensive as it appears to be. This mode is recommend for
|
/* is not as expensive as it appears to be.
|
||||||
/* applications that update individual MILTER_MACROS members
|
|
||||||
/* directly.
|
|
||||||
/* .PP
|
/* .PP
|
||||||
/* milter_macros_free() destroys a MILTER_MACROS structure and
|
/* milter_macros_free() destroys a MILTER_MACROS structure and
|
||||||
/* frees any strings referenced by it.
|
/* frees any strings referenced by it.
|
||||||
/*
|
/*
|
||||||
/* milter_macros_print() writes the contents of a MILTER_MACROS
|
/* milter_macros_print() writes the contents of a MILTER_MACROS
|
||||||
/* structure to the named stream using the specified attribute
|
/* 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:
|
/* as a call-back to attr_print*(), thusly:
|
||||||
/*
|
/*
|
||||||
/* ATTR_TYPE_FUNC, milter_macros_print, (void *) macros,
|
/* ATTR_TYPE_FUNC, milter_macros_print, (void *) macros,
|
||||||
/*
|
/*
|
||||||
/* milter_macros_scan() reads a MILTER_MACROS structure from
|
/* milter_macros_scan() reads a MILTER_MACROS structure from
|
||||||
/* the named stream using the specified attribute scan routine.
|
/* the named stream using the specified attribute scan routine.
|
||||||
/* milter_macros_scan() is meant to be passed as a call-back
|
/* No attempt is made to free the memory of existing structure
|
||||||
/* to attr_scan*(), thusly:
|
/* 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,
|
/* ATTR_TYPE_FUNC, milter_macros_scan, (void *) macros,
|
||||||
/* DIAGNOSTICS
|
/* DIAGNOSTICS
|
||||||
@@ -121,7 +126,7 @@
|
|||||||
#define MAIL_ATTR_MILT_MAC_EOD "eod_macros"
|
#define MAIL_ATTR_MILT_MAC_EOD "eod_macros"
|
||||||
#define MAIL_ATTR_MILT_MAC_UNK "unk_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 milter_macros_print(ATTR_PRINT_MASTER_FN print_fn, VSTREAM *fp,
|
||||||
int flags, void *ptr)
|
int flags, void *ptr)
|
||||||
@@ -146,13 +151,17 @@ int milter_macros_print(ATTR_PRINT_MASTER_FN print_fn, VSTREAM *fp,
|
|||||||
return (ret);
|
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 milter_macros_scan(ATTR_SCAN_MASTER_FN scan_fn, VSTREAM *fp,
|
||||||
int flags, void *ptr)
|
int flags, void *ptr)
|
||||||
{
|
{
|
||||||
MILTER_MACROS *mp = (MILTER_MACROS *) ptr;
|
MILTER_MACROS *mp = (MILTER_MACROS *) ptr;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We could simplify this by moving memory allocation into attr_scan*().
|
||||||
|
*/
|
||||||
VSTRING *conn_macros = vstring_alloc(10);
|
VSTRING *conn_macros = vstring_alloc(10);
|
||||||
VSTRING *helo_macros = vstring_alloc(10);
|
VSTRING *helo_macros = vstring_alloc(10);
|
||||||
VSTRING *mail_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);
|
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 *milter_macros_alloc(int mode)
|
||||||
{
|
{
|
||||||
MILTER_MACROS *mp;
|
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));
|
mp = (MILTER_MACROS *) mymalloc(sizeof(*mp));
|
||||||
switch (mode) {
|
switch (mode) {
|
||||||
case MILTER_MACROS_ALLOC_ZERO:
|
case MILTER_MACROS_ALLOC_ZERO:
|
||||||
@@ -242,6 +267,30 @@ MILTER_MACROS *milter_macros_alloc(int mode)
|
|||||||
|
|
||||||
void milter_macros_free(MILTER_MACROS *mp)
|
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);
|
milter_macros_wipe(mp);
|
||||||
myfree((char *) mp);
|
myfree((char *) mp);
|
||||||
}
|
}
|
||||||
|
@@ -18,7 +18,7 @@
|
|||||||
/* Arguments (multiple alternatives are separated by "\fB|\fR"):
|
/* Arguments (multiple alternatives are separated by "\fB|\fR"):
|
||||||
/* .IP "\fB-a accept|tempfail|reject|discard|skip|\fIddd x.y.z text\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
|
/* 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"
|
/* .IP "\fB-d\fI level\fR"
|
||||||
/* Enable libmilter debugging at the specified level.
|
/* Enable libmilter debugging at the specified level.
|
||||||
/* .IP "\fB-c connect|helo|mail|rcpt|data|header|eoh|body|eom|unknown|close|abort\fR"
|
/* .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.
|
/* Terminate after \fIcount\fR connections.
|
||||||
/* .IP "\fB-i \fI'index header-label header-value'\fR"
|
/* .IP "\fB-i \fI'index header-label header-value'\fR"
|
||||||
/* Insert header at specified position.
|
/* 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"
|
/* .IP "\fB-m connect|helo|mail|rcpt|data|eoh|eom\fR"
|
||||||
/* The protocol stage that receives the list of macros specified
|
/* The protocol stage that receives the list of macros specified
|
||||||
/* with \fB-M\fR. The default protocol stage is \fBconnect\fR.
|
/* with \fB-M\fR. The default protocol stage is \fBconnect\fR.
|
||||||
@@ -100,7 +103,7 @@ struct command_map {
|
|||||||
int *reply;
|
int *reply;
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct command_map command_map[] = {
|
static const struct command_map command_map[] = {
|
||||||
"connect", &test_connect_reply,
|
"connect", &test_connect_reply,
|
||||||
"helo", &test_helo_reply,
|
"helo", &test_helo_reply,
|
||||||
"mail", &test_mail_reply,
|
"mail", &test_mail_reply,
|
||||||
@@ -387,7 +390,7 @@ struct noproto_map {
|
|||||||
FILTER_ACTION *action;
|
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,
|
"connect", SMFIP_NOCONNECT, SMFIP_NR_CONN, &test_connect_reply, &smfilter.xxfi_connect,
|
||||||
"helo", SMFIP_NOHELO, SMFIP_NR_HELO, &test_helo_reply, &smfilter.xxfi_helo,
|
"helo", SMFIP_NOHELO, SMFIP_NR_HELO, &test_helo_reply, &smfilter.xxfi_helo,
|
||||||
"mail", SMFIP_NOMAIL, SMFIP_NR_MAIL, &test_mail_reply, &smfilter.xxfi_envfrom,
|
"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 nosend_mask;
|
||||||
static int noreply_mask;
|
static int noreply_mask;
|
||||||
|
static int misc_mask;
|
||||||
|
|
||||||
static sfsistat test_negotiate(SMFICTX *ctx,
|
static sfsistat test_negotiate(SMFICTX *ctx,
|
||||||
unsigned long f0,
|
unsigned long f0,
|
||||||
@@ -420,10 +424,10 @@ static sfsistat test_negotiate(SMFICTX *ctx,
|
|||||||
smfi_setsymlist(ctx, set_macro_state, set_macro_list);
|
smfi_setsymlist(ctx, set_macro_state, set_macro_list);
|
||||||
}
|
}
|
||||||
if (verbose)
|
if (verbose)
|
||||||
printf("negotiate f0=%lx *pf0 = %lx f1=%lx *pf1=%lx nosend=%lx noreply=%lx\n",
|
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);
|
f0, *pf0, f1, *pf1, (long) nosend_mask, (long) noreply_mask, (long) misc_mask);
|
||||||
*pf0 = f0;
|
*pf0 = f0;
|
||||||
*pf1 = f1 & (nosend_mask | noreply_mask);
|
*pf1 = f1 & (nosend_mask | noreply_mask | misc_mask);
|
||||||
return (SMFIS_CONTINUE);
|
return (SMFIS_CONTINUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -439,7 +443,9 @@ static void parse_hdr_info(const char *optarg, int *idx,
|
|||||||
fprintf(stderr, "out of memory\n");
|
fprintf(stderr, "out of memory\n");
|
||||||
exit(1);
|
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);
|
fprintf(stderr, "bad header info: %s\n", optarg);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
@@ -449,16 +455,16 @@ int main(int argc, char **argv)
|
|||||||
{
|
{
|
||||||
char *action = 0;
|
char *action = 0;
|
||||||
char *command = 0;
|
char *command = 0;
|
||||||
struct command_map *cp;
|
const struct command_map *cp;
|
||||||
int ch;
|
int ch;
|
||||||
int code;
|
int code;
|
||||||
const char **cpp;
|
const char **cpp;
|
||||||
char *set_macro_state_arg = 0;
|
char *set_macro_state_arg = 0;
|
||||||
char *nosend = 0;
|
char *nosend = 0;
|
||||||
char *noreply = 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) {
|
switch (ch) {
|
||||||
case 'a':
|
case 'a':
|
||||||
action = optarg;
|
action = optarg;
|
||||||
@@ -482,6 +488,18 @@ int main(int argc, char **argv)
|
|||||||
#else
|
#else
|
||||||
fprintf(stderr, "no libmilter support to insert header\n");
|
fprintf(stderr, "no libmilter support to insert header\n");
|
||||||
exit(1);
|
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
|
#endif
|
||||||
break;
|
break;
|
||||||
case 'm':
|
case 'm':
|
||||||
@@ -493,6 +511,7 @@ int main(int argc, char **argv)
|
|||||||
set_macro_state_arg = optarg;
|
set_macro_state_arg = optarg;
|
||||||
#else
|
#else
|
||||||
fprintf(stderr, "no libmilter support to specify macro list\n");
|
fprintf(stderr, "no libmilter support to specify macro list\n");
|
||||||
|
exit(1);
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
case 'M':
|
case 'M':
|
||||||
|
@@ -211,7 +211,7 @@
|
|||||||
/* filter) applications after an unknown SMTP command.
|
/* filter) applications after an unknown SMTP command.
|
||||||
/* .IP "\fBmilter_end_of_header_macros (see postconf -n output)\fR"
|
/* .IP "\fBmilter_end_of_header_macros (see postconf -n output)\fR"
|
||||||
/* The macros that are sent to Milter (mail filter) applications
|
/* 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"
|
/* .IP "\fBmilter_end_of_data_macros (see postconf -n output)\fR"
|
||||||
/* The macros that are sent to Milter (mail filter) applications
|
/* The macros that are sent to Milter (mail filter) applications
|
||||||
/* after the message end-of-data.
|
/* 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
|
* XXX Send Milter information first, because this will hang when cleanup
|
||||||
* goes into "throw away" mode. Also, cleanup needs to know early on
|
* goes into "throw away" mode. Also, cleanup needs to know early on
|
||||||
* whether or not it has to do its own SMTP event emulation.
|
* 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) {
|
if (state->dest) {
|
||||||
state->cleanup = state->dest->stream;
|
state->cleanup = state->dest->stream;
|
||||||
|
@@ -14,12 +14,12 @@
|
|||||||
/* } NAME_CODE;
|
/* } NAME_CODE;
|
||||||
/*
|
/*
|
||||||
/* int name_code(table, flags, name)
|
/* int name_code(table, flags, name)
|
||||||
/* NAME_CODE *table;
|
/* const NAME_CODE *table;
|
||||||
/* int flags;
|
/* int flags;
|
||||||
/* const char *name;
|
/* const char *name;
|
||||||
/*
|
/*
|
||||||
/* const char *str_name_code(table, code)
|
/* const char *str_name_code(table, code)
|
||||||
/* NAME_CODE *table;
|
/* const NAME_CODE *table;
|
||||||
/* int code;
|
/* int code;
|
||||||
/* DESCRIPTION
|
/* DESCRIPTION
|
||||||
/* This module does simple name<->number mapping. The process
|
/* This module does simple name<->number mapping. The process
|
||||||
@@ -66,9 +66,9 @@
|
|||||||
|
|
||||||
/* name_code - look up code by name */
|
/* 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 *);
|
int (*lookup) (const char *, const char *);
|
||||||
|
|
||||||
if (flags & NAME_CODE_FLAG_STRICT_CASE)
|
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 */
|
/* 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++)
|
for (np = table; np->name; np++)
|
||||||
if (code == np->code)
|
if (code == np->code)
|
||||||
|
@@ -22,8 +22,8 @@ typedef struct {
|
|||||||
#define NAME_CODE_FLAG_NONE 0
|
#define NAME_CODE_FLAG_NONE 0
|
||||||
#define NAME_CODE_FLAG_STRICT_CASE (1<<0)
|
#define NAME_CODE_FLAG_STRICT_CASE (1<<0)
|
||||||
|
|
||||||
extern int name_code(NAME_CODE *, int, const char *);
|
extern int name_code(const NAME_CODE *, int, const char *);
|
||||||
extern const char *str_name_code(NAME_CODE *, int);
|
extern const char *str_name_code(const NAME_CODE *, int);
|
||||||
|
|
||||||
/* LICENSE
|
/* LICENSE
|
||||||
/* .ad
|
/* .ad
|
||||||
|
@@ -8,23 +8,23 @@
|
|||||||
/*
|
/*
|
||||||
/* int name_mask(context, table, names)
|
/* int name_mask(context, table, names)
|
||||||
/* const char *context;
|
/* const char *context;
|
||||||
/* NAME_MASK *table;
|
/* const NAME_MASK *table;
|
||||||
/* const char *names;
|
/* const char *names;
|
||||||
/*
|
/*
|
||||||
/* const char *str_name_mask(context, table, mask)
|
/* const char *str_name_mask(context, table, mask)
|
||||||
/* const char *context;
|
/* const char *context;
|
||||||
/* NAME_MASK *table;
|
/* const NAME_MASK *table;
|
||||||
/* int mask;
|
/* int mask;
|
||||||
/*
|
/*
|
||||||
/* int name_mask_opt(context, table, names, flags)
|
/* int name_mask_opt(context, table, names, flags)
|
||||||
/* const char *context;
|
/* const char *context;
|
||||||
/* NAME_MASK *table;
|
/* const NAME_MASK *table;
|
||||||
/* const char *names;
|
/* const char *names;
|
||||||
/* int flags;
|
/* int flags;
|
||||||
/*
|
/*
|
||||||
/* int name_mask_delim_opt(context, table, names, delim, flags)
|
/* int name_mask_delim_opt(context, table, names, delim, flags)
|
||||||
/* const char *context;
|
/* const char *context;
|
||||||
/* NAME_MASK *table;
|
/* const NAME_MASK *table;
|
||||||
/* const char *names;
|
/* const char *names;
|
||||||
/* const char *delim;
|
/* const char *delim;
|
||||||
/* int flags;
|
/* int flags;
|
||||||
@@ -32,7 +32,7 @@
|
|||||||
/* const char *str_name_mask_opt(buf, context, table, mask, flags)
|
/* const char *str_name_mask_opt(buf, context, table, mask, flags)
|
||||||
/* VSTRING *buf;
|
/* VSTRING *buf;
|
||||||
/* const char *context;
|
/* const char *context;
|
||||||
/* NAME_MASK *table;
|
/* const NAME_MASK *table;
|
||||||
/* int mask;
|
/* int mask;
|
||||||
/* int flags;
|
/* int flags;
|
||||||
/* DESCRIPTION
|
/* DESCRIPTION
|
||||||
@@ -129,14 +129,14 @@
|
|||||||
|
|
||||||
/* name_mask_delim_opt - compute mask corresponding to list of names */
|
/* 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 *names, const char *delim, int flags)
|
||||||
{
|
{
|
||||||
const char *myname = "name_mask";
|
const char *myname = "name_mask";
|
||||||
char *saved_names = mystrdup(names);
|
char *saved_names = mystrdup(names);
|
||||||
char *bp = saved_names;
|
char *bp = saved_names;
|
||||||
int result = 0;
|
int result = 0;
|
||||||
NAME_MASK *np;
|
const NAME_MASK *np;
|
||||||
char *name;
|
char *name;
|
||||||
int (*lookup) (const char *, const char *);
|
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 */
|
/* str_name_mask_opt - mask to string */
|
||||||
|
|
||||||
const char *str_name_mask_opt(VSTRING *buf, const char *context,
|
const char *str_name_mask_opt(VSTRING *buf, const char *context,
|
||||||
NAME_MASK *table,
|
const NAME_MASK *table,
|
||||||
int mask, int flags)
|
int mask, int flags)
|
||||||
{
|
{
|
||||||
const char *myname = "name_mask";
|
const char *myname = "name_mask";
|
||||||
NAME_MASK *np;
|
const NAME_MASK *np;
|
||||||
int len;
|
int len;
|
||||||
static VSTRING *my_buf = 0;
|
static VSTRING *my_buf = 0;
|
||||||
int delim = (flags & NAME_MASK_COMMA ? ',' :
|
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)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
static NAME_MASK table[] = {
|
static const NAME_MASK table[] = {
|
||||||
"zero", 1 << 0,
|
"zero", 1 << 0,
|
||||||
"one", 1 << 1,
|
"one", 1 << 1,
|
||||||
"two", 1 << 2,
|
"two", 1 << 2,
|
||||||
|
@@ -45,8 +45,8 @@ typedef struct {
|
|||||||
#define str_name_mask(tag, table, mask) \
|
#define str_name_mask(tag, table, mask) \
|
||||||
str_name_mask_opt(((VSTRING *) 0), (tag), (table), (mask), NAME_MASK_DEFAULT)
|
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 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 *, NAME_MASK *, int, int);
|
extern const char *str_name_mask_opt(VSTRING *, const char *, const NAME_MASK *, int, int);
|
||||||
|
|
||||||
/* LICENSE
|
/* LICENSE
|
||||||
/* .ad
|
/* .ad
|
||||||
|
Reference in New Issue
Block a user