1N/A/*
1N/A * Copyright (c) 2000-2001 Sendmail, Inc. and its suppliers.
1N/A * All rights reserved.
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/*
1N/A * Copyright (c) 1997 Todd C. Miller <Todd.Miller@courtesan.com>
1N/A *
1N/A * Permission to use, copy, modify, and distribute this software for any
1N/A * purpose with or without fee is hereby granted, provided that the above
1N/A * copyright notice and this permission notice appear in all copies.
1N/A *
1N/A * THE SOFTWARE IS PROVIDED "AS IS" AND TODD C. MILLER DISCLAIMS ALL
1N/A * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
1N/A * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL TODD C. MILLER BE LIABLE
1N/A * FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
1N/A * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
1N/A * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
1N/A * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
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: vasprintf.c,v 1.26.2.1 2003/06/03 02:14:09 ca Exp $")
1N/A#include <stdlib.h>
1N/A#include <errno.h>
1N/A#include <sm/io.h>
1N/A#include <sm/heap.h>
1N/A#include "local.h"
1N/A
1N/A/*
1N/A** SM_VASPRINTF -- printf to a dynamically allocated string
1N/A**
1N/A** Write 'printf' output to a dynamically allocated string
1N/A** buffer which is returned to the caller.
1N/A**
1N/A** Parameters:
1N/A** str -- *str receives a pointer to the allocated string
1N/A** fmt -- format directives for printing
1N/A** ap -- variable argument list
1N/A**
1N/A** Results:
1N/A** On failure, set *str to NULL, set errno, and return -1.
1N/A**
1N/A** On success, set *str to a pointer to a nul-terminated
1N/A** string buffer containing printf output, and return the
1N/A** length of the string (not counting the nul).
1N/A*/
1N/A
1N/A#define SM_VA_BUFSIZE 128
1N/A
1N/Aint
1N/Asm_vasprintf(str, fmt, ap)
1N/A char **str;
1N/A const char *fmt;
1N/A SM_VA_LOCAL_DECL
1N/A{
1N/A int ret;
1N/A SM_FILE_T fake;
1N/A unsigned char *base;
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 | SMALC;
1N/A fake.f_bf.smb_base = fake.f_p = (unsigned char *)sm_malloc(SM_VA_BUFSIZE);
1N/A if (fake.f_bf.smb_base == NULL)
1N/A goto err2;
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_vasprintf:fake";
1N/A fake.f_bf.smb_size = fake.f_w = SM_VA_BUFSIZE - 1;
1N/A fake.f_timeout = SM_TIME_FOREVER;
1N/A ret = sm_io_vfprintf(&fake, SM_TIME_FOREVER, fmt, ap);
1N/A if (ret == -1)
1N/A goto err;
1N/A *fake.f_p = '\0';
1N/A
1N/A /* use no more space than necessary */
1N/A base = (unsigned char *) sm_realloc(fake.f_bf.smb_base, ret + 1);
1N/A if (base == NULL)
1N/A goto err;
1N/A *str = (char *)base;
1N/A return ret;
1N/A
1N/Aerr:
1N/A if (fake.f_bf.smb_base != NULL)
1N/A {
1N/A sm_free(fake.f_bf.smb_base);
1N/A fake.f_bf.smb_base = NULL;
1N/A }
1N/Aerr2:
1N/A *str = NULL;
1N/A errno = ENOMEM;
1N/A return -1;
1N/A}