1N/A/*
1N/A * Copyright (c) 2000-2001 Sendmail, Inc. and its suppliers.
1N/A * All rights reserved.
1N/A * Copyright (c) 1990, 1993
1N/A * The Regents of the University of California. All rights reserved.
1N/A *
1N/A * This code is derived from software contributed to Berkeley by
1N/A * Chris Torek.
1N/A *
1N/A * By using this file, you agree to the terms and conditions set
1N/A * forth in the LICENSE file which can be found at the top level of
1N/A * the sendmail distribution.
1N/A */
1N/A
1N/A#pragma ident "%Z%%M% %I% %E% SMI"
1N/A
1N/A#include <sm/gen.h>
1N/ASM_RCSID("@(#)$Id: vsnprintf.c,v 1.21 2001/03/04 23:28:41 ca Exp $")
1N/A#include <limits.h>
1N/A#include <sm/io.h>
1N/A#include "local.h"
1N/A
1N/A/*
1N/A** SM_VSNPRINTF -- format data for "output" into a string
1N/A**
1N/A** Assigned 'str' to a "fake" file pointer. This allows common
1N/A** o/p formatting function sm_vprintf() to be used.
1N/A**
1N/A** Parameters:
1N/A** str -- location for output
1N/A** n -- maximum size for o/p
1N/A** fmt -- format directives
1N/A** ap -- data unit vectors for use by 'fmt'
1N/A**
1N/A** Results:
1N/A** result from sm_io_vfprintf()
1N/A**
1N/A** Side Effects:
1N/A** Limits the size ('n') to INT_MAX.
1N/A*/
1N/A
1N/Aint
1N/Asm_vsnprintf(str, n, fmt, ap)
1N/A char *str;
1N/A size_t n;
1N/A const char *fmt;
1N/A SM_VA_LOCAL_DECL
1N/A{
1N/A int ret;
1N/A char dummy;
1N/A SM_FILE_T fake;
1N/A
1N/A /* While snprintf(3) specifies size_t stdio uses an int internally */
1N/A if (n > INT_MAX)
1N/A n = INT_MAX;
1N/A
1N/A /* Stdio internals do not deal correctly with zero length buffer */
1N/A if (n == 0)
1N/A {
1N/A str = &dummy;
1N/A n = 1;
1N/A }
1N/A fake.sm_magic = SmFileMagic;
1N/A fake.f_timeout = SM_TIME_FOREVER;
1N/A fake.f_timeoutstate = SM_TIME_BLOCK;
1N/A fake.f_file = -1;
1N/A fake.f_flags = SMWR | SMSTR;
1N/A fake.f_bf.smb_base = fake.f_p = (unsigned char *)str;
1N/A fake.f_bf.smb_size = fake.f_w = n - 1;
1N/A fake.f_close = NULL;
1N/A fake.f_open = NULL;
1N/A fake.f_read = NULL;
1N/A fake.f_write = NULL;
1N/A fake.f_seek = NULL;
1N/A fake.f_setinfo = fake.f_getinfo = NULL;
1N/A fake.f_type = "sm_vsnprintf:fake";
1N/A ret = sm_io_vfprintf(&fake, SM_TIME_FOREVER, fmt, ap);
1N/A *fake.f_p = 0;
1N/A return ret;
1N/A}