/* * Copyright (c) 2000-2002, 2004, 2005 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: snprintf.c,v 1.13 2005/01/27 00:29:17 ca Exp $") #include "sm/varargs.h" #include "sm/io.h" #include "sm/assert.h" #include "sm/limits.h" #include "io-int.h" /* ** SM_SNPRINTF -- format a string to a memory location of restricted size ** ** Parameters: ** str -- memory location to place formatted string ** n -- size of buffer pointed to by str, capped to ** a maximum of INT_MAX ** fmt -- the formatting directives ** ... -- the data to satisfy the formatting ** ** Returns: ** Failure: -1 ** Success: number of bytes that would have been written ** to str, not including the trailing '\0', ** up to a maximum of INT_MAX, as if there was ** no buffer size limitation. If the result >= n ** then the output was truncated. ** ** Side Effects: ** If n > 0, then between 0 and n-1 bytes of formatted output ** are written into 'str', followed by a '\0'. */ int sm_snprintf(char *str, size_t n, char const *fmt, ...) { int ret; va_list ap; sm_file_T fake; /* While snprintf(3) specifies size_t stdio uses an int internally */ if (n > INT_MAX) n = INT_MAX; va_start(ap, fmt); /* todo: put this into a static?? */ fake.sm_magic = SM_FILE_MAGIC; f_fd(fake) = -1; f_flags(fake) = SMWR|SMSTR; fake.f_cookie = &fake; f_bfbase(fake) = f_p(fake) = (uchar *)str; f_bfsize(fake) = f_w(fake) = n ? n - 1 : 0; fake.f_timeout = SM_TIME_FOREVER; 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); if (n > 0) *f_p(fake) = '\0'; va_end(ap); return ret; }