1 /* 2 * Copyright (c) 2000-2001 Sendmail, 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 #pragma ident "%Z%%M% %I% %E% SMI" 16 17 #include <sm/gen.h> 18 SM_RCSID("@(#)$Id: vsnprintf.c,v 1.21 2001/03/04 23:28:41 ca Exp $") 19 #include <limits.h> 20 #include <sm/io.h> 21 #include "local.h" 22 23 /* 24 ** SM_VSNPRINTF -- format data for "output" into a string 25 ** 26 ** Assigned 'str' to a "fake" file pointer. This allows common 27 ** o/p formatting function sm_vprintf() to be used. 28 ** 29 ** Parameters: 30 ** str -- location for output 31 ** n -- maximum size for o/p 32 ** fmt -- format directives 33 ** ap -- data unit vectors for use by 'fmt' 34 ** 35 ** Results: 36 ** result from sm_io_vfprintf() 37 ** 38 ** Side Effects: 39 ** Limits the size ('n') to INT_MAX. 40 */ 41 42 int 43 sm_vsnprintf(str, n, fmt, ap) 44 char *str; 45 size_t n; 46 const char *fmt; 47 SM_VA_LOCAL_DECL 48 { 49 int ret; 50 char dummy; 51 SM_FILE_T fake; 52 53 /* While snprintf(3) specifies size_t stdio uses an int internally */ 54 if (n > INT_MAX) 55 n = INT_MAX; 56 57 /* Stdio internals do not deal correctly with zero length buffer */ 58 if (n == 0) 59 { 60 str = &dummy; 61 n = 1; 62 } 63 fake.sm_magic = SmFileMagic; 64 fake.f_timeout = SM_TIME_FOREVER; 65 fake.f_timeoutstate = SM_TIME_BLOCK; 66 fake.f_file = -1; 67 fake.f_flags = SMWR | SMSTR; 68 fake.f_bf.smb_base = fake.f_p = (unsigned char *)str; 69 fake.f_bf.smb_size = fake.f_w = n - 1; 70 fake.f_close = NULL; 71 fake.f_open = NULL; 72 fake.f_read = NULL; 73 fake.f_write = NULL; 74 fake.f_seek = NULL; 75 fake.f_setinfo = fake.f_getinfo = NULL; 76 fake.f_type = "sm_vsnprintf:fake"; 77 ret = sm_io_vfprintf(&fake, SM_TIME_FOREVER, fmt, ap); 78 *fake.f_p = 0; 79 return ret; 80 } 81