/* * 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_hdr.c,v 1.5 2006/10/05 04:27:38 ca Exp $") #include "sm/error.h" #include "sm/assert.h" #include "sm/types.h" #include "sm/sm_extracthdr.h" #include "sm/io.h" #include "sm/smreplycodes.h" #include "pmilter.h" #include "sm/pmilter.h" #include "sm/pmfapi.h" #if MTA_USE_PMILTER /* How to use this? as library: doesn't work so well as it needs to access some context. as macro? (similar to bsd-tree.h?) */ /* context per SMTP session */ typedef struct pmexse_ctx_S pmexse_ctx_T, *pmexse_ctx_P; struct pmexse_ctx_S { uint32_t pmexse_flags; sm_xhdr_ctx_P pmexse_xhdr_ctx; }; #define PMSE_FL_NONE 0x0000 #define PMSE_FL_MSG_INIT 0x0001 #define PMSE_FL_MSG_HDR 0x0002 #define PMSE_FL_MSG_EOH 0x0004 #define PMSE_FL_MSG_BODY 0x0008 #define PMSE_SET_FLAG(pmexse_ctx, fl) (pmexse_ctx)->pmexse_flags |= (fl) #define PMSE_CLR_FLAG(pmexse_ctx, fl) (pmexse_ctx)->pmexse_flags &= ~(fl) #define PMSE_IS_FLAG(pmexse_ctx, fl) (((pmexse_ctx)->pmexse_flags & (fl)) != 0) static sfsistat_T pm_hdr(pmexse_ctx_P pmexse_ctx, unsigned char *buf, size_t len) { sm_ret_T ret; bool newchunk; sm_xhdr_ctx_P sm_xhdr_ctx; newchunk = true; sm_xhdr_ctx = pmexse_ctx->pmexse_xhdr_ctx; do { ret = sm_xhdr(buf, len, newchunk, sm_xhdr_ctx); newchunk = false; if (ret == SM_XHDR_GOT1 || ret == SM_XHDR_GOTA || ret == SM_XHDR_GOTL) { /* invoke header function */ sm_io_fprintf(smioout, "name: %#S\n", sm_xhdr_ctx->sm_xhdr_name); sm_io_fprintf(smioout, "value: %#S\n", sm_xhdr_ctx->sm_xhdr_value); } } while (!sm_is_err(ret) && ret == SM_XHDR_GOTA); if (ret == SM_XHDR_EOHDR || ret == SM_XHDR_GOTL) { PMSE_CLR_FLAG(pmexse_ctx, PMSE_FL_MSG_HDR); PMSE_SET_FLAG(pmexse_ctx, PMSE_FL_MSG_EOH); /* invoke end-of-header function */ PMSE_CLR_FLAG(pmexse_ctx, PMSE_FL_MSG_EOH); PMSE_SET_FLAG(pmexse_ctx, PMSE_FL_MSG_BODY); } return ret; } extern sfsistat_T pm_body(pmse_ctx_P _pmse_ctx, unsigned char *_buf, size_t _len); sfsistat_T pm_msg(pmse_ctx_P pmse_ctx, unsigned char *buf, size_t len) { sm_ret_T ret; pmexse_ctx_P pmexse_ctx; pmexse_ctx = (pmexse_ctx_P) sm_pmfi_get_ctx_se(pmse_ctx); if (pmexse_ctx == NULL) return SMTP_R_TEMP; ret = SMTP_R_CONT; if (!PMSE_IS_FLAG(pmexse_ctx, PMSE_FL_MSG_INIT)) { ret = sm_xhdr_init(SM_XHDR_FL_SKIP_FIRST_BLANK, &pmexse_ctx->pmexse_xhdr_ctx); if (sm_is_err(ret)) return SMTP_R_TEMP; PMSE_SET_FLAG(pmexse_ctx, PMSE_FL_MSG_INIT|PMSE_FL_MSG_HDR); } if (PMSE_IS_FLAG(pmexse_ctx, PMSE_FL_MSG_HDR)) { ret = pm_hdr(pmexse_ctx, buf, len); if (PMSE_IS_FLAG(pmexse_ctx, PMSE_FL_MSG_BODY)) { sm_xhdr_ctx_P sm_xhdr_ctx; sm_xhdr_ctx = pmexse_ctx->pmexse_xhdr_ctx; if (sm_xhdr_ctx->sm_xhdr_chunk_off < len) { len -= sm_xhdr_ctx->sm_xhdr_chunk_off; buf += sm_xhdr_ctx->sm_xhdr_chunk_off; ret = sm_xhdr_end(sm_xhdr_ctx); } else len = 0; } } if (PMSE_IS_FLAG(pmexse_ctx, PMSE_FL_MSG_BODY) && len > 0) ret = pm_body(pmse_ctx, buf, len); return ret; } #endif /* MTA_USE_PMILTER */