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