/*
 * Copyright (c) 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_replacemsg.c,v 1.5 2006/10/05 04:27:38 ca Exp $")
#include "sm/error.h"
#include "sm/assert.h"
#include "pmilter.h"
#include "sm/pmfdef.h"
#include "sm/pmfapi.h"
#include "sm/pmilter.h"
#include "sm/reccom.h"

#if MTA_USE_PMILTER

/*
**  SM_PMILT_REPLACEMSG -- Invoke pmilter callback to get body chunks
**		to replace message
**
**	Parameters:
**		pmse_ctx -- pmilter/SMTP server session context
**
**	Returns:
**		usual sm_error code
*/

sm_ret_T
sm_pmilt_msg_rplc(void *ctx)
{
	sm_ret_T ret, rcode;
	size_t len;
	const unsigned char *msg;
	pmse_ctx_P pmse_ctx;
	pmss_ctx_P pmss_ctx;
	sm_rcbe_P rcbe;
	sm_evthr_task_P tsk;
	pmilter_P pmilter;

	SM_REQUIRE(ctx != NULL);
	pmse_ctx = (pmse_ctx_P) ctx;
	SM_IS_PMSE_CTX(pmse_ctx);
	pmss_ctx = pmse_ctx->pmse_pmss_ctx;
	SM_IS_PMSS_CTX(pmss_ctx);
	tsk = pmss_ctx->pmss_com.rcbcom_tsk;
	pmilter = pmse_ctx->pmse_pmg_ctx->pmg_pmilter;
	SM_REQUIRE(pmilter != NULL);
	SM_REQUIRE(pmilter->pmfi_msg_rplc != NULL);
	rcbe = NULL;
	pmse_ctx->pmse_state = PMSE_ST_MSG_RPLC;
	len = 0;
	sm_str_clr(pmse_ctx->pmse_reply_text);

	rcode = (*pmilter->pmfi_msg_rplc)(pmse_ctx, &msg, &len);
	if (len >= PMILTER_CHUNK_SIZE)
	{
		ret = sm_error_perm(SM_EM_PMILTER, SM_E_OVFLW_NS);
		goto error;
	}
	if (SMTP_R_CONT == rcode && (NULL == msg || 0 == len))
	{
		ret = sm_error_perm(SM_EM_PMILTER, EINVAL);
		goto error;
	}

	ret = sm_rcbe_new_enc(&rcbe, -1, 0);
	if (sm_is_err(ret))
		goto error;

	if (SMTP_R_CONT == rcode)
	{
		rcbe->rcbe_wr_cb = sm_pmilt_msg_rplc;
		rcbe->rcbe_ctx = pmse_ctx;
	}

	ret = sm_rcb_putv(&rcbe->rcbe_rcb, RCB_PUTV_FIRST,
		SM_RCBV_INT, RT_PROT_VER, PROT_VER_RT,
		SM_RCBV_INT, RT_M2S_ID, pmss_ctx->pmss_id,
		SM_RCBV_BUF, RT_M2S_SEID, pmse_ctx->pmse_se_id, SMTP_STID_SIZE,
		SM_RCBV_INT, RT_M2S_RCODE, rcode,
		SM_RCBV_END);

	if (sm_is_success(ret) && msg != NULL && len > 0)
	{
		ret = sm_rcb_putv(&rcbe->rcbe_rcb, RCB_PUTV_NONE,
			SM_RCBV_BUF, RT_M2S_MSG_PART, msg, len,
			SM_RCBV_END);
	}
	if (sm_is_err(ret))
		goto error;
	ret = sm_rcbcom_endrep(&pmss_ctx->pmss_com, tsk, false, &rcbe);
	if (sm_is_err(ret))
		pmse_ctx->pmse_cmd_status = ret;

	return ret;

  error:
	pmse_ctx->pmse_cmd_status = ret;
	if (pmilter->pmfi_msg_rplc_stat != NULL)
		(void) (*pmilter->pmfi_msg_rplc_stat)(pmse_ctx, ret);
	return ret;
}
#endif /* MTA_USE_PMILTER */


syntax highlighted by Code2HTML, v. 0.9.1