main.c revision 168515
1/*
2 *  Copyright (c) 1999-2003, 2006 Sendmail, Inc. and its suppliers.
3 *	All rights reserved.
4 *
5 * By using this file, you agree to the terms and conditions set
6 * forth in the LICENSE file which can be found at the top level of
7 * the sendmail distribution.
8 *
9 */
10
11#include <sm/gen.h>
12SM_RCSID("@(#)$Id: main.c,v 8.81 2006/11/02 18:31:43 ca Exp $")
13
14#define _DEFINE	1
15#include "libmilter.h"
16#include <fcntl.h>
17#include <sys/stat.h>
18
19
20static smfiDesc_ptr smfi = NULL;
21
22/*
23**  SMFI_REGISTER -- register a filter description
24**
25**	Parameters:
26**		smfilter -- description of filter to register
27**
28**	Returns:
29**		MI_SUCCESS/MI_FAILURE
30*/
31
32int
33smfi_register(smfilter)
34	smfiDesc_str smfilter;
35{
36	size_t len;
37
38	if (smfi == NULL)
39	{
40		smfi = (smfiDesc_ptr) malloc(sizeof *smfi);
41		if (smfi == NULL)
42			return MI_FAILURE;
43	}
44	(void) memcpy(smfi, &smfilter, sizeof *smfi);
45	if (smfilter.xxfi_name == NULL)
46		smfilter.xxfi_name = "Unknown";
47
48	len = strlen(smfilter.xxfi_name) + 1;
49	smfi->xxfi_name = (char *) malloc(len);
50	if (smfi->xxfi_name == NULL)
51		return MI_FAILURE;
52	(void) sm_strlcpy(smfi->xxfi_name, smfilter.xxfi_name, len);
53
54	/* compare milter version with hard coded version */
55	if (smfi->xxfi_version != SMFI_VERSION)
56	{
57		/* hard failure for now! */
58		smi_log(SMI_LOG_ERR,
59			"%s: smfi_register: version mismatch application: %d != milter: %d",
60			smfi->xxfi_name, smfi->xxfi_version,
61			(int) SMFI_VERSION);
62
63		/* XXX how about smfi? */
64		free(smfi->xxfi_name);
65		return MI_FAILURE;
66	}
67
68	return MI_SUCCESS;
69}
70
71/*
72**  SMFI_STOP -- stop milter
73**
74**	Parameters:
75**		none.
76**
77**	Returns:
78**		success.
79*/
80
81int
82smfi_stop()
83{
84	mi_stop_milters(MILTER_STOP);
85	return MI_SUCCESS;
86}
87
88/*
89**  Default values for some variables.
90**	Most of these can be changed with the functions below.
91*/
92
93static int dbg = 0;
94static char *conn = NULL;
95static int timeout = MI_TIMEOUT;
96static int backlog = MI_SOMAXCONN;
97
98/*
99**  SMFI_OPENSOCKET -- try the socket setup to make sure we'll be
100**		       able to start up
101**
102**	Parameters:
103**		rmsocket -- if true, instructs libmilter to attempt
104**			to remove the socket before creating it;
105**			only applies for "local:" or "unix:" sockets
106**
107**	Return:
108**		MI_SUCCESS/MI_FAILURE
109*/
110
111int
112smfi_opensocket(rmsocket)
113	bool rmsocket;
114{
115	if (smfi == NULL || conn == NULL)
116		return MI_FAILURE;
117
118	return mi_opensocket(conn, backlog, dbg, rmsocket, smfi);
119}
120
121/*
122**  SMFI_SETDBG -- set debug level.
123**
124**	Parameters:
125**		odbg -- new debug level.
126**
127**	Returns:
128**		MI_SUCCESS
129*/
130
131int
132smfi_setdbg(odbg)
133	int odbg;
134{
135	dbg = odbg;
136	return MI_SUCCESS;
137}
138
139/*
140**  SMFI_SETTIMEOUT -- set timeout (for read/write).
141**
142**	Parameters:
143**		otimeout -- new timeout.
144**
145**	Returns:
146**		MI_SUCCESS
147*/
148
149int
150smfi_settimeout(otimeout)
151	int otimeout;
152{
153	timeout = otimeout;
154	return MI_SUCCESS;
155}
156
157/*
158**  SMFI_SETCONN -- set connection information (socket description)
159**
160**	Parameters:
161**		oconn -- new connection information.
162**
163**	Returns:
164**		MI_SUCCESS/MI_FAILURE
165*/
166
167int
168smfi_setconn(oconn)
169	char *oconn;
170{
171	size_t l;
172
173	if (oconn == NULL || *oconn == '\0')
174		return MI_FAILURE;
175	l = strlen(oconn) + 1;
176	if ((conn = (char *) malloc(l)) == NULL)
177		return MI_FAILURE;
178	if (sm_strlcpy(conn, oconn, l) >= l)
179		return MI_FAILURE;
180	return MI_SUCCESS;
181}
182
183/*
184**  SMFI_SETBACKLOG -- set backlog
185**
186**	Parameters:
187**		obacklog -- new backlog.
188**
189**	Returns:
190**		MI_SUCCESS/MI_FAILURE
191*/
192
193int
194smfi_setbacklog(obacklog)
195	int obacklog;
196{
197	if (obacklog <= 0)
198		return MI_FAILURE;
199	backlog = obacklog;
200	return MI_SUCCESS;
201}
202
203
204/*
205**  SMFI_MAIN -- setup milter connnection and start listener.
206**
207**	Parameters:
208**		none.
209**
210**	Returns:
211**		MI_SUCCESS/MI_FAILURE
212*/
213
214int
215smfi_main()
216{
217	int r;
218
219	(void) signal(SIGPIPE, SIG_IGN);
220	if (conn == NULL)
221	{
222		smi_log(SMI_LOG_FATAL, "%s: missing connection information",
223			smfi->xxfi_name);
224		return MI_FAILURE;
225	}
226
227	(void) atexit(mi_clean_signals);
228	if (mi_control_startup(smfi->xxfi_name) != MI_SUCCESS)
229	{
230		smi_log(SMI_LOG_FATAL,
231			"%s: Couldn't start signal thread",
232			smfi->xxfi_name);
233		return MI_FAILURE;
234	}
235	r = MI_MONITOR_INIT();
236
237	/* Startup the listener */
238	if (mi_listener(conn, dbg, smfi, timeout, backlog) != MI_SUCCESS)
239		r = MI_FAILURE;
240
241	return r;
242}
243
244