/*
* Copyright (c) 2004, 2005 Sendmail, Inc. and its suppliers.
* All rights reserved.
*
* By using this file, you agree to the terms and conditions set
* forth in the LICENSE file which can be found at the top level of
* the sendmail distribution.
*/
#include "sm/generic.h"
SM_RCSID("@(#)$Id: pmilter_api.c,v 1.13 2006/10/05 04:27:37 ca Exp $")
#include "sm/error.h"
#include "sm/assert.h"
#include "sm/types.h"
#include "sm/fcntl.h"
#include "sm/io.h"
#include "sm/ctype.h"
#include "sm/reccom.h"
#include "sm/mta.h"
#define PMILTER_DEBUG_DEFINE 1
#include "pmilter.h"
#include "sm/pmilter.h"
#include "sm/pmfapi.h"
#include "util.h"
#if MTA_USE_PMILTER
/*
** SM_PMFI_VERSION -- return version of libpmilter
**
** Parameters:
** pmg_ctx -- pmilter (library) context
** major -- (pointer to) major version number of libpmilter
** minor -- (pointer to) minor version number of libpmilter
** patchlevel -- (pointer to) patchlevel of libpmilter
**
** Returns:
** usual sm_error code
*/
sm_ret_T
sm_pmfi_version(pmg_ctx_P pmg_ctx, uint32_t *major, uint32_t *minor, uint32_t *patchlevel)
{
SM_REQUIRE(major != NULL);
SM_REQUIRE(minor != NULL);
SM_REQUIRE(patchlevel != NULL);
*major = LPMILTER_VERSION_MAJOR;
*minor = LPMILTER_VERSION_MINOR;
*patchlevel = LPMILTER_VERSION_PL;
return SM_SUCCESS;
}
/*
** SM_PMFI_SETCONN -- set pathname of socket
**
** Parameters:
** pmg_ctx -- pmilter (library) context
** path -- pathname of socket to use
**
** Returns:
** usual sm_error code
*/
sm_ret_T
sm_pmfi_setconn(pmg_ctx_P pmg_ctx, const char *path)
{
SM_IS_PMG_CTX(pmg_ctx);
SM_REQUIRE(path != NULL);
/* memory leak if called multiple times. */
pmg_ctx->pmg_sockname = strdup(path);
if (pmg_ctx->pmg_sockname == NULL)
return sm_err_temp(ENOMEM);
return SM_PMI_SUCCESS;
}
/*
** SM_PMFI_INIT -- initialize PMILTER library
**
** Parameters:
** ppmg_ctx -- (pointer to) pmilter (library) context (output)
**
** Returns:
** usual sm_error code
*/
sm_ret_T
sm_pmfi_init(pmg_ctx_P *ppmg_ctx)
{
sm_ret_T ret;
if (getuid() == 0 || geteuid() == 0)
{
sm_io_fprintf(smioerr,
"ERROR: do not run this as super-user!\n");
return sm_err_perm(EPERM);
}
/* basic initialization */
ret = sm_pmilt_init0(ppmg_ctx);
#if SM_HEAP_CHECK
SmHeapCheck = 1;
if (HEAP_CHECK)
sm_heap_report(smioerr, 3);
#endif
return ret;
}
/*
** SM_PMFI_START -- start PMILTER
**
** Parameters:
** pmg_ctx -- pmilter (library) context
** pmilter -- pmilter application context
**
** Returns:
** exit code
*/
sm_ret_T
sm_pmfi_start(pmg_ctx_P pmg_ctx, pmilter_P pmilter)
{
sm_ret_T ret;
SM_IS_PMG_CTX(pmg_ctx);
SM_REQUIRE(pmilter != NULL);
if (getuid() == 0 || geteuid() == 0)
{
sm_io_fprintf(smioerr,
"ERROR: do not run this as super-user!\n");
return EPERM;
}
pmg_ctx->pmg_pmilter = pmilter;
if (SM_PM_VRS_MAJOR(pmilter->pmfi_version) != LPMILTER_VERSION_MAJOR)
{
sm_io_fprintf(smioerr,
"ERROR: major version numbers do not match [lib=%d, pmilter=%d]\n"
, LPMILTER_VERSION_MAJOR
, SM_PM_VRS_MAJOR(pmilter->pmfi_version));
return EINVAL;
}
/* initialize system */
ret = sm_pmilt_init1(pmg_ctx);
if (sm_is_err(ret))
{
sm_io_fprintf(smioerr, "sev=ERROR, sm_pmilt_init=%x\n", ret);
goto error;
}
/* startup pmilt */
ret = sm_pmilt_start(pmg_ctx);
if (sm_is_err(ret))
{
sm_io_fprintf(smioerr, "sev=ERROR, sm_pmilt_start=%x\n", ret);
goto error;
}
pmg_ctx->pmg_state = PMILT_ST_RUN;
/* wait for events, schedule tasks */
ret = evthr_loop(pmg_ctx->pmg_ev_ctx);
pmg_ctx->pmg_state = PMILT_ST_STOPPING;
ret = sm_pmilt_stop(pmg_ctx);
pmg_ctx->pmg_state = PMILT_ST_STOPPED;
#if SM_HEAP_CHECK
if (HEAP_CHECK)
sm_heap_report(smioerr, 3);
#endif
return SM_PMI_SUCCESS;
error:
/* ignore shutdown errors... */
(void) sm_pmilt_stop(pmg_ctx);
/* select an appropriate error here... */
return sm_error_value(ret);
}
/*
** SM_PMFI_STOP -- stop PMILTER
**
** Parameters:
** pmg_ctx -- pmilter (library) context
**
** Returns:
** usual sm_error code
*/
sm_ret_T
sm_pmfi_stop(pmg_ctx_P pmg_ctx)
{
SM_IS_PMG_CTX(pmg_ctx);
return sm_pmilt_stop(pmg_ctx);
}
/*
** SM_PMFI_SETDBG -- set debug level
**
** Parameters:
** pmg_ctx -- pmilter (library) context
** debuglevel -- debug level
**
** Returns:
** usual sm_error code
*/
sm_ret_T
sm_pmfi_setdbg(pmg_ctx_P pmg_ctx, unsigned int debuglevel)
{
SM_IS_PMG_CTX(pmg_ctx);
#if PMILTER_DEBUG
pm_debug = debuglevel;
#endif
return SM_SUCCESS;
}
#endif /* MTA_USE_PMILTER */
syntax highlighted by Code2HTML, v. 0.9.1