aboutsummaryrefslogtreecommitdiff
path: root/sendmail/libmilter/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'sendmail/libmilter/main.c')
-rw-r--r--sendmail/libmilter/main.c246
1 files changed, 246 insertions, 0 deletions
diff --git a/sendmail/libmilter/main.c b/sendmail/libmilter/main.c
new file mode 100644
index 000000000000..faff4f8363db
--- /dev/null
+++ b/sendmail/libmilter/main.c
@@ -0,0 +1,246 @@
+/*
+ * Copyright (c) 1999-2003, 2006, 2007 Sendmail, Inc. and its suppliers.
+ * All rights reserved.
+ *
+ * By using this file, you agree to the terms and conditions set
+ * forth in the LICENSE file which can be found at the top level of
+ * the sendmail distribution.
+ *
+ */
+
+#include <sm/gen.h>
+SM_RCSID("@(#)$Id: main.c,v 8.83 2007/04/23 22:22:50 ca Exp $")
+
+#define _DEFINE 1
+#include "libmilter.h"
+#include <fcntl.h>
+#include <sys/stat.h>
+
+
+static smfiDesc_ptr smfi = NULL;
+
+/*
+** SMFI_REGISTER -- register a filter description
+**
+** Parameters:
+** smfilter -- description of filter to register
+**
+** Returns:
+** MI_SUCCESS/MI_FAILURE
+*/
+
+int
+smfi_register(smfilter)
+ smfiDesc_str smfilter;
+{
+ size_t len;
+
+ if (smfi == NULL)
+ {
+ smfi = (smfiDesc_ptr) malloc(sizeof *smfi);
+ if (smfi == NULL)
+ return MI_FAILURE;
+ }
+ (void) memcpy(smfi, &smfilter, sizeof *smfi);
+ if (smfilter.xxfi_name == NULL)
+ smfilter.xxfi_name = "Unknown";
+
+ len = strlen(smfilter.xxfi_name) + 1;
+ smfi->xxfi_name = (char *) malloc(len);
+ if (smfi->xxfi_name == NULL)
+ return MI_FAILURE;
+ (void) sm_strlcpy(smfi->xxfi_name, smfilter.xxfi_name, len);
+
+ /* compare milter version with hard coded version */
+ if (smfi->xxfi_version != SMFI_VERSION &&
+ smfi->xxfi_version != 2 &&
+ smfi->xxfi_version != 3 &&
+ smfi->xxfi_version != 4)
+ {
+ /* hard failure for now! */
+ smi_log(SMI_LOG_ERR,
+ "%s: smfi_register: version mismatch application: %d != milter: %d",
+ smfi->xxfi_name, smfi->xxfi_version,
+ (int) SMFI_VERSION);
+
+ /* XXX how about smfi? */
+ free(smfi->xxfi_name);
+ return MI_FAILURE;
+ }
+
+ return MI_SUCCESS;
+}
+
+/*
+** SMFI_STOP -- stop milter
+**
+** Parameters:
+** none.
+**
+** Returns:
+** success.
+*/
+
+int
+smfi_stop()
+{
+ mi_stop_milters(MILTER_STOP);
+ return MI_SUCCESS;
+}
+
+/*
+** Default values for some variables.
+** Most of these can be changed with the functions below.
+*/
+
+static int dbg = 0;
+static char *conn = NULL;
+static int timeout = MI_TIMEOUT;
+static int backlog = MI_SOMAXCONN;
+
+/*
+** SMFI_OPENSOCKET -- try the socket setup to make sure we'll be
+** able to start up
+**
+** Parameters:
+** rmsocket -- if true, instructs libmilter to attempt
+** to remove the socket before creating it;
+** only applies for "local:" or "unix:" sockets
+**
+** Return:
+** MI_SUCCESS/MI_FAILURE
+*/
+
+int
+smfi_opensocket(rmsocket)
+ bool rmsocket;
+{
+ if (smfi == NULL || conn == NULL)
+ return MI_FAILURE;
+
+ return mi_opensocket(conn, backlog, dbg, rmsocket, smfi);
+}
+
+/*
+** SMFI_SETDBG -- set debug level.
+**
+** Parameters:
+** odbg -- new debug level.
+**
+** Returns:
+** MI_SUCCESS
+*/
+
+int
+smfi_setdbg(odbg)
+ int odbg;
+{
+ dbg = odbg;
+ return MI_SUCCESS;
+}
+
+/*
+** SMFI_SETTIMEOUT -- set timeout (for read/write).
+**
+** Parameters:
+** otimeout -- new timeout.
+**
+** Returns:
+** MI_SUCCESS
+*/
+
+int
+smfi_settimeout(otimeout)
+ int otimeout;
+{
+ timeout = otimeout;
+ return MI_SUCCESS;
+}
+
+/*
+** SMFI_SETCONN -- set connection information (socket description)
+**
+** Parameters:
+** oconn -- new connection information.
+**
+** Returns:
+** MI_SUCCESS/MI_FAILURE
+*/
+
+int
+smfi_setconn(oconn)
+ char *oconn;
+{
+ size_t l;
+
+ if (oconn == NULL || *oconn == '\0')
+ return MI_FAILURE;
+ l = strlen(oconn) + 1;
+ if ((conn = (char *) malloc(l)) == NULL)
+ return MI_FAILURE;
+ if (sm_strlcpy(conn, oconn, l) >= l)
+ return MI_FAILURE;
+ return MI_SUCCESS;
+}
+
+/*
+** SMFI_SETBACKLOG -- set backlog
+**
+** Parameters:
+** obacklog -- new backlog.
+**
+** Returns:
+** MI_SUCCESS/MI_FAILURE
+*/
+
+int
+smfi_setbacklog(obacklog)
+ int obacklog;
+{
+ if (obacklog <= 0)
+ return MI_FAILURE;
+ backlog = obacklog;
+ return MI_SUCCESS;
+}
+
+
+/*
+** SMFI_MAIN -- setup milter connnection and start listener.
+**
+** Parameters:
+** none.
+**
+** Returns:
+** MI_SUCCESS/MI_FAILURE
+*/
+
+int
+smfi_main()
+{
+ int r;
+
+ (void) signal(SIGPIPE, SIG_IGN);
+ if (conn == NULL)
+ {
+ smi_log(SMI_LOG_FATAL, "%s: missing connection information",
+ smfi->xxfi_name);
+ return MI_FAILURE;
+ }
+
+ (void) atexit(mi_clean_signals);
+ if (mi_control_startup(smfi->xxfi_name) != MI_SUCCESS)
+ {
+ smi_log(SMI_LOG_FATAL,
+ "%s: Couldn't start signal thread",
+ smfi->xxfi_name);
+ return MI_FAILURE;
+ }
+ r = MI_MONITOR_INIT();
+
+ /* Startup the listener */
+ if (mi_listener(conn, dbg, smfi, timeout, backlog) != MI_SUCCESS)
+ r = MI_FAILURE;
+
+ return r;
+}
+