aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2008-01-11 21:25:11 +0000
committerSergey Poznyakoff <gray@gnu.org.ua>2008-01-11 21:25:11 +0000
commit0ea6c8adaa26d07fc8cf624baefb02416c7fc850 (patch)
tree41ee79c13ca25528b865b32655bd6f70d9bf810d
parent8f6eac030e298913170ab946ce607e77da18c8c3 (diff)
downloadmailfromd-0ea6c8adaa26d07fc8cf624baefb02416c7fc850.tar.gz
mailfromd-0ea6c8adaa26d07fc8cf624baefb02416c7fc850.tar.bz2
Update
git-svn-id: file:///svnroot/mailfromd/branches/gmach@1551 7a8a7f39-df28-0410-adc6-e0d955640f24
-rw-r--r--ChangeLog3
-rw-r--r--gacopyz/gacopyz.h2
-rw-r--r--gacopyz/server.c56
-rw-r--r--pmult/pmult.c219
4 files changed, 273 insertions, 7 deletions
diff --git a/ChangeLog b/ChangeLog
index f806196a..f03b2bcd 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,8 @@
2008-01-11 Sergey Poznyakoff <gray@gnu.org.ua>
+ * pmult/pmult.c: Update
+ * gacopyz/gacopyz.h, gacopyz/server.c: Implement gacopyz_srv_conn.
+
* src/gram.y (parse_time_interval): Move to lib/parsetime.c.
* src/mailfromd.h (parse_time_interval): Move to lib/libmf.h
* lib/libmf.h (parse_time_interval): New proto.
diff --git a/gacopyz/gacopyz.h b/gacopyz/gacopyz.h
index 4c82183c..ec20ff9b 100644
--- a/gacopyz/gacopyz.h
+++ b/gacopyz/gacopyz.h
@@ -347,6 +347,8 @@ int gacopyz_srv_negotiate(gacopyz_srv_t srv);
int gacopyz_srv_abort(gacopyz_srv_t srv);
int gacopyz_srv_quit(gacopyz_srv_t srv);
+int gacopyz_srv_conn(gacopyz_srv_t srv, const char *hostname,
+ struct sockaddr *sa);
int gacopyz_srv_helo (gacopyz_srv_t p, const char *domain);
int gacopyz_srv_envfrom (gacopyz_srv_t p, char **argv);
int gacopyz_srv_envrcpt (gacopyz_srv_t p, char **argv);
diff --git a/gacopyz/server.c b/gacopyz/server.c
index e00517f1..36868b7f 100644
--- a/gacopyz/server.c
+++ b/gacopyz/server.c
@@ -1068,6 +1068,62 @@ gacopyz_srv_quit(gacopyz_srv_t srv)
}
int
+gacopyz_srv_conn(gacopyz_srv_t srv, const char *hostname, struct sockaddr *sa)
+{
+ int rc;
+ milter_sockaddr_t *ps = (milter_sockaddr_t*)sa;
+
+ GACOPYZ_ASSERT(srv);
+ if (srv->proto & SMFIP_NOCONNECT)
+ rc = SMFIR_CONTINUE;
+ else {
+ size_t hlen, vlen, size;
+ char *buf, *p, *q;
+ int code;
+
+ hlen = strlen (hostname);
+ vlen = 3;
+ switch (ps->sa.sa_family) {
+ case AF_UNIX:
+ vlen += strlen (ps->sunix.sun_path);
+ code = SMFIA_UNIX;
+ break;
+
+ case AF_INET:
+ vlen += 16;
+ code = SMFIA_INET;
+ break;
+
+ default:
+ gacopyz_io_log(&srv->iod, SMI_LOG_DEBUG,
+ _("%s: unknown family: %d"),
+ "gacopyz_srv_conn",
+ ps->sa.sa_family);
+ return SMFIR_CONTINUE;
+ }
+
+ size = hlen + vlen + 2;
+ GACOPYZ_ALLOC(srv, buf = malloc (size));
+ memcpy (buf, hostname, hlen + 1);
+ p = buf + hlen + 1;
+ *p++ = code;
+ switch (ps->sa.sa_family) {
+ case AF_UNIX:
+ strcpy (p, ps->sunix.sun_path);
+ break;
+
+ case AF_INET:
+ q = inet_ntoa (ps->sin.sin_addr);
+ memcpy (p, q, 16);
+ }
+
+ rc = gacopyz_srv_send_command(srv, SMFIC_CONNECT, buf, size);
+ free (buf);
+ }
+ return rc;
+}
+
+int
gacopyz_srv_helo(gacopyz_srv_t srv, const char *domain)
{
int rc;
diff --git a/pmult/pmult.c b/pmult/pmult.c
index c106d849..cfd17288 100644
--- a/pmult/pmult.c
+++ b/pmult/pmult.c
@@ -13,6 +13,7 @@
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
@@ -23,6 +24,7 @@
#include <mailutils/server.h>
#include <mailutils/libargp.h>
#include <sysexits.h>
+#include <pthread.h>
#include <gacopyz.h>
#include "xalloc.h"
#include "libmf.h"
@@ -63,7 +65,6 @@ const char *package_bugreport = "<" PACKAGE_BUGREPORT ">";
#include "sm/pmfdef.h"
#include "sm/pmfapi.h"
-
char *portspec;
struct pmult_client
@@ -75,7 +76,17 @@ struct pmult_client
int logmask;
};
-mu_list_t /* of gacopyz_srv_t */ client_list;
+mu_list_t /* of struct pmult_client */ client_list;
+
+struct pmult_priv_data
+{
+ mu_list_t /* of gacopyz_srv_t */ srvlist;
+};
+
+
+static pthread_mutex_t pmult_mutex = PTHREAD_MUTEX_INITIALIZER;
+#define protect() pthread_mutex_lock (&pmult_mutex)
+#define unprotect() pthread_mutex_unlock (&pmult_mutex)
static int
@@ -95,7 +106,7 @@ _cb_client_type (mu_debug_t debug, void *data, char *arg)
}
static int
-cb_timeout(struct timeval *pt, mu_debug_t debug, char *arg)
+cb_timeout (struct timeval *pt, mu_debug_t debug, char *arg)
{
const char *endp;
time_t t;
@@ -140,6 +151,68 @@ _cb_connect_timeout (mu_debug_t debug, void *data, char *arg)
}
static int
+_cb_log_level (mu_debug_t debug, void *data, char *arg)
+{
+ struct pmult_client *clt = data;
+ int argc, i;
+ char **argv;
+ int rc;
+
+ rc = mu_argcv_get_np (arg, strlen (arg), ",", NULL, 0, &argc, &argv, NULL);
+ if (rc)
+ {
+ mu_cfg_format_error (debug, MU_DEBUG_ERROR,
+ "mu_argcv_get: %s", mu_strerror (rc));
+ return 1;
+ }
+
+ for (i = 0; i < argc; i++)
+ {
+ char *p = argv[i];
+ int lev;
+ int revert = 0;
+ int upto = 0;
+
+ if (*p == '!')
+ {
+ p++;
+ revert = 1;
+ }
+ if (*p == '<')
+ {
+ p++;
+ upto = 1;
+ }
+
+ lev = gacopyz_string_to_log_level (arg);
+ if (lev == -1)
+ {
+ mu_cfg_format_error (debug, MU_DEBUG_ERROR,
+ _("Invalid log level: %s"), arg);
+ return 1;
+ }
+
+ if (revert)
+ {
+ if (upto)
+ clt->logmask &= ~SMI_LOG_UPTO (lev);
+ else
+ clt->logmask &= ~SMI_LOG_FROM (lev);
+ }
+ else
+ {
+ if (upto)
+ clt->logmask |= SMI_LOG_UPTO (lev);
+ else
+ clt->logmask |= SMI_LOG_FROM (lev);
+ }
+ }
+
+ mu_argcv_free (argc, argv);
+ return 0;
+}
+
+static int
_cb_portspec (mu_debug_t debug, void *data, char *arg)
{
char **pptr = data, *ptr;
@@ -200,6 +273,13 @@ struct mu_cfg_param client_cfg_param[] = {
{ "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 }
};
@@ -211,6 +291,13 @@ struct mu_cfg_param pmult_cfg_param[] = {
{ NULL }
};
+static void
+pmult_client_free (struct pmult_client *clt)
+{
+ free (clt->name);
+ free (clt);
+}
+
static int
client_block_begin (mu_debug_t debug, char *name, void **section_data)
{
@@ -226,11 +313,16 @@ client_block_end (mu_debug_t debug, struct pmult_client *clt)
gacopyz_srv_t gsrv;
int rc = gacopyz_srv_create (&gsrv, clt->name, clt->url, clt->logmask);
if (rc)
- return 1; /* FIXME: error message */
+ {
+ pmult_client_free (clt);
+ return 1; /* FIXME: error message */
+ }
+
if (!client_list)
{
+ gacopyz_srv_destroy (&gsrv);
MU_ASSERT (mu_list_create (&client_list));
- mu_list_append (client_list, gsrv);
+ mu_list_append (client_list, clt);
}
return 0;
}
@@ -322,7 +414,66 @@ static struct argp argp = {
NULL,
NULL
};
-
+
+
+typedef int (*pmult_runfun_t) (pmse_ctx_P pmse_ctx, void *data);
+
+static int
+pmult_runlist (struct pmult_priv_data *p, pmult_runfun_t runfun,
+ pmse_ctx_P pmse_ctx, void *data)
+{
+ int rc;
+ mu_iterator_t itr;
+
+ 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;
+
+ mu_iterator_current (itr, (void**)&gsrv);
+ protect ();
+ rc = runfun (pmse_ctx, data);
+ /* FIXME */
+ unprotect ();
+ }
+
+ protect ();
+ mu_iterator_destroy (&itr);
+ unprotect ();
+}
+
+void
+pmult_shutdown (pmse_ctx_P pmse_ctx, struct pmult_priv_data *p)
+{
+ mu_iterator_t itr;
+
+ 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;
+
+ mu_iterator_current (itr, (void**)&gsrv);
+ gacopyz_srv_quit (gsrv);
+ gacopyz_srv_close (gsrv);
+ gacopyz_srv_destroy (&gsrv);
+ }
+ protect ();
+ mu_iterator_destroy (&itr);
+ mu_list_destroy (&p->srvlist);
+ unprotect ();
+
+ free (p);
+ sm_pmfi_set_ctx_se (pmse_ctx, NULL);
+}
+
static void
version (FILE *stream, struct argp_state *state)
@@ -361,18 +512,70 @@ static sfsistat_T
pmult_connect (pmse_ctx_P pmse_ctx, const char *hostname,
sm_sockaddr_T *hostaddr)
{
+ int rc;
+ mu_iterator_t itr;
+ struct pmult_priv_data *p;
+
+ p = malloc (sizeof *p);
+ if (!p)
+ {
+ mu_error ("%s: accept", mu_strerror (ENOMEM));
+ return SMTP_R_ACCEPT;
+ }
+ rc = mu_list_create (&p->srvlist);
+ if (rc)
+ {
+ mu_error ("mu_list_create: %s", mu_strerror (rc));
+ free (p);
+ return SMTP_R_ACCEPT;
+ }
+
+ 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;
+
+ 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);
+ }
+ gacopyz_srv_negotiate (gsrv);
+ protect ();
+ gacopyz_srv_conn (gsrv, hostname, &hostaddr->sa);
+ unprotect ();
+ mu_list_append (p->srvlist, gsrv);
+ }
+
+ protect ();
+ mu_iterator_destroy (&itr);
+ unprotect ();
+
return SMTP_R_CONT;
}
static sm_ret_T
pmult_close (pmse_ctx_P pmse_ctx)
{
+ struct pmult_priv_data *p = sm_pmfi_get_ctx_se (pmse_ctx);
+ pmult_shutdown (pmse_ctx, p);
return SM_SUCCESS;
}
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);
+
return SMTP_R_CONT;
}
@@ -383,7 +586,7 @@ pmult_mail (pmse_ctx_P pmse_ctx, const char *mail, char **argv)
}
static sfsistat_T
-pmult_rcpt(pmse_ctx_P pmse_ctx, const char *rcpt, char **argv)
+pmult_rcpt (pmse_ctx_P pmse_ctx, const char *rcpt, char **argv)
{
return SMTP_R_CONT;
}
@@ -403,6 +606,8 @@ pmult_unknown (pmse_ctx_P pmse_ctx, const char *cmd)
static sm_ret_T
pmult_abort (pmse_ctx_P pmse_ctx)
{
+ struct pmult_priv_data *p = sm_pmfi_get_ctx_se (pmse_ctx);
+ pmult_shutdown (pmse_ctx, p);
return SM_SUCCESS;
}

Return to:

Send suggestions and report system problems to the System administrator.