/*
* 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: strscatn.c,v 1.19 2007/01/30 04:59:05 ca Exp $")
#include "sm/assert.h"
#include "sm/magic.h"
#include "sm/error.h"
#include "sm/memops.h"
#include "sm/rpool.h"
#include "sm/varargs.h"
#include "sm/limits.h"
#include "sm/strrcb.h"
#include "sm/str-int.h"
#include "sm/str2rcb.h"
/*
** SM_STR_SCATN -- Append a copy of a sized char * to the end of a
** sm_str_P.
**
** The bytes you are appending do not have to be '\0' terminated.
** In fact, this will gladly copy '\0' characters if they are
** included in the range of len.
**
** Parameters:
** str -- sm_str_P object to append onto.
** append -- Array of bytes to append.
** len -- Number of bytes to append.
**
** Returns:
** usual sm_error code; ENOMEM, SM_E_FULL, SM_E_OVFLW_SC
*/
sm_ret_T
#if SM_STR_READ
sm_rcb_putn(sm_str_P str, const uchar *append, uint len)
#else
sm_str_scatn(sm_str_P str, const char *append, uint len)
#endif
{
uint new_alloc;
#if SM_STR_CHECK && SM_STR_READ
uint olen;
#endif
SM_IS_BUF(str);
SM_REQUIRE(append != NULL);
SM_REQUIRE(len < INT_MAX - 4);
#if SM_STR_READ
# if SM_RCB_CHECK
SM_REQUIRE(str->sm_rcb_state == SM_RCB_ENC);
# endif
# if SM_STR_CHECK
olen = len;
# endif
len = SM_ALIGN4(len);
/* do we really want to do this? */
if (str->sm_rcb_rw >= 0 && (int)len > str->sm_rcb_rw)
return sm_error_perm(SM_EM_STR_RCB, SM_E_FULL);
#endif /* SM_STR_READ */
new_alloc = str->sm_str_len + len;
/* overflow? */
if (len > 0 && new_alloc <= str->sm_str_len)
return sm_error_perm(SM_EM_STR_RCB, SM_E_OVFLW_SC);
if (new_alloc > str->sm_str_size)
SM_STR_INCREASE_R(str, new_alloc);
#if SM_STR_CHECK && SM_STR_READ
sm_memcpy(str->sm_str_base + str->sm_str_len, append, olen);
/* clear the "aligned" bytes to avoid complaints from purify */
if (len > olen)
sm_memzero(str->sm_str_base + str->sm_str_len + olen, len - olen);
#else /* SM_STR_CHECK && SM_STR_READ */
sm_memcpy(str->sm_str_base + str->sm_str_len, append, len);
#endif /* SM_STR_CHECK && SM_STR_READ */
str->sm_str_len += len;
#if SM_STR_READ
if (str->sm_rcb_rw >= 0)
str->sm_rcb_rw -= len;
#endif /* SM_STR_READ */
return SM_SUCCESS;
}
syntax highlighted by Code2HTML, v. 0.9.1