diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2008-01-12 00:05:36 +0000 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2008-01-12 00:05:36 +0000 |
commit | e0a0c604857935387254ab9cd8e53fe5becf9de4 (patch) | |
tree | 71a4b47d7f806fb7a3ea27b1ae847a3afd2975fa | |
parent | d44669876a9658995140bf92b5e558eec56382ac (diff) | |
download | mailfromd-e0a0c604857935387254ab9cd8e53fe5becf9de4.tar.gz mailfromd-e0a0c604857935387254ab9cd8e53fe5becf9de4.tar.bz2 |
* src/mailfromd.h, lib/libmf.h (dict_init, dict_install)
(dict_destroy, dict_getsym): Move to lib/libmf.h.
* src/prog (dict_init, dict_install, dict_destroy)
(dict_getsym): Move to lib/dict.c.
* lib/dict.c: New file.
* lib/Makefile.am: Add dict.c.
* pmult/pmult.c: Implement framework for milter macros.
git-svn-id: file:///svnroot/mailfromd/branches/gmach@1554 7a8a7f39-df28-0410-adc6-e0d955640f24
-rw-r--r-- | ChangeLog | 11 | ||||
-rw-r--r-- | lib/Makefile.am | 1 | ||||
-rw-r--r-- | lib/dict.c | 91 | ||||
-rw-r--r-- | lib/libmf.h | 7 | ||||
-rw-r--r-- | pmult/pmult.c | 155 | ||||
-rw-r--r-- | src/mailfromd.h | 6 | ||||
-rw-r--r-- | src/prog.c | 66 |
7 files changed, 256 insertions, 81 deletions
@@ -1,3 +1,14 @@ +2008-01-12 Sergey Poznyakoff <gray@gnu.org.ua> + + * src/mailfromd.h, lib/libmf.h (dict_init, dict_install) + (dict_destroy, dict_getsym): Move to lib/libmf.h. + * src/prog (dict_init, dict_install, dict_destroy) + (dict_getsym): Move to lib/dict.c. + * lib/dict.c: New file. + * lib/Makefile.am: Add dict.c. + + * pmult/pmult.c: Implement framework for milter macros. + 2008-01-11 Sergey Poznyakoff <gray@gnu.org.ua> * gacopyz/gacopyz.c (parse_url): Bugfix. diff --git a/lib/Makefile.am b/lib/Makefile.am index d321b61d..af44f802 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -22,6 +22,7 @@ EXTRA_DIST = syslog_async.c SYSLOG_ASYNC_O=syslog_async.o libmf_a_SOURCES=\ + dict.c\ nls.c\ parsetime.c\ version.c diff --git a/lib/dict.c b/lib/dict.c new file mode 100644 index 00000000..78e9a98c --- /dev/null +++ b/lib/dict.c @@ -0,0 +1,91 @@ +/* This file is part of mailfromd. + Copyright (C) 2007, 2008 Sergey Poznyakoff + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif +#include <stdlib.h> +#include <string.h> +#include <mailutils/assoc.h> +#include <mailutils/errno.h> +#include "xalloc.h" + + +/* Rudimentary dictionary support */ +struct dict_entry { + char *value; +}; + +void +name_destroy(void *item) +{ + struct dict_entry *ent = item; + free(ent->value); +} + +void +dict_init(mu_assoc_t *dict) +{ + mu_assoc_create(dict, sizeof (struct dict_entry), 0); + mu_assoc_set_free(*dict, name_destroy); +} + +char * +dict_install(mu_assoc_t dict, const char *name, const char *value) +{ + struct dict_entry *p; + int rc; + + rc = mu_assoc_ref_install (dict, name, (void **)&p); + if (rc == MU_ERR_EXISTS) + free (p->value); + p->value = xstrdup (value); + return 0; +} + +void +dict_destroy(mu_assoc_t *dict) +{ + mu_assoc_destroy(dict); +} + +char * +dict_getsym(void *data, const char *str) +{ + mu_assoc_t dict = data; + struct dict_entry *p; + char *tmp = NULL; + char *val = NULL; + + if (str[0] == '{') { + int len = strlen(str); + if (str[len-1] == '}') { + tmp = malloc(len-1); + if (!tmp) + abort(); + memcpy(tmp, str+1, len-2); + tmp[len-2] = 0; + str = tmp; + } + } + + p = mu_assoc_ref(dict, str); + if (p) + val = p->value; + free(tmp); + return val; +} + diff --git a/lib/libmf.h b/lib/libmf.h index 527d8d2b..9cc68889 100644 --- a/lib/libmf.h +++ b/lib/libmf.h @@ -15,6 +15,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. */ #include <gettext.h> +#include <mailutils/types.h> #define _(String) gettext(String) #define N_(String) String @@ -22,3 +23,9 @@ void mailfromd_version(const char *progname, FILE *stream); void mf_init_nls (void); int parse_time_interval(const char *str, time_t *pint, const char **endp); + +void dict_init(mu_assoc_t *dict); +char *dict_install(mu_assoc_t dict, const char *name, const char *value); +void dict_destroy(mu_assoc_t *dict); +char *dict_getsym(void *data, const char *str); + diff --git a/pmult/pmult.c b/pmult/pmult.c index 9d4675fc..367fccd6 100644 --- a/pmult/pmult.c +++ b/pmult/pmult.c @@ -89,6 +89,8 @@ struct pmult_priv_data { mu_debug_t debug; mu_list_t /* of gacopyz_srv_t */ srvlist; + unsigned nrcpt; + unsigned nbadrcpts; }; @@ -361,8 +363,10 @@ pmult_client_free (struct pmult_client *clt) static int client_block_begin (mu_debug_t debug, char *name, void **section_data) { + extern struct timeval default_gacopyz_timeout[GACOPYZ_TO_COUNT]; struct pmult_client *clt = xcalloc (1, sizeof *clt); clt->name = name ? xstrdup (name) : ""; + memcpy (clt->timeout, default_gacopyz_timeout, sizeof clt->timeout); *section_data = clt; return 0; } @@ -503,6 +507,43 @@ static struct argp argp = { }; +static void +pmult_macros_install (struct pmult_priv_data *p, const char **kv) +{ + mu_iterator_t itr = NULL; + + protect (); + mu_list_get_iterator (p->srvlist, &itr); + unprotect (); + + for (mu_iterator_first (itr); !mu_iterator_is_done (itr); + mu_iterator_next (itr)) + { + gacopyz_srv_t gsrv; + int i; + + mu_iterator_current (itr, (void**)&gsrv); + for (i = 0; kv[i]; i += 2) + gacopyz_srv_define_macro (gsrv, kv[i], kv[i+1]); + } + + protect (); + mu_iterator_destroy (&itr); + unprotect (); +} + +static void +pmult_macro_install (struct pmult_priv_data *p, const char *name, + const char *value) +{ + const char *kv[3]; + kv[0] = name; + kv[1] = value; + kv[2] = NULL; + pmult_macros_install (p, kv); +} + + typedef int (*pmult_runfun_t) (pmse_ctx_P pmse_ctx, void *data); static int @@ -619,7 +660,7 @@ pmult_connect (pmse_ctx_P pmse_ctx, const char *hostname, free (p); } - p = malloc (sizeof *p); + p = calloc (1, sizeof *p); if (!p) { mu_error ("%s: accept", mu_strerror (ENOMEM)); @@ -635,7 +676,7 @@ pmult_connect (pmse_ctx_P pmse_ctx, const char *hostname, free (p); return SMTP_R_ACCEPT; } - + protect (); mu_list_get_iterator (client_list, &itr); unprotect (); @@ -656,6 +697,7 @@ pmult_connect (pmse_ctx_P pmse_ctx, const char *hostname, gacopyz_srv_destroy (&gsrv); } gacopyz_srv_negotiate (gsrv); + gacopyz_srv_define_macro0 (gsrv, "r", "SMTP", 0); protect (); gacopyz_srv_conn (gsrv, hostname, &hostaddr->sa); unprotect (); @@ -665,7 +707,7 @@ pmult_connect (pmse_ctx_P pmse_ctx, const char *hostname, protect (); mu_iterator_destroy (&itr); unprotect (); - + sm_pmfi_set_ctx_se (pmse_ctx, p); return SMTP_R_CONT; } @@ -674,8 +716,10 @@ 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); + { + MU_DEBUG (p->debug, MU_DEBUG_TRACE1, "Closing connection\n"); + pmult_shutdown (pmse_ctx, p); + } return SM_SUCCESS; } @@ -683,14 +727,16 @@ 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); + MU_DEBUG1 (p->debug, MU_DEBUG_TRACE1, "HELO %s\n", helohost); + pmult_macro_install (p, "s", helohost); return SMTP_R_CONT; } static sfsistat_T pmult_mail (pmse_ctx_P pmse_ctx, const char *mail, char **argv) { + int rc; + mu_address_t addr; struct pmult_priv_data *p = sm_pmfi_get_ctx_se (pmse_ctx); if (p && mu_debug_check_level (p->debug, MU_DEBUG_TRACE1)) { @@ -700,13 +746,74 @@ pmult_mail (pmse_ctx_P pmse_ctx, const char *mail, char **argv) __MU_DEBUG1 (p->debug, MU_DEBUG_TRACE1, " %s", argv[i]); MU_DEBUG (p->debug, MU_DEBUG_TRACE1, "\n"); } + rc = mu_address_create (&addr, mail); + if (rc) + pmult_macro_install (p, "f", mail); + else + { + mu_address_sget_email (addr, 1, &mail); + pmult_macro_install (p, "f", mail); + mu_address_destroy (&addr); + } return SMTP_R_CONT; } +int +parse_email_addr (const char *arg, char **psender, char **addr, char **host) +{ + size_t len; + const char *p = arg, *q; + if (*p == '<') + { + len = strlen (p); + if (p[len-1] != '>') + return 1; + p++; + *psender = malloc (len - 1); + if (*psender) + { + memcpy (*psender, p, len - 2); + (*psender)[len - 2] = 0; + } + } + else + *psender = strdup (arg); + if (!*psender) + return 1; + p = *psender; + q = strchr (p, '@'); + if (q) + len = q - p; + else + len = strlen (p); + *addr = malloc (len + 1); + if (!*addr) + { + free (*psender); + return 1; + } + memcpy (*addr, p, len); + (*addr)[len] = 0; + if (q) + q++; + else + q = "localhost"; + *host = strdup (q); + if (!*host) + { + free (*psender); + free (*addr); + return 1; + } + return 0; +} + 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); + char *sender, *addr, *host; + if (p && mu_debug_check_level (p->debug, MU_DEBUG_TRACE1)) { int i; @@ -715,6 +822,34 @@ pmult_rcpt (pmse_ctx_P pmse_ctx, const char *rcpt, char **argv) __MU_DEBUG1 (p->debug, MU_DEBUG_TRACE1, " %s", argv[i]); MU_DEBUG (p->debug, MU_DEBUG_TRACE1, "\n"); } + + p->nrcpt++; + if (parse_email_addr (rcpt, &sender, &addr, &host)) + { + MU_DEBUG1 (p->debug, MU_DEBUG_ERROR, "bad recipient address %s", rcpt); + p->nbadrcpts++; + } + else + { + const char *kv[7]; + char buf1[128], buf2[128]; + snprintf (buf1, sizeof buf1, "%u", p->nrcpt); + snprintf (buf2, sizeof buf2, "%u", p->nbadrcpts); + kv[0] = "nrcpts"; + kv[1] = buf1; + kv[2] = "nbadrcpts"; + kv[3] = buf2; + kv[4] = "rcpt_host"; + kv[5] = host; + kv[6] = "rcpt_addr"; + kv[7] = addr; + kv[8] = NULL; + pmult_macros_install (p, kv); + } + free (sender); + free (addr); + free (host); + return SMTP_R_CONT; } @@ -741,8 +876,10 @@ 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); + { + MU_DEBUG (p->debug, MU_DEBUG_TRACE1, "ABORT\n"); + pmult_shutdown (pmse_ctx, p); + } return SM_SUCCESS; } diff --git a/src/mailfromd.h b/src/mailfromd.h index 88cbd070..f1162ec9 100644 --- a/src/mailfromd.h +++ b/src/mailfromd.h @@ -744,12 +744,6 @@ extern void priv_setup(void); void mailfromd_daemon(void); void save_cmdline(int argc, char **argv); -/* DNS dictionary */ -void dict_init(mu_assoc_t *dict); -char *dict_install(mu_assoc_t dict, char *name, char *value); -void dict_destroy(mu_assoc_t *dict); -char *dict_getsym(void *data, char *str); - void mailfromd_test(int argc, char **argv); int set_option(char *name, char *value, int override); @@ -2055,72 +2055,6 @@ env_builtin_priv_destroy(eval_environ_t env) } } - -/* Rudimentary dictionary support */ -struct dict_entry { - char *value; -}; - -void -name_destroy(void *item) -{ - struct dict_entry *ent = item; - free(ent->value); -} - -void -dict_init(mu_assoc_t *dict) -{ - mu_assoc_create(dict, sizeof (struct dict_entry), 0); - mu_assoc_set_free(*dict, name_destroy); -} - -char * -dict_install(mu_assoc_t dict, char *name, char *value) -{ - struct dict_entry *p; - int rc; - - rc = mu_assoc_ref_install (dict, name, (void **)&p); - if (rc == MU_ERR_EXISTS) - free (p->value); - p->value = xstrdup (value); - return 0; -} - -void -dict_destroy(mu_assoc_t *dict) -{ - mu_assoc_destroy(dict); -} - -char * -dict_getsym(void *data, char *str) -{ - mu_assoc_t dict = data; - struct dict_entry *p; - char *tmp = NULL; - char *val = NULL; - - if (str[0] == '{') { - int len = strlen(str); - if (str[len-1] == '}') { - tmp = malloc(len-1); - if (!tmp) - abort(); - memcpy(tmp, str+1, len-2); - tmp[len-2] = 0; - str = tmp; - } - } - - p = mu_assoc_ref(dict, str); - if (p) - val = p->value; - free(tmp); - return val; -} - /* Initialize the data segment and relocate string variables */ static void init_dataseg(STKVAL *dseg) |