diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2008-01-11 22:38:15 +0000 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2008-01-11 22:38:15 +0000 |
commit | d03485268ceba39ba496d52c1ec012da1f96b66c (patch) | |
tree | 93997734cd0578a322aeb9a751625afa195df438 | |
parent | 0ea6c8adaa26d07fc8cf624baefb02416c7fc850 (diff) | |
download | mailfromd-d03485268ceba39ba496d52c1ec012da1f96b66c.tar.gz mailfromd-d03485268ceba39ba496d52c1ec012da1f96b66c.tar.bz2 |
* gacopyz/gacopyz.c (parse_url): Bugfix.
* pmult/pmult.c: Update.
git-svn-id: file:///svnroot/mailfromd/branches/gmach@1552 7a8a7f39-df28-0410-adc6-e0d955640f24
-rw-r--r-- | ChangeLog | 2 | ||||
-rw-r--r-- | gacopyz/gacopyz.c | 6 | ||||
-rw-r--r-- | pmult/pmult.c | 226 |
3 files changed, 197 insertions, 37 deletions
@@ -1,5 +1,7 @@ 2008-01-11 Sergey Poznyakoff <gray@gnu.org.ua> + * gacopyz/gacopyz.c (parse_url): Bugfix. + * pmult/pmult.c: Update * gacopyz/gacopyz.h, gacopyz/server.c: Implement gacopyz_srv_conn. diff --git a/gacopyz/gacopyz.c b/gacopyz/gacopyz.c index acc1ae67..f20a506f 100644 --- a/gacopyz/gacopyz.c +++ b/gacopyz/gacopyz.c @@ -95,9 +95,11 @@ parse_url(const char *proto, const char *cstr, char **pport, char **ppath) { const char *p = strchr (cstr, ':'); - if (!p) + if (!p) { *pport = NULL; - else if (copy_part(cstr, p, ppath)) + *ppath = strdup(cstr); + return *ppath == NULL ? MI_FAILURE : 0; + } else if (copy_part(cstr, p, ppath)) return MI_FAILURE; else cstr = p + 1; diff --git a/pmult/pmult.c b/pmult/pmult.c index cfd17288..9d4675fc 100644 --- a/pmult/pmult.c +++ b/pmult/pmult.c @@ -65,7 +65,13 @@ const char *package_bugreport = "<" PACKAGE_BUGREPORT ">"; #include "sm/pmfdef.h" #include "sm/pmfapi.h" -char *portspec; +char *portspec; /* Communication socket */ +int log_to_stderr; /* Use stderr for logging */ +char *syslog_tag; /* Tag to mark syslog entries with. */ +mu_log_level_t debug_level; +mu_debug_t pmult_debug; +char *pidfile; + struct pmult_client { @@ -75,11 +81,13 @@ struct pmult_client char *url; int logmask; }; - + +/* List of configured clients: */ mu_list_t /* of struct pmult_client */ client_list; struct pmult_priv_data { + mu_debug_t debug; mu_list_t /* of gacopyz_srv_t */ srvlist; }; @@ -89,6 +97,36 @@ static pthread_mutex_t pmult_mutex = PTHREAD_MUTEX_INITIALIZER; #define unprotect() pthread_mutex_unlock (&pmult_mutex) +/* Logging */ +void +log_setup (int want_stderr) +{ + mu_debug_t debug; + + mu_diag_get_debug (&debug); + + if (!want_stderr) + { + openlog (syslog_tag, LOG_PID, log_facility); + gacopyz_set_logger (gacopyz_syslog_log_printer); + mu_debug_set_print (debug, mu_diag_syslog_printer, NULL); + mu_debug_default_printer = mu_debug_syslog_printer; + } + else + gacopyz_set_logger (gacopyz_stderr_log_printer); +} + +static int +stderr_closed_p() +{ + int fd = dup(0); + if (fd < 0) + return 1; + close(fd); + return fd <= 2; +} + + static int _cb_client_type (mu_debug_t debug, void *data, char *arg) { @@ -184,7 +222,7 @@ _cb_log_level (mu_debug_t debug, void *data, char *arg) upto = 1; } - lev = gacopyz_string_to_log_level (arg); + lev = gacopyz_string_to_log_level (p); if (lev == -1) { mu_cfg_format_error (debug, MU_DEBUG_ERROR, @@ -212,13 +250,41 @@ _cb_log_level (mu_debug_t debug, void *data, char *arg) return 0; } +struct mu_cfg_param client_cfg_param[] = { + { "type", mu_cfg_callback, NULL, 0, _cb_client_type, + N_("Set remote milter type. Only `milter' is understood so far."), + N_("{milter [version: number]|pmilter}") }, + { "url", mu_cfg_string, NULL, mu_offsetof(struct pmult_client, url), NULL, + N_("Set remote client URL.") }, + { "write-timeout", mu_cfg_callback, NULL, 0, _cb_write_timeout, + N_("Set write timeout."), + N_("time") }, + { "read-timeout", mu_cfg_callback, NULL, 0, _cb_read_timeout, + N_("Set read timeout."), + N_("time") }, + { "eom-timeout", mu_cfg_callback, NULL, 0, _cb_eom_timeout, + N_("Set timeout for EOM."), + N_("time") }, + { "connect-timeout", mu_cfg_callback, NULL, 0, _cb_connect_timeout, + N_("Set connect timeout."), + N_("time") }, + { "log-level", mu_cfg_callback, NULL, 0, _cb_log_level, + N_("Set log verbosity level. Arg is a list of items separated by commas " + "or whitespace. Each item is a log level optionally prefixed with `!' " + "to indicate `any level except this', or '<', meaning `all levels up " + "to and including this'. Log levels in order of increasing priority " + "are: debug, info, warn, err, fatal."), + N_("arg: list") }, + { NULL } +}; + static int _cb_portspec (mu_debug_t debug, void *data, char *arg) { char **pptr = data, *ptr; - char *proto; - char *port; - char *path; + char *proto = NULL; + char *port = NULL; + char *path = NULL; size_t len; if (gacopyz_parse_connection (arg, &proto, &port, &path)) @@ -251,43 +317,37 @@ _cb_portspec (mu_debug_t debug, void *data, char *arg) } strcat (ptr, path); } + free (path); + free (port); + free (proto); *pptr = ptr; return 0; } -struct mu_cfg_param client_cfg_param[] = { - { "type", mu_cfg_callback, NULL, 0, _cb_client_type, - N_("Set remote milter type. Only `milter' is understood so far."), - N_("{milter [version: number]|pmilter}") }, - { "url", mu_cfg_string, NULL, mu_offsetof(struct pmult_client, url), NULL, - N_("Set remote client URL.") }, - { "write-timeout", mu_cfg_callback, NULL, 0, _cb_write_timeout, - N_("Set write timeout."), - N_("time") }, - { "read-timeout", mu_cfg_callback, NULL, 0, _cb_read_timeout, - N_("Set read timeout."), - N_("time") }, - { "eom-timeout", mu_cfg_callback, NULL, 0, _cb_eom_timeout, - N_("Set timeout for EOM."), - N_("time") }, - { "connect-timeout", mu_cfg_callback, NULL, 0, _cb_connect_timeout, - N_("Set connect timeout."), - N_("time") }, - { "log-level", mu_cfg_callback, NULL, 0, _cb_log_level, - N_("Set server log level. Arg is a list of items separated by commas or " - "whitespace. Each item is a log level optionally prefixed with `!' " - "to indicate `any level except this', or '<', meaning `all levels up " - "to and including this'. Log levels in order of decreasing priority " - "are: debug, info, warn, err, fatal."), - N_("arg: list") }, - { NULL } -}; +static int +_cb_debug (mu_debug_t debug, void *data, char *arg) +{ + int rc; + + rc = mu_debug_level_from_string (arg, &debug_level, debug); + if (rc) + return 0; + if (!pmult_debug) + mu_debug_create (&pmult_debug, NULL); + mu_debug_set_level (pmult_debug, debug_level); + return 0; +} struct mu_cfg_param pmult_cfg_param[] = { { "listen", mu_cfg_callback, &portspec, 0, _cb_portspec, N_("Listen for milter requests on the given URL."), N_("url") }, { "client", mu_cfg_section }, + /* MU-FIXME: */ + { "log-tag", mu_cfg_string, &syslog_tag, 0, NULL, + N_("Set syslog tag string.") }, + { "debug", mu_cfg_callback, NULL, 0, _cb_debug, + N_("Set debug verbosity level.") }, { NULL } }; @@ -365,12 +425,22 @@ static char doc[] = N_("pmult -- pmilter multiplexer"); static char args_doc[] = ""; enum { - OPTION_URL = 256 + OPTION_URL = 256, + OPTION_SYSLOG, + OPTION_LOG_TAG, }; static struct argp_option options[] = { { "url", OPTION_URL, N_("URL"), 0, N_("Listen on the given URL"), 0 }, + { "syslog", OPTION_SYSLOG, NULL, 0, + N_("Log to syslog (default)"), }, + { "stderr", 's', NULL, 0, + N_("Log to stderr"), }, + { "log-tag", OPTION_LOG_TAG, N_("STRING"), 0, + N_("Set the identifier used in syslog messages to STRING"), }, + { "debug", 'x', N_("LEVEL"), 0, + N_("Set debug verbosity level.") }, { NULL } }; @@ -385,6 +455,22 @@ parse_opt (int key, char *arg, struct argp_state *state) mu_argp_node_list_new (&lst, "listen", arg); break; + case OPTION_SYSLOG: + log_to_stderr = 0; + break; + + case 's': + log_to_stderr = 1; + break; + + case 'x': + mu_argp_node_list_new (&lst, "debug", arg); + break; + + case OPTION_LOG_TAG: + mu_argp_node_list_new (&lst, "log-tag", arg); + break; + case ARGP_KEY_INIT: mu_argp_node_list_init (&lst); break; @@ -401,6 +487,7 @@ parse_opt (int key, char *arg, struct argp_state *state) static const char *capa[] = { "common", + "debug", "logging", NULL }; @@ -470,6 +557,7 @@ pmult_shutdown (pmse_ctx_P pmse_ctx, struct pmult_priv_data *p) mu_list_destroy (&p->srvlist); unprotect (); + mu_debug_destroy (&p->debug, NULL); free (p); sm_pmfi_set_ctx_se (pmse_ctx, NULL); } @@ -515,17 +603,35 @@ pmult_connect (pmse_ctx_P pmse_ctx, const char *hostname, int rc; mu_iterator_t itr; struct pmult_priv_data *p; + mu_debug_t dbg = NULL; + + if (debug_level) + { + mu_debug_create (&dbg, NULL); + mu_debug_set_level (dbg, debug_level); + } + if (mu_debug_check_level (dbg, MU_DEBUG_TRACE1)) + { + char *p = mu_sockaddr_to_astr (&hostaddr->sa, sizeof *hostaddr); + __MU_DEBUG2 (dbg, MU_DEBUG_TRACE1, + "Connect from: %s, address %s\n", hostname, p); + free (p); + } + p = malloc (sizeof *p); if (!p) { mu_error ("%s: accept", mu_strerror (ENOMEM)); + mu_debug_destroy (&dbg, NULL); return SMTP_R_ACCEPT; } + p->debug = dbg; rc = mu_list_create (&p->srvlist); if (rc) { mu_error ("mu_list_create: %s", mu_strerror (rc)); + mu_debug_destroy (&dbg, NULL); free (p); return SMTP_R_ACCEPT; } @@ -567,6 +673,8 @@ static sm_ret_T pmult_close (pmse_ctx_P pmse_ctx) { struct pmult_priv_data *p = sm_pmfi_get_ctx_se (pmse_ctx); + if (p) + MU_DEBUG (p->debug, MU_DEBUG_TRACE1, "Closing connection\n"); pmult_shutdown (pmse_ctx, p); return SM_SUCCESS; } @@ -575,31 +683,56 @@ static sfsistat_T pmult_helo (pmse_ctx_P pmse_ctx, const char *helohost, bool ehlo) { struct pmult_priv_data *p = sm_pmfi_get_ctx_se (pmse_ctx); - + if (p) + MU_DEBUG1 (p->debug, MU_DEBUG_TRACE1, "HELO %s\n", helohost); return SMTP_R_CONT; } static sfsistat_T pmult_mail (pmse_ctx_P pmse_ctx, const char *mail, char **argv) { + struct pmult_priv_data *p = sm_pmfi_get_ctx_se (pmse_ctx); + if (p && mu_debug_check_level (p->debug, MU_DEBUG_TRACE1)) + { + int i; + __MU_DEBUG1 (p->debug, MU_DEBUG_TRACE1, "MAIL FROM: %s", mail); + for (i = 0; argv[i]; i++) + __MU_DEBUG1 (p->debug, MU_DEBUG_TRACE1, " %s", argv[i]); + MU_DEBUG (p->debug, MU_DEBUG_TRACE1, "\n"); + } return SMTP_R_CONT; } static sfsistat_T pmult_rcpt (pmse_ctx_P pmse_ctx, const char *rcpt, char **argv) { + struct pmult_priv_data *p = sm_pmfi_get_ctx_se (pmse_ctx); + if (p && mu_debug_check_level (p->debug, MU_DEBUG_TRACE1)) + { + int i; + __MU_DEBUG1 (p->debug, MU_DEBUG_TRACE1, "RCPT TO: %s", rcpt); + for (i = 0; argv[i]; i++) + __MU_DEBUG1 (p->debug, MU_DEBUG_TRACE1, " %s", argv[i]); + MU_DEBUG (p->debug, MU_DEBUG_TRACE1, "\n"); + } return SMTP_R_CONT; } static sfsistat_T pmult_data (pmse_ctx_P pmse_ctx) { + struct pmult_priv_data *p = sm_pmfi_get_ctx_se (pmse_ctx); + if (p) + MU_DEBUG (p->debug, MU_DEBUG_TRACE1, "DATA\n"); return SMTP_R_CONT; } static sfsistat_T pmult_unknown (pmse_ctx_P pmse_ctx, const char *cmd) { + struct pmult_priv_data *p = sm_pmfi_get_ctx_se (pmse_ctx); + if (p) + MU_DEBUG1 (p->debug, MU_DEBUG_TRACE1, "Unknown command %s\n", cmd); return SMTP_R_CONT; } @@ -607,6 +740,8 @@ static sm_ret_T pmult_abort (pmse_ctx_P pmse_ctx) { struct pmult_priv_data *p = sm_pmfi_get_ctx_se (pmse_ctx); + if (p) + MU_DEBUG (p->debug, MU_DEBUG_TRACE1, "ABORT\n"); pmult_shutdown (pmse_ctx, p); return SM_SUCCESS; } @@ -614,12 +749,25 @@ pmult_abort (pmse_ctx_P pmse_ctx) static sfsistat_T pmult_msg(pmse_ctx_P pmse_ctx, unsigned char *buf, size_t len) { + struct pmult_priv_data *p = sm_pmfi_get_ctx_se (pmse_ctx); + if (p) + { + if (mu_debug_check_level (p->debug, MU_DEBUG_TRACE1)) + __MU_DEBUG3 (p->debug, MU_DEBUG_TRACE1, "BODY %lu %.*s\n", + (unsigned long) len, (int) len, buf); + else + MU_DEBUG1 (p->debug, MU_DEBUG_TRACE1, "BODY %lu\n", + (unsigned long) len); + } return SM_SUCCESS; } static sfsistat_T pmult_eom (pmse_ctx_P pmse_ctx) { + struct pmult_priv_data *p = sm_pmfi_get_ctx_se (pmse_ctx); + if (p) + MU_DEBUG (p->debug, MU_DEBUG_TRACE1, "EOM\n"); return SMTP_R_CONT; } @@ -665,6 +813,7 @@ main (int argc, char **argv) argp_program_version_hook = version; /* Set default logging */ log_facility = DEFAULT_LOG_FACILITY; + log_setup (!stderr_closed_p ()); pmult_cfg_init (); @@ -673,6 +822,11 @@ main (int argc, char **argv) if (rc) exit (EX_CONFIG); + if (!syslog_tag) + syslog_tag = xstrdup (mu_program_name); + + log_setup (log_to_stderr); + if (!portspec) { mu_error (_("URL to listen on was not specified.")); @@ -696,7 +850,9 @@ main (int argc, char **argv) SM_ASSERT (sm_pmfi_setconn (pmg_ctx, portspec)); SM_ASSERT (sm_pmfi_set_ctx_g (pmg_ctx, NULL)); + mu_diag_output (MU_DIAG_INFO, _("%s starting"), program_version); SM_ASSERT (sm_pmfi_start (pmg_ctx, &pmilter)); + mu_diag_output (MU_DIAG_INFO, _("%s terminated"), program_version); exit (EX_OK); } |