/*
* Copyright (c) 2005, 2006 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: cstrscpyv0.c,v 1.6 2006/10/05 04:27:37 ca Exp $")
#include "sm/assert.h"
#include "sm/magic.h"
#include "sm/memops.h"
#include "sm/varargs.h"
#include "sm/limits.h"
#include "sm/cstr.h"
/*
** SM_CSTR_SCPYVN0 -- Create a cstring and copy n bytes from src into it;
** repeat that process until a NULL is encountered.
** This is used to create a '\0' terminated string without counting
** the trailing '\0'.
**
** Parameters:
** src -- Byte array to copy from
** n -- Number of bytes to copy from src
** ... repeated until src == NULL
**
** Returns:
** New cstr object
** NULL on error (ENOMEM)
*/
sm_cstr_P
sm_cstr_scpyvn0(const uchar *src, uint n, ...)
{
sm_cstr_P cstr;
const uchar *s0;
uint total_len, n0, offset;
va_list ap;
#if MTA_USE_PTHREADS
int r;
#endif
SM_REQUIRE(src != NULL);
if (n >= CSTR_MAX_SIZE)
return NULL;
total_len = 0;
va_start(ap, n);
s0 = src;
n0 = n;
while (s0 != NULL)
{
total_len += n0;
if (n0 >= CSTR_MAX_SIZE)
return NULL;
if (total_len >= CSTR_MAX_SIZE)
return NULL;
s0 = va_arg(ap, uchar *);
if (s0 != NULL)
n0 = va_arg(ap, uint);
}
va_end(ap);
cstr = sm_malloc(sizeof(*cstr));
if (cstr == NULL)
return NULL;
cstr->sm_cstr_base = sm_malloc(total_len + 1);
if (cstr->sm_cstr_base == NULL)
{
sm_free_size(cstr, sizeof(*cstr));
return NULL;
}
#if MTA_USE_PTHREADS
r = pthread_mutex_init(&cstr->sm_cstr_mutex, SM_PTHREAD_MUTEXATTR);
if (r != 0)
{
sm_free_size(cstr->sm_cstr_base, n + 1);
sm_free_size(cstr, sizeof(*cstr));
return NULL;
}
#endif /* MTA_USE_PTHREADS */
cstr->sm_cstr_len = total_len;
cstr->sm_cstr_refcnt = 1;
va_start(ap, n);
s0 = src;
n0 = n;
offset = 0;
while (s0 != NULL)
{
SM_ASSERT(offset < total_len);
SM_ASSERT(offset + n0 <= total_len);
if (n0 > 0)
{
sm_memcpy(cstr->sm_cstr_base + offset, s0, n0);
offset += n0;
}
s0 = va_arg(ap, uchar *);
if (s0 != NULL)
n0 = va_arg(ap, uint);
}
va_end(ap);
cstr->sm_cstr_base[total_len] = '\0';
cstr->sm_magic = SM_CSTR_MAGIC;
return cstr;
}
syntax highlighted by Code2HTML, v. 0.9.1