From 2a963ce202911085c98dac7628150f4a56ee1295 Mon Sep 17 00:00:00 2001 From: Sergey Poznyakoff Date: Thu, 7 May 2009 18:50:54 +0300 Subject: Implement v6 negotiation in pmult. * pmult/pmult.c (define_single_macro): Check for table overflow. (collect_stage_symbols, collect_symlists): New functions. (pmult_negotiate) [HAVE_SM_PMFI_SETMACS]: Call collect_symlists. --- pmult/pmult.c | 115 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 114 insertions(+), 1 deletion(-) 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, ¯o)) { @@ -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, ¯o)) + { + 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**) ¯onames[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 -- cgit v1.2.1