aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--pmult/pmult.c115
1 files changed, 114 insertions, 1 deletions
diff --git a/pmult/pmult.c b/pmult/pmult.c
index 0bee2f8d..77384cd7 100644
--- a/pmult/pmult.c
+++ b/pmult/pmult.c
@@ -526,6 +526,14 @@ define_single_macro (mu_debug_t debug, const char *string, void *data)
{
struct macro_slot *slot = data;
int macro;
+
+ if (slot->num == PM_MAX_MACROS)
+ {
+ mu_cfg_format_error (debug, MU_DEBUG_ERROR,
+ _("macro table %d is full, symbol {%s} ignored"),
+ slot->stage, string);
+ return 0;
+ }
if (mu_kwd_xlat_name (macro_trans, string, &macro))
{
@@ -1275,6 +1283,110 @@ version (FILE *stream, struct argp_state *state)
}
+/* Translation table gacopyz_state -> PM state */
+static int gacopyz_to_smst[] = {
+ /* gacopyz_stage_conn -> */ PM_SMST_CONNECT,
+ /* gacopyz_stage_helo -> */ PM_SMST_EHLO,
+ /* gacopyz_stage_mail -> */ PM_SMST_MAIL,
+ /* gacopyz_stage_rcpt -> */ PM_SMST_RCPT,
+ /* gacopyz_stage_data -> */ PM_SMST_DATA,
+ /* gacopyz_stage_eom -> */ PM_SMST_DOT,
+ /* gacopyz_stage_eoh -> */ PM_SMST_DATA
+};
+
+/* For each Sendmail macro name from SYMV, find the corresponding
+ MeTA1 macro and register it for use at a given GSTAGE.
+
+ Produce verbose warnings if there are no more free slots in the
+ macro table. */
+void
+collect_stage_symbols (enum gacopyz_stage gstage, const char **symv)
+{
+ int i;
+ int smst = gacopyz_to_smst[gstage];
+
+ for (i = 0; i < PM_MAX_MACROS && macrotab[smst][i] != PMM_END; i++)
+ ;
+ for (; *symv; ++symv)
+ {
+ int macro;
+
+ if (i == PM_MAX_MACROS)
+ {
+ PMU_DEBUG2 (pmult_debug, MU_DEBUG_TRACE1,
+ _("macro table %d is full, symbol {%s} is ignored"),
+ smst, *symv);
+ continue;
+ }
+
+ if (macro_defined (macrotab[smst], i, macro))
+ continue;
+
+ if (mu_kwd_xlat_name (macro_trans, *symv, &macro))
+ {
+ PMU_DEBUG1 (pmult_debug, MU_DEBUG_TRACE1,
+ _("Sendmail macro {%s} does not translate to a MeTA1 one"),
+ *symv);
+ continue;
+ }
+
+ if (mu_kwd_xlat_tok (macro_trans, macro,
+ (const char**) &macronames[smst][i]))
+ {
+ mu_error (_("INTERNAL ERROR at %s:%d"), __FILE__, __LINE__);
+ exit (EX_SOFTWARE);
+ }
+ macrotab[smst][i++] = macro;
+ }
+}
+
+/* Run initial negotiation with each registered Gacopyz server. If the
+ negotiation returns requested macro names, register them for further
+ use. */
+
+void
+collect_symlists ()
+{
+ mu_iterator_t itr = NULL;
+
+ protect ();
+ mu_list_get_iterator (client_list, &itr);
+ unprotect ();
+
+ for (mu_iterator_first (itr); !mu_iterator_is_done (itr);
+ mu_iterator_next (itr))
+ {
+ struct pmult_client *clt;
+ gacopyz_srv_t gsrv;
+ int i;
+
+ mu_iterator_current (itr, (void**)&clt);
+ gacopyz_srv_create (&gsrv, clt->name, clt->url, clt->logmask);
+ gacopyz_srv_set_all_timeouts (gsrv, clt->timeout);
+ if (gacopyz_srv_connect (gsrv) != MI_SUCCESS)
+ {
+ mu_error (_("Failed to connect to %s (milter %s)"),
+ clt->url, clt->name);
+ gacopyz_srv_destroy (&gsrv);
+ continue;
+ }
+ gacopyz_srv_negotiate (gsrv);
+
+ for (i = 0; i < gacopyz_stage_max; i++)
+ {
+ const char **symv = gacopyz_srv_get_required_macros (gsrv, i);
+
+ if (symv)
+ collect_stage_symbols (i, symv);
+ }
+
+ gacopyz_srv_quit (gsrv);
+ gacopyz_srv_close (gsrv);
+ gacopyz_srv_destroy (&gsrv);
+ }
+ mu_iterator_destroy (&itr);
+}
+
static sm_ret_T
pmult_negotiate (pmss_ctx_P pmss_ctx,
uint32_t srv_cap, uint32_t srv_fct, uint32_t srv_feat,
@@ -1283,7 +1395,8 @@ pmult_negotiate (pmss_ctx_P pmss_ctx,
{
#if HAVE_SM_PMFI_SETMACS
uint i;
-
+
+ collect_symlists ();
for (i = 0; i < PM_SMST_MAX; i++)
SM_CHECK (sm_pmfi_setmacs (pmss_ctx, i, macrotab[i]));
#else

Return to:

Send suggestions and report system problems to the System administrator.