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