/* * Copyright (c) 2000-2002, 2004 Sendmail, Inc. and its suppliers. * All rights reserved. * Copyright (c) 1990, 1993 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by * Chris Torek. * * 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: vsnprintf.c,v 1.9 2004/12/29 23:47:35 ca Exp $") #include "sm/varargs.h" #include "sm/limits.h" #include "sm/io.h" #include "sm/assert.h" #include "io-int.h" /* ** SM_VSNPRINTF -- format data for "output" into a string ** ** Assigned 'str' to a "fake" file pointer. This allows common ** o/p formatting function sm_vprintf() to be used. ** ** Parameters: ** str -- location for output ** n -- maximum size for o/p ** fmt -- format directives ** ap -- data unit vectors for use by 'fmt' ** ** Results: ** result from sm_io_vfprintf() ** ** Side Effects: ** Limits the size ('n') to INT_MAX. */ int sm_vsnprintf(char *str, size_t n, const char *fmt, va_list ap) { int ret; char dummy; sm_file_T fake; /* While snprintf(3) specifies size_t stdio uses an int internally */ if (n > INT_MAX) n = INT_MAX; /* Stdio internals do not deal correctly with zero length buffer */ if (n == 0) { str = &dummy; n = 1; } fake.sm_magic = SM_FILE_MAGIC; fake.f_timeout = SM_TIME_FOREVER; f_fd(fake) = -1; f_flags(fake) = SMWR | SMSTR; f_bfbase(fake) = f_p(fake) = (uchar *)str; f_bfsize(fake) = f_w(fake) = n - 1; f_read(fake) = NULL; f_write(fake) = NULL; f_close(fake) = NULL; f_open(fake) = NULL; f_seek(fake) = NULL; f_setinfo(fake) = f_getinfo(fake) = NULL; ret = sm_io_vfprintf(&fake, fmt, ap); *f_p(fake) = 0; return ret; }