main.c revision 303975
1272343Sngie/*
2272343Sngie *  Copyright (c) 1999-2003, 2006, 2007 Proofpoint, Inc. and its suppliers.
3272343Sngie *	All rights reserved.
4272343Sngie *
5272343Sngie * By using this file, you agree to the terms and conditions set
6272343Sngie * forth in the LICENSE file which can be found at the top level of
7272343Sngie * the sendmail distribution.
8272343Sngie *
9272343Sngie */
10272343Sngie
11272343Sngie#include <sm/gen.h>
12272343SngieSM_RCSID("@(#)$Id: main.c,v 8.85 2013-11-22 20:51:36 ca Exp $")
13272343Sngie
14272343Sngie#define _DEFINE	1
15272343Sngie#include "libmilter.h"
16272343Sngie#include <fcntl.h>
17272343Sngie#include <sys/stat.h>
18272343Sngie
19272343Sngie
20272343Sngiestatic smfiDesc_ptr smfi = NULL;
21272343Sngie
22272343Sngie/*
23272343Sngie**  SMFI_REGISTER -- register a filter description
24272343Sngie**
25272343Sngie**	Parameters:
26272343Sngie**		smfilter -- description of filter to register
27272343Sngie**
28272343Sngie**	Returns:
29272343Sngie**		MI_SUCCESS/MI_FAILURE
30272343Sngie*/
31272343Sngie
32272343Sngieint
33272343Sngiesmfi_register(smfilter)
34272343Sngie	smfiDesc_str smfilter;
35272343Sngie{
36272343Sngie	size_t len;
37272343Sngie
38272343Sngie	if (smfi == NULL)
39272343Sngie	{
40272343Sngie		smfi = (smfiDesc_ptr) malloc(sizeof *smfi);
41272343Sngie		if (smfi == NULL)
42272343Sngie			return MI_FAILURE;
43272343Sngie	}
44272343Sngie	(void) memcpy(smfi, &smfilter, sizeof *smfi);
45272343Sngie	if (smfilter.xxfi_name == NULL)
46272343Sngie		smfilter.xxfi_name = "Unknown";
47272343Sngie
48272343Sngie	len = strlen(smfilter.xxfi_name) + 1;
49272343Sngie	smfi->xxfi_name = (char *) malloc(len);
50272343Sngie	if (smfi->xxfi_name == NULL)
51272343Sngie		return MI_FAILURE;
52272343Sngie	(void) sm_strlcpy(smfi->xxfi_name, smfilter.xxfi_name, len);
53272343Sngie
54272343Sngie	/* compare milter version with hard coded version */
55272343Sngie	if ((SM_LM_VRS_MAJOR(smfi->xxfi_version) != SM_LM_VRS_MAJOR(SMFI_VERSION) ||
56272343Sngie	     SM_LM_VRS_MINOR(smfi->xxfi_version) != SM_LM_VRS_MINOR(SMFI_VERSION)) &&
57272343Sngie	    smfi->xxfi_version != 2 &&
58272343Sngie	    smfi->xxfi_version != 3 &&
59272343Sngie	    smfi->xxfi_version != 4)
60272343Sngie	{
61272343Sngie		/* hard failure for now! */
62272343Sngie		smi_log(SMI_LOG_ERR,
63272343Sngie			"%s: smfi_register: version mismatch application: %d != milter: %d",
64272343Sngie			smfi->xxfi_name, smfi->xxfi_version,
65272343Sngie			(int) SMFI_VERSION);
66272343Sngie
67272343Sngie		/* XXX how about smfi? */
68272343Sngie		free(smfi->xxfi_name);
69272343Sngie		return MI_FAILURE;
70272343Sngie	}
71272343Sngie
72272343Sngie	return MI_SUCCESS;
73272343Sngie}
74272343Sngie
75272343Sngie/*
76272343Sngie**  SMFI_STOP -- stop milter
77272343Sngie**
78272343Sngie**	Parameters:
79272343Sngie**		none.
80272343Sngie**
81272343Sngie**	Returns:
82272343Sngie**		success.
83272343Sngie*/
84272343Sngie
85272343Sngieint
86272343Sngiesmfi_stop()
87272343Sngie{
88272343Sngie	mi_stop_milters(MILTER_STOP);
89272343Sngie	return MI_SUCCESS;
90272343Sngie}
91272343Sngie
92272343Sngie/*
93272343Sngie**  Default values for some variables.
94272343Sngie**	Most of these can be changed with the functions below.
95272343Sngie*/
96272343Sngie
97272343Sngiestatic int dbg = 0;
98272343Sngiestatic char *conn = NULL;
99272343Sngiestatic int timeout = MI_TIMEOUT;
100272343Sngiestatic int backlog = MI_SOMAXCONN;
101272343Sngie
102272343Sngie/*
103272343Sngie**  SMFI_OPENSOCKET -- try the socket setup to make sure we'll be
104272343Sngie**		       able to start up
105272343Sngie**
106272343Sngie**	Parameters:
107272343Sngie**		rmsocket -- if true, instructs libmilter to attempt
108272343Sngie**			to remove the socket before creating it;
109272343Sngie**			only applies for "local:" or "unix:" sockets
110272343Sngie**
111272343Sngie**	Return:
112272343Sngie**		MI_SUCCESS/MI_FAILURE
113272343Sngie*/
114272343Sngie
115272343Sngieint
116272343Sngiesmfi_opensocket(rmsocket)
117272343Sngie	bool rmsocket;
118272343Sngie{
119272343Sngie	if (smfi == NULL || conn == NULL)
120272343Sngie		return MI_FAILURE;
121272343Sngie
122272343Sngie	return mi_opensocket(conn, backlog, dbg, rmsocket, smfi);
123272343Sngie}
124272343Sngie
125272343Sngie/*
126272343Sngie**  SMFI_SETDBG -- set debug level.
127272343Sngie**
128272343Sngie**	Parameters:
129272343Sngie**		odbg -- new debug level.
130272343Sngie**
131272343Sngie**	Returns:
132272343Sngie**		MI_SUCCESS
133272343Sngie*/
134272343Sngie
135272343Sngieint
136272343Sngiesmfi_setdbg(odbg)
137272343Sngie	int odbg;
138272343Sngie{
139272343Sngie	dbg = odbg;
140272343Sngie	return MI_SUCCESS;
141272343Sngie}
142272343Sngie
143272343Sngie/*
144272343Sngie**  SMFI_SETTIMEOUT -- set timeout (for read/write).
145272343Sngie**
146272343Sngie**	Parameters:
147272343Sngie**		otimeout -- new timeout.
148272343Sngie**
149272343Sngie**	Returns:
150272343Sngie**		MI_SUCCESS
151272343Sngie*/
152272343Sngie
153272343Sngieint
154272343Sngiesmfi_settimeout(otimeout)
155272343Sngie	int otimeout;
156272343Sngie{
157272343Sngie	timeout = otimeout;
158272343Sngie	return MI_SUCCESS;
159272343Sngie}
160272343Sngie
161272343Sngie/*
162272343Sngie**  SMFI_SETCONN -- set connection information (socket description)
163272343Sngie**
164272343Sngie**	Parameters:
165272343Sngie**		oconn -- new connection information.
166272343Sngie**
167272343Sngie**	Returns:
168272343Sngie**		MI_SUCCESS/MI_FAILURE
169272343Sngie*/
170272343Sngie
171272343Sngieint
172smfi_setconn(oconn)
173	char *oconn;
174{
175	size_t l;
176
177	if (oconn == NULL || *oconn == '\0')
178		return MI_FAILURE;
179	l = strlen(oconn) + 1;
180	if ((conn = (char *) malloc(l)) == NULL)
181		return MI_FAILURE;
182	if (sm_strlcpy(conn, oconn, l) >= l)
183		return MI_FAILURE;
184	return MI_SUCCESS;
185}
186
187/*
188**  SMFI_SETBACKLOG -- set backlog
189**
190**	Parameters:
191**		obacklog -- new backlog.
192**
193**	Returns:
194**		MI_SUCCESS/MI_FAILURE
195*/
196
197int
198smfi_setbacklog(obacklog)
199	int obacklog;
200{
201	if (obacklog <= 0)
202		return MI_FAILURE;
203	backlog = obacklog;
204	return MI_SUCCESS;
205}
206
207
208/*
209**  SMFI_MAIN -- setup milter connnection and start listener.
210**
211**	Parameters:
212**		none.
213**
214**	Returns:
215**		MI_SUCCESS/MI_FAILURE
216*/
217
218int
219smfi_main()
220{
221	int r;
222
223	(void) signal(SIGPIPE, SIG_IGN);
224	if (conn == NULL)
225	{
226		smi_log(SMI_LOG_FATAL, "%s: missing connection information",
227			smfi->xxfi_name);
228		return MI_FAILURE;
229	}
230
231	(void) atexit(mi_clean_signals);
232	if (mi_control_startup(smfi->xxfi_name) != MI_SUCCESS)
233	{
234		smi_log(SMI_LOG_FATAL,
235			"%s: Couldn't start signal thread",
236			smfi->xxfi_name);
237		return MI_FAILURE;
238	}
239	r = MI_MONITOR_INIT();
240
241	/* Startup the listener */
242	if (mi_listener(conn, dbg, smfi, timeout, backlog) != MI_SUCCESS)
243		r = MI_FAILURE;
244
245	return r;
246}
247
248