/* * Copyright (c) 2002-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: rcbopen2.c,v 1.8 2005/06/02 19:00:36 ca Exp $") #include "sm/assert.h" #include "sm/magic.h" #include "sm/memops.h" #include "sm/rpool.h" #include "sm/str-int.h" #include "sm/rcb.h" #include "sm/str2rcb.h" #include "sm/reccom.h" /* ** SM_RCB_OPEN_RCVN -- Open rcb for receiving data from file. ** ** Parameters: ** rcb -- sm_rcb_P object. ** ** Returns: ** SM_SUCCESS */ sm_ret_T sm_rcb_open_rcvn(sm_rcb_P rcb) { SM_IS_RCB(rcb); SM_REQUIRE(rcb->sm_rcb_base != NULL); rcb->sm_rcb_len = 0; rcb->sm_rcb_rw = -1; #if SM_RCB_CHECK rcb->sm_rcb_state = SM_RCB_RCV; #endif return SM_SUCCESS; } /* ** SM_RCB_OPEN_DECN -- Open rcb for decoding data. ** ** Parameters: ** rcb -- sm_rcb_P object. ** ** Returns: ** SM_SUCCESS */ sm_ret_T sm_rcb_open_decn(sm_rcb_P rcb) { SM_IS_RCB(rcb); SM_REQUIRE(rcb->sm_rcb_base != NULL); rcb->sm_rcb_rw = 0; #if SM_RCB_CHECK rcb->sm_rcb_state = SM_RCB_DEC; #endif return SM_SUCCESS; } /* ** SM_RCB_OPEN_ENCN -- Open rcb for encoding data into it. ** ** Parameters: ** rcb -- sm_rcb_P object. ** n -- required size. ** ** Returns: ** SM_SUCCESS */ sm_ret_T sm_rcb_open_encn(sm_rcb_P rcb, int n) { SM_IS_RCB(rcb); SM_REQUIRE(rcb->sm_rcb_base != NULL); rcb->sm_rcb_len = 0; if (n > 0 && (uint)n > rcb->sm_rcb_size) { uint u; u = (uint)n; SM_STR_INCREASE_R(rcb, u); } rcb->sm_rcb_rw = n; #if SM_RCB_CHECK rcb->sm_rcb_state = SM_RCB_ENC; #endif return SM_SUCCESS; } /* ** SM_RCB_OPEN_SNDN -- Open rcb for sending data from it. ** ** Parameters: ** rcb -- sm_rcb_P object. ** ** Returns: ** SM_SUCCESS */ sm_ret_T sm_rcb_open_sndn(sm_rcb_P rcb) { SM_IS_RCB(rcb); SM_REQUIRE(rcb->sm_rcb_base != NULL); rcb->sm_rcb_rw = 0; #if SM_RCB_CHECK rcb->sm_rcb_state = SM_RCB_SND; #endif return SM_SUCCESS; } /* ** SM_RCB_CLOSE_RCVN -- Close rcb after receiving data from file. ** ** Parameters: ** rcb -- sm_rcb_P object. ** ** Returns: ** SM_SUCCESS */ sm_ret_T sm_rcb_close_rcvn(sm_rcb_P rcb) { SM_IS_RCB(rcb); SM_REQUIRE(rcb->sm_rcb_base != NULL); rcb->sm_rcb_rw = 0; #if SM_RCB_CHECK rcb->sm_rcb_state = SM_RCB_NONE; #endif return SM_SUCCESS; } /* ** SM_RCB_CLOSE_DECN -- Close rcb after decoding data. ** ** Parameters: ** rcb -- sm_rcb_P object. ** ** Returns: ** SM_SUCCESS */ sm_ret_T sm_rcb_close_decn(sm_rcb_P rcb) { SM_IS_RCB(rcb); SM_REQUIRE(rcb->sm_rcb_base != NULL); rcb->sm_rcb_rw = 0; #if SM_RCB_CHECK rcb->sm_rcb_state = SM_RCB_NONE; #endif return SM_SUCCESS; } /* ** SM_RCB_CLOSE_ENCN -- Close rcb after encoding data into it. ** ** Parameters: ** rcb -- sm_rcb_P object. ** ** Returns: ** usual sm_error code; EINVAL, etc */ sm_ret_T sm_rcb_close_encn(sm_rcb_P rcb) { uint32_t len; #if SM_RCB_END_RCB sm_ret_T ret; #endif SM_IS_RCB(rcb); SM_REQUIRE(rcb->sm_rcb_base != NULL); #if SM_RCB_CHECK /* reset state even if an error occurs? */ rcb->sm_rcb_state = SM_RCB_NONE; #endif if (rcb->sm_rcb_len <= sizeof(int)) return sm_error_perm(SM_EM_RECCOM, EINVAL); #if SM_RCB_END_RCB ret = sm_rcb_put3uint32(rcb, 4, RT_END_OF_RCB, rcb->sm_rcb_len + 12); if (sm_is_err(ret)) return ret; #endif len = (uint32_t) (rcb->sm_rcb_len); sm_uint32_2buf(len, rcb->sm_rcb_base); return SM_SUCCESS; } /* ** SM_RCB_CLOSE_SNDN -- Close rcb after sending data from it. ** ** Parameters: ** rcb -- sm_rcb_P object. ** ** Returns: ** SM_SUCCESS */ sm_ret_T sm_rcb_close_sndn(sm_rcb_P rcb) { SM_IS_RCB(rcb); SM_REQUIRE(rcb->sm_rcb_base != NULL); rcb->sm_rcb_rw = 0; #if SM_RCB_CHECK rcb->sm_rcb_state = SM_RCB_NONE; #endif return SM_SUCCESS; } /* ** SM_RCB_CLOSE_N -- Close rcb (unconditionally). ** ** Parameters: ** rcb -- sm_rcb_P object. ** ** Returns: ** SM_SUCCESS */ sm_ret_T sm_rcb_close_n(sm_rcb_P rcb) { if (rcb == NULL) return SM_SUCCESS; SM_IS_RCB(rcb); rcb->sm_rcb_rw = 0; #if SM_RCB_CHECK rcb->sm_rcb_state = SM_RCB_NONE; #endif return SM_SUCCESS; }