aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2008-01-11 18:01:37 +0000
committerSergey Poznyakoff <gray@gnu.org.ua>2008-01-11 18:01:37 +0000
commitdebfe21c4267c65fe80a6d706fb4a4332b0fdf41 (patch)
tree9ead786dcb16d5d5901d9623bb725cbd0c1c0bf5
parentc7daadf0f361c0013014e5df230c0eb51e0b6762 (diff)
downloadmailfromd-debfe21c4267c65fe80a6d706fb4a4332b0fdf41.tar.gz
mailfromd-debfe21c4267c65fe80a6d706fb4a4332b0fdf41.tar.bz2
* 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. * lib/Makefile.am: Add parsetime.c. * lib/parsetime.c: New file. * smap/smap.c: Include mailutils/daemon.h. * pmult: New directory. * pmult/pmult.c: New file. A framework for pmilter multiplexer. * pmult/Makefile.am: New file. * configure.ac: New option --enable-pmilter. * Makefile.am (SUBDIRS): Add pmult. git-svn-id: file:///svnroot/mailfromd/branches/gmach@1549 7a8a7f39-df28-0410-adc6-e0d955640f24
-rw-r--r--ChangeLog14
-rw-r--r--Makefile.am2
-rw-r--r--configure.ac51
-rw-r--r--lib/Makefile.am1
-rw-r--r--lib/libmf.h1
-rw-r--r--lib/parsetime.c107
-rw-r--r--pmult/Makefile.am36
-rw-r--r--pmult/pmult.c510
-rw-r--r--smap/smap.c1
-rw-r--r--src/gram.y85
-rw-r--r--src/mailfromd.h1
11 files changed, 722 insertions, 87 deletions
diff --git a/ChangeLog b/ChangeLog
index 391147ac..f806196a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,17 @@
+2008-01-11 Sergey Poznyakoff <gray@gnu.org.ua>
+
+ * 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.
+ * lib/Makefile.am: Add parsetime.c.
+ * lib/parsetime.c: New file.
+ * smap/smap.c: Include mailutils/daemon.h.
+ * pmult: New directory.
+ * pmult/pmult.c: New file. A framework for pmilter multiplexer.
+ * pmult/Makefile.am: New file.
+ * configure.ac: New option --enable-pmilter.
+ * Makefile.am (SUBDIRS): Add pmult.
+
2008-01-09 Sergey Poznyakoff <gray@gnu.org.ua>
* src/engine.c (check_pidfile): Bugfix.
diff --git a/Makefile.am b/Makefile.am
index 005ecda5..7d255764 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -15,7 +15,7 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
AUTOMAKE_OPTIONS = gnits 1.8.5 std-options
-SUBDIRS = gnu lib gacopyz src mflib smap elisp po etc doc tests
+SUBDIRS = gnu lib gacopyz src mflib smap pmult elisp po etc doc tests
ACLOCAL_AMFLAGS = -I m4
distuninstallcheck_listfiles = find . -type f -not -name 'mailfromd.rc' -print
diff --git a/configure.ac b/configure.ac
index 6714d217..25a9cb66 100644
--- a/configure.ac
+++ b/configure.ac
@@ -518,6 +518,54 @@ AC_MSG_RESULT($DEFAULT_LOG_FACILITY)
AC_DEFINE_UNQUOTED(DEFAULT_LOG_FACILITY, $DEFAULT_LOG_FACILITY,
[Default log facility])
+# Test for libpmilter
+AC_ARG_ENABLE([pmilter],
+ AC_HELP_STRING([--enable-pmilter=PATH-TO-META1],
+ [enable pmilter support (EXPERIMENTAL)]),
+ [case "${enableval}" in
+ /*) meta1_dir=`echo ${enableval} | sed 's,/$,,'`
+ enable_pmilter=yes
+ ;;
+ *) AC_MSG_ERROR([Argument to --enable-pmilter is not a directory name])
+ esac],[enable_pmilter=no])
+
+if test "$enable_pmilter" = yes; then
+ saved_LIBS=$LIBS
+ AC_SUBST(PTHREAD_LIBRARIES)
+ AC_CHECK_LIB(pthread, pthread_self,
+ [ have_pthread=yes
+ PTHREAD_LIBRARIES="-lpthread -lc" ],
+ [ PTHREAD_LIBRARIES="-lpthread"
+ AC_CHECK_FUNC(pthread_self,
+ [HAVE_PTHREAD=yes]) ])
+ if test $have_pthread != yes; then
+ AC_MSG_ERROR([POSIX threads library not found. Please install it and then reconfigure])
+ fi
+
+ libs="libpmilter/libpmilter.a \
+ libpmilter/libpmutil.a\
+ libevthr/libevthr.a\
+ libthr/libthr.a\
+ libmta/librcbcomm.a\
+ libmta/librcb.a\
+ libmta/libmtar.a\
+ libcheck/libcheck.a\
+ librepl/libreplr.a"
+
+ AC_SUBST(META1_LIBS)
+ for file in $libs
+ do
+ if test -f $meta1_dir/$file; then
+ META1_LIBS="$META1_LIBS $meta1_dir/$file"
+ else
+ AC_MSG_ERROR([Required library $file not found in $meta1_dir])
+ fi
+ done
+ AC_SUBST(ENABLE_PMULT,'${PMULT_PROG}')
+ AC_SUBST(META1_INCLUDES,"-I$meta1_dir/include")
+ LIBS=$saved_LIBS
+fi
+
# Doc hints.
# Select a rendition level:
# DISTRIB for stable releases (at most one dot in the version number)
@@ -561,6 +609,7 @@ Rates expire interval..................... $rates_expire
Compile asynchronous syslog............... $syslog_async
Readline (for mtasim)..................... $usereadline
Documentation rendition type.............. $rendition
+Enable pmilter support.................... $enable_pmilter
*******************************************************************
EOF
@@ -581,6 +630,7 @@ rates_expire=$DEFAULT_EXPIRE_RATES_INTERVAL
usereadline=$usereadline
rendition=$RENDITION
syslog_async=$syslog_async
+enable_pmilter=$enable_pmilter
])
AC_CONFIG_FILES([Makefile
@@ -590,6 +640,7 @@ AC_CONFIG_FILES([Makefile
src/Makefile
mflib/Makefile
smap/Makefile
+ pmult/Makefile
elisp/Makefile
po/Makefile.in
etc/Makefile
diff --git a/lib/Makefile.am b/lib/Makefile.am
index 2ffbd995..d321b61d 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -23,6 +23,7 @@ SYSLOG_ASYNC_O=syslog_async.o
libmf_a_SOURCES=\
nls.c\
+ parsetime.c\
version.c
libmf_a_LIBADD=$(LIBOBJS) $(BUILD_SYSLOG_ASYNC)
diff --git a/lib/libmf.h b/lib/libmf.h
index bf4aab50..527d8d2b 100644
--- a/lib/libmf.h
+++ b/lib/libmf.h
@@ -21,3 +21,4 @@
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);
diff --git a/lib/parsetime.c b/lib/parsetime.c
new file mode 100644
index 00000000..d449e0c3
--- /dev/null
+++ b/lib/parsetime.c
@@ -0,0 +1,107 @@
+/* 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 <ctype.h>
+
+static int
+time_multiplier(const char *str, unsigned *m, unsigned *plen)
+{
+ static struct timetab {
+ char *name;
+ unsigned mul;
+ } tab[] = {
+ { "seconds", 1 },
+ { "minutes", 60 },
+ { "hours", 60*60 },
+ { "days", 24*60*60 },
+ { "weeks", 7*24*60*60 },
+ { "months", 31*7*24*60*60 },
+ { NULL }
+ };
+ struct timetab *p;
+ int slen;
+
+ for (slen = 0; str[slen]; slen++)
+ if (isspace(str[slen]))
+ break;
+
+ for (p = tab; p->name; p++) {
+ if (p->name[0] == tolower(str[0])) {
+ int nlen = strlen(p->name);
+
+ if (nlen > slen)
+ nlen = slen;
+
+ if (strncasecmp(p->name, str, nlen) == 0) {
+ *m = p->mul;
+ if (plen)
+ *plen = nlen;
+ return 0;
+ }
+ }
+ }
+ return 1;
+}
+
+int
+parse_time_interval(const char *str, time_t *pint, const char **endp)
+{
+ int rc = 0;
+ time_t interval = 0;
+
+ while (*str) {
+ char *p;
+ unsigned long n;
+ unsigned mul, len;
+
+ while (*str && isspace(*str))
+ str++;
+
+ if (!isdigit(*str) && time_multiplier(str, &mul, &len) == 0) {
+ n = 1;
+ str += len;
+ } else {
+ n = strtoul(str, &p, 10);
+ if (*p && !isspace(*p)) {
+ str = p;
+ rc = 1;
+ break;
+ }
+
+ while (*p && isspace(*p))
+ p++;
+
+ str = p;
+ if (*str) {
+ if (rc = time_multiplier(str, &mul, &len))
+ break;
+ str += len;
+ } else
+ mul = 1;
+ }
+ interval += n*mul;
+ }
+
+ if (rc && endp)
+ *endp = str;
+ *pint = interval;
+ return rc;
+}
+
diff --git a/pmult/Makefile.am b/pmult/Makefile.am
new file mode 100644
index 00000000..2b409374
--- /dev/null
+++ b/pmult/Makefile.am
@@ -0,0 +1,36 @@
+# This file is part of mailfrom filter.
+# Copyright (C) 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/>.
+
+PMULT_PROG = pmult
+sbin_PROGRAMS = @ENABLE_PMULT@
+EXTRA_PROGRAMS = pmult
+
+INCLUDES = \
+ $(MAILUTILS_INCLUDES)\
+ $(MU_COMMON_INCLUDES)\
+ -I$(top_srcdir)/lib\
+ -I$(top_srcdir)/gnu\
+ -I../gnu\
+ -I../gacopyz\
+ @META1_INCLUDES@
+
+pmult_SOURCES = pmult.c
+LDADD = \
+ ../lib/libmf.a\
+ ../gnu/libgnu.a\
+ $(MAILUTILS_LIBS)\
+ $(MILTER)\
+ @META1_LIBS@ @PTHREAD_LIBRARIES@
diff --git a/pmult/pmult.c b/pmult/pmult.c
new file mode 100644
index 00000000..c106d849
--- /dev/null
+++ b/pmult/pmult.c
@@ -0,0 +1,510 @@
+/* This file is part of mailfromd.
+ Copyright (C) 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 <syslog.h>
+#include <mailutils/mailutils.h>
+#include <mailutils/server.h>
+#include <mailutils/libargp.h>
+#include <sysexits.h>
+#include <gacopyz.h>
+#include "xalloc.h"
+#include "libmf.h"
+
+/* There are several problems with using libpmilter, as of
+ meta1-1.0.PreAlpha22.0:
+
+ 1. libpmilter and libpmutl are installed, but none of the seven libraries
+ they depend on is;
+ 2. None of the necessary headers are installed, except pmfapi.h,
+ pmilter.h and pmfdef.h;
+ 3. The rest of headers include generic.h which defines PACKAGE_* symbols,
+ which no decent library should ever attempt to do;
+
+ I compensate for these deficiences by:
+
+ 1 and 2 - Special handling in configure.ac, which requires Meta1 sources
+ to be present;
+ 3 - Using the necessary symbols ASAP and undefining them before
+ including the pmilter headers;
+
+ Po kiego licha to robie? Bo mam, kurna, popyt!
+*/
+
+const char *program_version = "pmult (" PACKAGE_STRING ")";
+const char *package_bugreport = "<" PACKAGE_BUGREPORT ">";
+#undef PACKAGE
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+#undef VERSION
+
+#include "sm/error.h"
+#include "sm/smreplycodes.h"
+#include "sm/pmilter.h"
+#include "sm/pmfdef.h"
+#include "sm/pmfapi.h"
+
+
+char *portspec;
+
+struct pmult_client
+{
+ int type; /* Type, unused so far */
+ char *name;
+ struct timeval timeout[GACOPYZ_TO_COUNT];
+ char *url;
+ int logmask;
+};
+
+mu_list_t /* of gacopyz_srv_t */ client_list;
+
+
+static int
+_cb_client_type (mu_debug_t debug, void *data, char *arg)
+{
+ if (strcmp (arg, "milter") == 0)
+ /* dobrze */;
+ else if (strcmp (arg, "pmilter") == 0)
+ mu_cfg_format_error (debug, MU_DEBUG_ERROR,
+ _("client type %s is not supported yet"),
+ arg);
+ else
+ mu_cfg_format_error (debug, MU_DEBUG_ERROR,
+ _("unknown client type %s"),
+ arg);
+ return 0;
+}
+
+static int
+cb_timeout(struct timeval *pt, mu_debug_t debug, char *arg)
+{
+ const char *endp;
+ time_t t;
+ if (parse_time_interval (arg, &t, &endp))
+ {
+ mu_cfg_format_error (debug, MU_DEBUG_ERROR,
+ _("unrecognized time format (near `%s')"),
+ endp);
+ return 1;
+ }
+ pt->tv_usec = 0;
+ pt->tv_sec = t;
+ return 0;
+}
+
+static int
+_cb_write_timeout (mu_debug_t debug, void *data, char *arg)
+{
+ struct pmult_client *clt = data;
+ return cb_timeout (&clt->timeout[GACOPYZ_TO_WRITE], debug, arg);
+}
+
+static int
+_cb_read_timeout (mu_debug_t debug, void *data, char *arg)
+{
+ struct pmult_client *clt = data;
+ return cb_timeout (&clt->timeout[GACOPYZ_TO_READ], debug, arg);
+}
+
+static int
+_cb_eom_timeout (mu_debug_t debug, void *data, char *arg)
+{
+ struct pmult_client *clt = data;
+ return cb_timeout (&clt->timeout[GACOPYZ_TO_EOM], debug, arg);
+}
+
+static int
+_cb_connect_timeout (mu_debug_t debug, void *data, char *arg)
+{
+ struct pmult_client *clt = data;
+ return cb_timeout (&clt->timeout[GACOPYZ_TO_CONNECT], debug, arg);
+}
+
+static int
+_cb_portspec (mu_debug_t debug, void *data, char *arg)
+{
+ char **pptr = data, *ptr;
+ char *proto;
+ char *port;
+ char *path;
+ size_t len;
+
+ if (gacopyz_parse_connection (arg, &proto, &port, &path))
+ {
+ mu_cfg_format_error (debug, MU_DEBUG_ERROR, _("Invalid URL: %s"), arg);
+ return 1;
+ }
+
+ if (!proto)
+ {
+ if (port)
+ {
+ mu_cfg_format_error (debug, MU_DEBUG_ERROR,
+ _("Invalid URL: %s"), arg);
+ return 1;
+ }
+ ptr = xstrdup (path);
+ }
+ else
+ {
+ len = strlen (proto) + 1
+ + (port ? strlen (port) + 1 : 0) + strlen (path) + 1;
+ ptr = xmalloc (len);
+ strcpy (ptr, proto);
+ strcat (ptr, ":");
+ if (port)
+ {
+ strcat (ptr, port);
+ strcat (ptr, "@");
+ }
+ strcat (ptr, path);
+ }
+ *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") },
+ { NULL }
+};
+
+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 },
+ { NULL }
+};
+
+static int
+client_block_begin (mu_debug_t debug, char *name, void **section_data)
+{
+ struct pmult_client *clt = xcalloc (1, sizeof *clt);
+ clt->name = name ? xstrdup (name) : "";
+ *section_data = clt;
+ return 0;
+}
+
+static int
+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 */
+ if (!client_list)
+ {
+ MU_ASSERT (mu_list_create (&client_list));
+ mu_list_append (client_list, gsrv);
+ }
+ return 0;
+}
+
+static int
+client_section_parser (enum mu_cfg_section_stage stage,
+ const mu_cfg_node_t *node,
+ const char *section_label, void **section_data,
+ void *call_data,
+ mu_cfg_tree_t *tree)
+{
+ switch (stage)
+ {
+ case mu_cfg_section_start:
+ return client_block_begin (tree->debug, node->tag_label, section_data);
+
+ case mu_cfg_section_end:
+ return client_block_end (tree->debug,
+ (struct pmult_client *)*section_data);
+ }
+ return 0;
+}
+
+static void
+pmult_cfg_init ()
+{
+ struct mu_cfg_section *section;
+
+ if (mu_create_canned_section ("client", &section))
+ exit (EX_SOFTWARE);
+ section->parser = client_section_parser;
+ section->label = N_("ident");
+ mu_cfg_section_add_params (section, client_cfg_param);
+}
+
+
+/* Command line parsing */
+
+static char doc[] = N_("pmult -- pmilter multiplexer");
+static char args_doc[] = "";
+
+enum {
+ OPTION_URL = 256
+};
+
+static struct argp_option options[] = {
+ { "url", OPTION_URL, N_("URL"), 0,
+ N_("Listen on the given URL"), 0 },
+ { NULL }
+};
+
+static error_t
+parse_opt (int key, char *arg, struct argp_state *state)
+{
+ static struct mu_argp_node_list lst;
+
+ switch (key)
+ {
+ case OPTION_URL:
+ mu_argp_node_list_new (&lst, "listen", arg);
+ break;
+
+ case ARGP_KEY_INIT:
+ mu_argp_node_list_init (&lst);
+ break;
+
+ case ARGP_KEY_FINI:
+ mu_argp_node_list_finish (&lst, NULL, NULL);
+ break;
+
+ default:
+ return ARGP_ERR_UNKNOWN;
+ }
+ return 0;
+}
+
+static const char *capa[] = {
+ "common",
+ "logging",
+ NULL
+};
+
+static struct argp argp = {
+ options,
+ parse_opt,
+ args_doc,
+ doc,
+ NULL,
+ NULL,
+ NULL
+};
+
+
+static void
+version (FILE *stream, struct argp_state *state)
+{
+ mailfromd_version ("pmult", stream);
+}
+
+#define SM_ASSERT(expr) do \
+ { \
+ sm_ret_T ret = expr; \
+ if (sm_is_err (ret)) \
+ { \
+ char *cp = smerr2txt (ret); \
+ if (cp) \
+ mu_error ("%s:%d: " #expr " failed: %s", \
+ __FILE__, __LINE__, cp); \
+ else \
+ mu_error ("%s:%d: " #expr " failed: %#x", \
+ __FILE__, __LINE__, ret); \
+ exit (EX_CONFIG); \
+ } \
+ } \
+while (0)
+
+
+static sm_ret_T
+pmult_negotiate (pmss_ctx_P pmss_ctx,
+ uint32_t srv_cap, uint32_t srv_fct, uint32_t srv_feat,
+ uint32_t srv_misc, uint32_t *pm_cap, uint32_t *pm_fct,
+ uint32_t *pm_feat, uint32_t *pm_misc)
+{
+ return SMTP_R_CONT;
+}
+
+static sfsistat_T
+pmult_connect (pmse_ctx_P pmse_ctx, const char *hostname,
+ sm_sockaddr_T *hostaddr)
+{
+ return SMTP_R_CONT;
+}
+
+static sm_ret_T
+pmult_close (pmse_ctx_P pmse_ctx)
+{
+ return SM_SUCCESS;
+}
+
+static sfsistat_T
+pmult_helo (pmse_ctx_P pmse_ctx, const char *helohost, bool ehlo)
+{
+ return SMTP_R_CONT;
+}
+
+static sfsistat_T
+pmult_mail (pmse_ctx_P pmse_ctx, const char *mail, char **argv)
+{
+ return SMTP_R_CONT;
+}
+
+static sfsistat_T
+pmult_rcpt(pmse_ctx_P pmse_ctx, const char *rcpt, char **argv)
+{
+ return SMTP_R_CONT;
+}
+
+static sfsistat_T
+pmult_data (pmse_ctx_P pmse_ctx)
+{
+ return SMTP_R_CONT;
+}
+
+static sfsistat_T
+pmult_unknown (pmse_ctx_P pmse_ctx, const char *cmd)
+{
+ return SMTP_R_CONT;
+}
+
+static sm_ret_T
+pmult_abort (pmse_ctx_P pmse_ctx)
+{
+ return SM_SUCCESS;
+}
+
+static sfsistat_T
+pmult_msg(pmse_ctx_P pmse_ctx, unsigned char *buf, size_t len)
+{
+ return SM_SUCCESS;
+}
+
+static sfsistat_T
+pmult_eom (pmse_ctx_P pmse_ctx)
+{
+ return SMTP_R_CONT;
+}
+
+static sm_ret_T
+pmult_signal (pmg_ctx_P pmg_ctx, int sig)
+{
+ return SM_SUCCESS;
+}
+
+
+static pmilter_T pmilter = {
+ "pmult",
+ LPMILTER_VERSION,
+ SM_SCAP_PM_ALL,
+ 0,
+ 0,
+ 0,
+ pmult_negotiate,
+ pmult_connect,
+ pmult_helo,
+ pmult_mail,
+ pmult_rcpt,
+ pmult_data,
+ pmult_msg,
+ pmult_eom,
+ pmult_abort,
+ pmult_close,
+ pmult_unknown,
+ pmult_signal
+};
+
+int
+main (int argc, char **argv)
+{
+ int rc;
+ size_t count;
+ pmg_ctx_P pmg_ctx;
+ uint32_t major, minor, patchlevel;
+
+ mf_init_nls ();
+ if (!program_invocation_short_name)
+ program_invocation_short_name = argv[0];
+ argp_program_version_hook = version;
+ /* Set default logging */
+ log_facility = DEFAULT_LOG_FACILITY;
+
+ pmult_cfg_init ();
+
+ mu_argp_init (program_version, package_bugreport);
+ rc = mu_app_init (&argp, capa, pmult_cfg_param, argc, argv, 0, NULL, NULL);
+ if (rc)
+ exit (EX_CONFIG);
+
+ if (!portspec)
+ {
+ mu_error (_("URL to listen on was not specified."));
+ exit (EX_CONFIG);
+ }
+
+ if (!client_list || mu_list_count (client_list, &count) || count == 0)
+ {
+ mu_error (_("No clients configured."));
+ exit (EX_CONFIG);
+ }
+
+ SM_ASSERT (sm_pmfi_init (&pmg_ctx));
+ SM_ASSERT (sm_pmfi_version (pmg_ctx, &major, &minor, &patchlevel));
+ if (major != LPMILTER_VERSION_MAJOR)
+ {
+ mu_error (_("Version mismatch: compile_time=%d, run_time=%d"),
+ LPMILTER_VERSION_MAJOR, major);
+ exit (EX_CONFIG);
+ }
+
+ SM_ASSERT (sm_pmfi_setconn (pmg_ctx, portspec));
+ SM_ASSERT (sm_pmfi_set_ctx_g (pmg_ctx, NULL));
+ SM_ASSERT (sm_pmfi_start (pmg_ctx, &pmilter));
+ exit (EX_OK);
+}
+
+void
+xalloc_die ()
+{
+ mu_error ("not enough memory");
+ abort ();
+}
+
+/*
+ Local Variables:
+ c-file-style: "gnu"
+ End:
+*/
+/* EOF */
diff --git a/smap/smap.c b/smap/smap.c
index c5cc29b6..c1453139 100644
--- a/smap/smap.c
+++ b/smap/smap.c
@@ -32,6 +32,7 @@
#include <ctype.h>
#include <sysexits.h> /* FIXME */
#include <mailutils/mailutils.h>
+#include <mailutils/daemon.h>
#include <mailutils/server.h>
#include <mailutils/libargp.h>
#include <mailutils/libcfg.h>
diff --git a/src/gram.y b/src/gram.y
index ad552d8a..965b7224 100644
--- a/src/gram.y
+++ b/src/gram.y
@@ -2920,91 +2920,6 @@ set_poll_arg(struct poll_data *poll, int kw, NODE *expr)
}
}
-static int
-time_multiplier(const char *str, unsigned *m, unsigned *plen)
-{
- static struct timetab {
- char *name;
- unsigned mul;
- } tab[] = {
- { "seconds", 1 },
- { "minutes", 60 },
- { "hours", 60*60 },
- { "days", 24*60*60 },
- { "weeks", 7*24*60*60 },
- { "months", 31*7*24*60*60 },
- { NULL }
- };
- struct timetab *p;
- int slen;
-
- for (slen = 0; str[slen]; slen++)
- if (isspace(str[slen]))
- break;
-
- for (p = tab; p->name; p++) {
- if (p->name[0] == tolower(str[0])) {
- int nlen = strlen(p->name);
-
- if (nlen > slen)
- nlen = slen;
-
- if (strncasecmp(p->name, str, nlen) == 0) {
- *m = p->mul;
- if (plen)
- *plen = nlen;
- return 0;
- }
- }
- }
- return 1;
-}
-
-int
-parse_time_interval(const char *str, time_t *pint, const char **endp)
-{
- int rc = 0;
- time_t interval = 0;
-
- while (*str) {
- char *p;
- unsigned long n;
- unsigned mul, len;
-
- while (*str && isspace(*str))
- str++;
-
- if (!isdigit(*str) && time_multiplier(str, &mul, &len) == 0) {
- n = 1;
- str += len;
- } else {
- n = strtoul(str, &p, 10);
- if (*p && !isspace(*p)) {
- str = p;
- rc = 1;
- break;
- }
-
- while (*p && isspace(*p))
- p++;
-
- str = p;
- if (*str) {
- if (rc = time_multiplier(str, &mul, &len))
- break;
- str += len;
- } else
- mul = 1;
- }
- interval += n*mul;
- }
-
- if (rc && endp)
- *endp = str;
- *pint = interval;
- return rc;
-}
-
int
convert_rate(const char *arg, double *rate)
{
diff --git a/src/mailfromd.h b/src/mailfromd.h
index c4f31ad5..88cbd070 100644
--- a/src/mailfromd.h
+++ b/src/mailfromd.h
@@ -645,7 +645,6 @@ void parse_error(char *fmt, ...);
void parse_error_locus(const struct locus *loc, char *fmt, ...);
void parse_warning(char *fmt, ...);
void parse_warning_locus(const struct locus *loc, char *fmt, ...);
-int parse_time_interval(const char *str, time_t *pint, const char **endp);
void print_syntax_tree(void);
void print_macros(void);
const char *function_name(void);

Return to:

Send suggestions and report system problems to the System administrator.