11556Srgrimes/* 21556Srgrimes * Copyright (c) 2000-2001 Proofpoint, Inc. and its suppliers. 31556Srgrimes * All rights reserved. 41556Srgrimes * Copyright (c) 1990, 1993 51556Srgrimes * The Regents of the University of California. All rights reserved. 61556Srgrimes * 71556Srgrimes * This code is derived from software contributed to Berkeley by 81556Srgrimes * Chris Torek. 91556Srgrimes * 101556Srgrimes * By using this file, you agree to the terms and conditions set 111556Srgrimes * forth in the LICENSE file which can be found at the top level of 121556Srgrimes * the sendmail distribution. 131556Srgrimes */ 141556Srgrimes 151556Srgrimes#include <sm/gen.h> 161556SrgrimesSM_RCSID("@(#)$Id: vsnprintf.c,v 1.24 2013-11-22 20:51:44 ca Exp $") 171556Srgrimes#include <limits.h> 181556Srgrimes#include <sm/io.h> 191556Srgrimes#include "local.h" 201556Srgrimes 211556Srgrimes/* 221556Srgrimes** SM_VSNPRINTF -- format data for "output" into a string 231556Srgrimes** 241556Srgrimes** Assigned 'str' to a "fake" file pointer. This allows common 251556Srgrimes** o/p formatting function sm_vprintf() to be used. 261556Srgrimes** 271556Srgrimes** Parameters: 281556Srgrimes** str -- location for output 291556Srgrimes** n -- maximum size for o/p 301556Srgrimes** fmt -- format directives 311556Srgrimes** ap -- data unit vectors for use by 'fmt' 321556Srgrimes** 331556Srgrimes** Results: 341556Srgrimes** result from sm_io_vfprintf() 351556Srgrimes** 361556Srgrimes** Side Effects: 371556Srgrimes** Limits the size ('n') to INT_MAX. 3850471Speter*/ 391556Srgrimes 401556Srgrimesint 411556Srgrimessm_vsnprintf(str, n, fmt, ap) 421556Srgrimes char *str; 431556Srgrimes size_t n; 441556Srgrimes const char *fmt; 451556Srgrimes va_list ap; 461556Srgrimes{ 471556Srgrimes int ret; 4846684Skris char dummy; 491556Srgrimes SM_FILE_T fake; 501556Srgrimes 511556Srgrimes /* While snprintf(3) specifies size_t stdio uses an int internally */ 521556Srgrimes if (n > INT_MAX) 531556Srgrimes n = INT_MAX; 5446684Skris 551556Srgrimes /* Stdio internals do not deal correctly with zero length buffer */ 561556Srgrimes if (n == 0) 571556Srgrimes { 581556Srgrimes str = &dummy; 591556Srgrimes n = 1; 601556Srgrimes } 611556Srgrimes fake.sm_magic = SmFileMagic; 621556Srgrimes fake.f_timeout = SM_TIME_FOREVER; 631556Srgrimes fake.f_timeoutstate = SM_TIME_BLOCK; 641556Srgrimes fake.f_file = -1; 651556Srgrimes fake.f_flags = SMWR | SMSTR; 661556Srgrimes fake.f_bf.smb_base = fake.f_p = (unsigned char *)str; 671556Srgrimes fake.f_bf.smb_size = fake.f_w = n - 1; 681556Srgrimes fake.f_close = NULL; 691556Srgrimes fake.f_open = NULL; 701556Srgrimes fake.f_read = NULL; 711556Srgrimes fake.f_write = NULL; 721556Srgrimes fake.f_seek = NULL; 731556Srgrimes fake.f_setinfo = fake.f_getinfo = NULL; 741556Srgrimes fake.f_type = "sm_vsnprintf:fake"; 751556Srgrimes ret = sm_io_vfprintf(&fake, SM_TIME_FOREVER, fmt, ap); 761556Srgrimes *fake.f_p = 0; 771556Srgrimes return ret; 781556Srgrimes} 791556Srgrimes