1251876Speter/*
2251876Speter *  Copyright (c) 1999-2003, 2006, 2007 Proofpoint, Inc. and its suppliers.
3251876Speter *	All rights reserved.
4251876Speter *
5251876Speter * By using this file, you agree to the terms and conditions set
6251876Speter * forth in the LICENSE file which can be found at the top level of
7251876Speter * the sendmail distribution.
8251876Speter *
9251876Speter */
10251876Speter
11251876Speter#include <sm/gen.h>
12251876SpeterSM_RCSID("@(#)$Id: main.c,v 8.85 2013-11-22 20:51:36 ca Exp $")
13251876Speter
14251876Speter#define _DEFINE	1
15251876Speter#include "libmilter.h"
16251876Speter#include <fcntl.h>
17251876Speter#include <sys/stat.h>
18251876Speter
19251876Speter
20251876Speterstatic smfiDesc_ptr smfi = NULL;
21251876Speter
22251876Speter/*
23251876Speter**  SMFI_REGISTER -- register a filter description
24251876Speter**
25251876Speter**	Parameters:
26251876Speter**		smfilter -- description of filter to register
27251876Speter**
28251876Speter**	Returns:
29251876Speter**		MI_SUCCESS/MI_FAILURE
30251876Speter*/
31251876Speter
32251876Speterint
33251876Spetersmfi_register(smfilter)
34251876Speter	smfiDesc_str smfilter;
35251876Speter{
36251876Speter	size_t len;
37251876Speter
38251876Speter	if (smfi == NULL)
39251876Speter	{
40251876Speter		smfi = (smfiDesc_ptr) malloc(sizeof *smfi);
41251876Speter		if (smfi == NULL)
42251876Speter			return MI_FAILURE;
43251876Speter	}
44251876Speter	(void) memcpy(smfi, &smfilter, sizeof *smfi);
45251876Speter	if (smfilter.xxfi_name == NULL)
46251876Speter		smfilter.xxfi_name = "Unknown";
47251876Speter
48251876Speter	len = strlen(smfilter.xxfi_name) + 1;
49251876Speter	smfi->xxfi_name = (char *) malloc(len);
50251876Speter	if (smfi->xxfi_name == NULL)
51251876Speter		return MI_FAILURE;
52251876Speter	(void) sm_strlcpy(smfi->xxfi_name, smfilter.xxfi_name, len);
53251876Speter
54251876Speter	/* compare milter version with hard coded version */
55251876Speter	if ((SM_LM_VRS_MAJOR(smfi->xxfi_version) != SM_LM_VRS_MAJOR(SMFI_VERSION) ||
56251876Speter	     SM_LM_VRS_MINOR(smfi->xxfi_version) != SM_LM_VRS_MINOR(SMFI_VERSION)) &&
57251876Speter	    smfi->xxfi_version != 2 &&
58251876Speter	    smfi->xxfi_version != 3 &&
59251876Speter	    smfi->xxfi_version != 4)
60251876Speter	{
61251876Speter		/* hard failure for now! */
62251876Speter		smi_log(SMI_LOG_ERR,
63251876Speter			"%s: smfi_register: version mismatch application: %d != milter: %d",
64251876Speter			smfi->xxfi_name, smfi->xxfi_version,
65251876Speter			(int) SMFI_VERSION);
66251876Speter
67251876Speter		/* XXX how about smfi? */
68251876Speter		free(smfi->xxfi_name);
69251876Speter		return MI_FAILURE;
70251876Speter	}
71251876Speter
72251876Speter	return MI_SUCCESS;
73251876Speter}
74251876Speter
75251876Speter/*
76251876Speter**  SMFI_STOP -- stop milter
77251876Speter**
78251876Speter**	Parameters:
79251876Speter**		none.
80251876Speter**
81251876Speter**	Returns:
82251876Speter**		success.
83251876Speter*/
84251876Speter
85251876Speterint
86251876Spetersmfi_stop()
87251876Speter{
88251876Speter	mi_stop_milters(MILTER_STOP);
89251876Speter	return MI_SUCCESS;
90251876Speter}
91251876Speter
92251876Speter/*
93251876Speter**  Default values for some variables.
94251876Speter**	Most of these can be changed with the functions below.
95251876Speter*/
96251876Speter
97251876Speterstatic int dbg = 0;
98251876Speterstatic char *conn = NULL;
99251876Speterstatic int timeout = MI_TIMEOUT;
100251876Speterstatic int backlog = MI_SOMAXCONN;
101251876Speter
102251876Speter/*
103251876Speter**  SMFI_OPENSOCKET -- try the socket setup to make sure we'll be
104251876Speter**		       able to start up
105251876Speter**
106251876Speter**	Parameters:
107251876Speter**		rmsocket -- if true, instructs libmilter to attempt
108251876Speter**			to remove the socket before creating it;
109251876Speter**			only applies for "local:" or "unix:" sockets
110251876Speter**
111251876Speter**	Return:
112251876Speter**		MI_SUCCESS/MI_FAILURE
113251876Speter*/
114251876Speter
115251876Speterint
116251876Spetersmfi_opensocket(rmsocket)
117251876Speter	bool rmsocket;
118251876Speter{
119251876Speter	if (smfi == NULL || conn == NULL)
120251876Speter		return MI_FAILURE;
121251876Speter
122251876Speter	return mi_opensocket(conn, backlog, dbg, rmsocket, smfi);
123251876Speter}
124251876Speter
125251876Speter/*
126251876Speter**  SMFI_SETDBG -- set debug level.
127251876Speter**
128251876Speter**	Parameters:
129251876Speter**		odbg -- new debug level.
130251876Speter**
131251876Speter**	Returns:
132251876Speter**		MI_SUCCESS
133251876Speter*/
134251876Speter
135251876Speterint
136251876Spetersmfi_setdbg(odbg)
137251876Speter	int odbg;
138251876Speter{
139251876Speter	dbg = odbg;
140251876Speter	return MI_SUCCESS;
141251876Speter}
142251876Speter
143251876Speter/*
144251876Speter**  SMFI_SETTIMEOUT -- set timeout (for read/write).
145251876Speter**
146251876Speter**	Parameters:
147251876Speter**		otimeout -- new timeout.
148251876Speter**
149251876Speter**	Returns:
150251876Speter**		MI_SUCCESS
151251876Speter*/
152251876Speter
153251876Speterint
154251876Spetersmfi_settimeout(otimeout)
155251876Speter	int otimeout;
156251876Speter{
157251876Speter	timeout = otimeout;
158251876Speter	return MI_SUCCESS;
159251876Speter}
160251876Speter
161251876Speter/*
162251876Speter**  SMFI_SETCONN -- set connection information (socket description)
163251876Speter**
164251876Speter**	Parameters:
165251876Speter**		oconn -- new connection information.
166251876Speter**
167251876Speter**	Returns:
168251876Speter**		MI_SUCCESS/MI_FAILURE
169251876Speter*/
170251876Speter
171251876Speterint
172251876Spetersmfi_setconn(oconn)
173251876Speter	char *oconn;
174251876Speter{
175251876Speter	size_t l;
176251876Speter
177251876Speter	if (oconn == NULL || *oconn == '\0')
178251876Speter		return MI_FAILURE;
179251876Speter	l = strlen(oconn) + 1;
180251876Speter	if ((conn = (char *) malloc(l)) == NULL)
181251876Speter		return MI_FAILURE;
182251876Speter	if (sm_strlcpy(conn, oconn, l) >= l)
183251876Speter		return MI_FAILURE;
184251876Speter	return MI_SUCCESS;
185251876Speter}
186251876Speter
187251876Speter/*
188251876Speter**  SMFI_SETBACKLOG -- set backlog
189251876Speter**
190251876Speter**	Parameters:
191251876Speter**		obacklog -- new backlog.
192251876Speter**
193251876Speter**	Returns:
194251876Speter**		MI_SUCCESS/MI_FAILURE
195251876Speter*/
196251876Speter
197251876Speterint
198251876Spetersmfi_setbacklog(obacklog)
199251876Speter	int obacklog;
200251876Speter{
201251876Speter	if (obacklog <= 0)
202251876Speter		return MI_FAILURE;
203251876Speter	backlog = obacklog;
204251876Speter	return MI_SUCCESS;
205251876Speter}
206251876Speter
207251876Speter
208251876Speter/*
209251876Speter**  SMFI_MAIN -- setup milter connnection and start listener.
210251876Speter**
211251876Speter**	Parameters:
212251876Speter**		none.
213251876Speter**
214251876Speter**	Returns:
215251876Speter**		MI_SUCCESS/MI_FAILURE
216251876Speter*/
217251876Speter
218251876Speterint
219251876Spetersmfi_main()
220251876Speter{
221251876Speter	int r;
222251876Speter
223251876Speter	(void) signal(SIGPIPE, SIG_IGN);
224251876Speter	if (conn == NULL)
225251876Speter	{
226251876Speter		smi_log(SMI_LOG_FATAL, "%s: missing connection information",
227251876Speter			smfi->xxfi_name);
228251876Speter		return MI_FAILURE;
229251876Speter	}
230251876Speter
231251876Speter	(void) atexit(mi_clean_signals);
232251876Speter	if (mi_control_startup(smfi->xxfi_name) != MI_SUCCESS)
233251876Speter	{
234251876Speter		smi_log(SMI_LOG_FATAL,
235251876Speter			"%s: Couldn't start signal thread",
236251876Speter			smfi->xxfi_name);
237251876Speter		return MI_FAILURE;
238251876Speter	}
239251876Speter	r = MI_MONITOR_INIT();
240251876Speter
241251876Speter	/* Startup the listener */
242251876Speter	if (mi_listener(conn, dbg, smfi, timeout, backlog) != MI_SUCCESS)
243251876Speter		r = MI_FAILURE;
244251876Speter
245251876Speter	return r;
246251876Speter}
247251876Speter
248251876Speter