1 /* 2 * Copyright (c) 2000-2001 Proofpoint, Inc. and its suppliers. 3 * All rights reserved. 4 * Copyright (c) 1990, 1993 5 * The Regents of the University of California. All rights reserved. 6 * 7 * This code is derived from software contributed to Berkeley by 8 * Chris Torek. 9 * 10 * By using this file, you agree to the terms and conditions set 11 * forth in the LICENSE file which can be found at the top level of 12 * the sendmail distribution. 13 */ 14 15 #include <sm/gen.h> 16 SM_RCSID("@(#)$Id: vsnprintf.c,v 1.24 2013-11-22 20:51:44 ca Exp $") 17 #include <limits.h> 18 #include <sm/io.h> 19 #include "local.h" 20 21 /* 22 ** SM_VSNPRINTF -- format data for "output" into a string 23 ** 24 ** Assigned 'str' to a "fake" file pointer. This allows common 25 ** o/p formatting function sm_vprintf() to be used. 26 ** 27 ** Parameters: 28 ** str -- location for output 29 ** n -- maximum size for o/p 30 ** fmt -- format directives 31 ** ap -- data unit vectors for use by 'fmt' 32 ** 33 ** Results: 34 ** result from sm_io_vfprintf() 35 ** 36 ** Side Effects: 37 ** Limits the size ('n') to INT_MAX. 38 */ 39 40 int 41 sm_vsnprintf(str, n, fmt, ap) 42 char *str; 43 size_t n; 44 const char *fmt; 45 va_list ap; 46 { 47 int ret; 48 char dummy; 49 SM_FILE_T fake; 50 51 /* While snprintf(3) specifies size_t stdio uses an int internally */ 52 if (n > INT_MAX) 53 n = INT_MAX; 54 55 /* Stdio internals do not deal correctly with zero length buffer */ 56 if (n == 0) 57 { 58 str = &dummy; 59 n = 1; 60 } 61 fake.sm_magic = SmFileMagic; 62 fake.f_timeout = SM_TIME_FOREVER; 63 fake.f_timeoutstate = SM_TIME_BLOCK; 64 fake.f_file = -1; 65 fake.f_flags = SMWR | SMSTR; 66 fake.f_bf.smb_base = fake.f_p = (unsigned char *)str; 67 fake.f_bf.smb_size = fake.f_w = n - 1; 68 fake.f_close = NULL; 69 fake.f_open = NULL; 70 fake.f_read = NULL; 71 fake.f_write = NULL; 72 fake.f_seek = NULL; 73 fake.f_setinfo = fake.f_getinfo = NULL; 74 fake.f_type = "sm_vsnprintf:fake"; 75 ret = sm_io_vfprintf(&fake, SM_TIME_FOREVER, fmt, ap); 76 *fake.f_p = 0; 77 return ret; 78 } 79