Import sendmail 8.14.2
[dragonfly.git] / contrib / sendmail-8.14 / libmilter / main.c
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