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> 16SM_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 40int 41sm_vsnprintf(str, n, fmt, ap) 42 char *str; 43 size_t n; 44 const char *fmt; 45 SM_VA_LOCAL_DECL 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