aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2008-01-12 00:05:36 +0000
committerSergey Poznyakoff <gray@gnu.org.ua>2008-01-12 00:05:36 +0000
commite0a0c604857935387254ab9cd8e53fe5becf9de4 (patch)
tree71a4b47d7f806fb7a3ea27b1ae847a3afd2975fa
parentd44669876a9658995140bf92b5e558eec56382ac (diff)
downloadmailfromd-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--ChangeLog11
-rw-r--r--lib/Makefile.am1
-rw-r--r--lib/dict.c91
-rw-r--r--lib/libmf.h7
-rw-r--r--pmult/pmult.c155
-rw-r--r--src/mailfromd.h6
-rw-r--r--src/prog.c66
7 files changed, 256 insertions, 81 deletions
diff --git a/ChangeLog b/ChangeLog
index 2a28c706..b731d924 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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);
diff --git a/src/prog.c b/src/prog.c
index 9f4f6049..7305b518 100644
--- a/src/prog.c
+++ b/src/prog.c
@@ -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)

Return to:

Send suggestions and report system problems to the System administrator.