140266059SGregory Neil Shapiro /* 25dd76dd0SGregory Neil Shapiro * Copyright (c) 2000-2001 Proofpoint, Inc. and its suppliers. 340266059SGregory Neil Shapiro * All rights reserved. 440266059SGregory Neil Shapiro * 540266059SGregory Neil Shapiro * By using this file, you agree to the terms and conditions set 640266059SGregory Neil Shapiro * forth in the LICENSE file which can be found at the top level of 740266059SGregory Neil Shapiro * the sendmail distribution. 840266059SGregory Neil Shapiro */ 940266059SGregory Neil Shapiro 1040266059SGregory Neil Shapiro /* 1140266059SGregory Neil Shapiro * Copyright (c) 1997 Todd C. Miller <Todd.Miller@courtesan.com> 1240266059SGregory Neil Shapiro * 13a7ec597cSGregory Neil Shapiro * Permission to use, copy, modify, and distribute this software for any 14a7ec597cSGregory Neil Shapiro * purpose with or without fee is hereby granted, provided that the above 15a7ec597cSGregory Neil Shapiro * copyright notice and this permission notice appear in all copies. 1640266059SGregory Neil Shapiro * 17a7ec597cSGregory Neil Shapiro * THE SOFTWARE IS PROVIDED "AS IS" AND TODD C. MILLER DISCLAIMS ALL 18a7ec597cSGregory Neil Shapiro * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES 19a7ec597cSGregory Neil Shapiro * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL TODD C. MILLER BE LIABLE 20a7ec597cSGregory Neil Shapiro * FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 21a7ec597cSGregory Neil Shapiro * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION 22a7ec597cSGregory Neil Shapiro * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 23a7ec597cSGregory Neil Shapiro * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 2440266059SGregory Neil Shapiro */ 2540266059SGregory Neil Shapiro 2640266059SGregory Neil Shapiro #include <sm/gen.h> 274313cc83SGregory Neil Shapiro SM_RCSID("@(#)$Id: vasprintf.c,v 1.28 2013-11-22 20:51:44 ca Exp $") 2840266059SGregory Neil Shapiro #include <stdlib.h> 2940266059SGregory Neil Shapiro #include <errno.h> 3040266059SGregory Neil Shapiro #include <sm/io.h> 3140266059SGregory Neil Shapiro #include <sm/heap.h> 3240266059SGregory Neil Shapiro #include "local.h" 3340266059SGregory Neil Shapiro 3440266059SGregory Neil Shapiro /* 3540266059SGregory Neil Shapiro ** SM_VASPRINTF -- printf to a dynamically allocated string 3640266059SGregory Neil Shapiro ** 3740266059SGregory Neil Shapiro ** Write 'printf' output to a dynamically allocated string 3840266059SGregory Neil Shapiro ** buffer which is returned to the caller. 3940266059SGregory Neil Shapiro ** 4040266059SGregory Neil Shapiro ** Parameters: 4140266059SGregory Neil Shapiro ** str -- *str receives a pointer to the allocated string 4240266059SGregory Neil Shapiro ** fmt -- format directives for printing 4340266059SGregory Neil Shapiro ** ap -- variable argument list 4440266059SGregory Neil Shapiro ** 4540266059SGregory Neil Shapiro ** Results: 4640266059SGregory Neil Shapiro ** On failure, set *str to NULL, set errno, and return -1. 4740266059SGregory Neil Shapiro ** 4840266059SGregory Neil Shapiro ** On success, set *str to a pointer to a nul-terminated 4940266059SGregory Neil Shapiro ** string buffer containing printf output, and return the 5040266059SGregory Neil Shapiro ** length of the string (not counting the nul). 5140266059SGregory Neil Shapiro */ 5240266059SGregory Neil Shapiro 5340266059SGregory Neil Shapiro #define SM_VA_BUFSIZE 128 5440266059SGregory Neil Shapiro 5540266059SGregory Neil Shapiro int 5640266059SGregory Neil Shapiro sm_vasprintf(str, fmt, ap) 5740266059SGregory Neil Shapiro char **str; 5840266059SGregory Neil Shapiro const char *fmt; 59*2fb4f839SGregory Neil Shapiro va_list ap; 6040266059SGregory Neil Shapiro { 6140266059SGregory Neil Shapiro int ret; 6240266059SGregory Neil Shapiro SM_FILE_T fake; 6340266059SGregory Neil Shapiro unsigned char *base; 6440266059SGregory Neil Shapiro 6540266059SGregory Neil Shapiro fake.sm_magic = SmFileMagic; 6640266059SGregory Neil Shapiro fake.f_timeout = SM_TIME_FOREVER; 6740266059SGregory Neil Shapiro fake.f_timeoutstate = SM_TIME_BLOCK; 6840266059SGregory Neil Shapiro fake.f_file = -1; 6940266059SGregory Neil Shapiro fake.f_flags = SMWR | SMSTR | SMALC; 7040266059SGregory Neil Shapiro fake.f_bf.smb_base = fake.f_p = (unsigned char *)sm_malloc(SM_VA_BUFSIZE); 7140266059SGregory Neil Shapiro if (fake.f_bf.smb_base == NULL) 7240266059SGregory Neil Shapiro goto err2; 7340266059SGregory Neil Shapiro fake.f_close = NULL; 7440266059SGregory Neil Shapiro fake.f_open = NULL; 7540266059SGregory Neil Shapiro fake.f_read = NULL; 7640266059SGregory Neil Shapiro fake.f_write = NULL; 7740266059SGregory Neil Shapiro fake.f_seek = NULL; 7840266059SGregory Neil Shapiro fake.f_setinfo = fake.f_getinfo = NULL; 7940266059SGregory Neil Shapiro fake.f_type = "sm_vasprintf:fake"; 8040266059SGregory Neil Shapiro fake.f_bf.smb_size = fake.f_w = SM_VA_BUFSIZE - 1; 8140266059SGregory Neil Shapiro fake.f_timeout = SM_TIME_FOREVER; 8240266059SGregory Neil Shapiro ret = sm_io_vfprintf(&fake, SM_TIME_FOREVER, fmt, ap); 8340266059SGregory Neil Shapiro if (ret == -1) 8440266059SGregory Neil Shapiro goto err; 8540266059SGregory Neil Shapiro *fake.f_p = '\0'; 8640266059SGregory Neil Shapiro 8740266059SGregory Neil Shapiro /* use no more space than necessary */ 8840266059SGregory Neil Shapiro base = (unsigned char *) sm_realloc(fake.f_bf.smb_base, ret + 1); 8940266059SGregory Neil Shapiro if (base == NULL) 9040266059SGregory Neil Shapiro goto err; 9140266059SGregory Neil Shapiro *str = (char *)base; 9240266059SGregory Neil Shapiro return ret; 9340266059SGregory Neil Shapiro 9440266059SGregory Neil Shapiro err: 9540266059SGregory Neil Shapiro if (fake.f_bf.smb_base != NULL) 9640266059SGregory Neil Shapiro { 9740266059SGregory Neil Shapiro sm_free(fake.f_bf.smb_base); 9840266059SGregory Neil Shapiro fake.f_bf.smb_base = NULL; 9940266059SGregory Neil Shapiro } 10040266059SGregory Neil Shapiro err2: 10140266059SGregory Neil Shapiro *str = NULL; 10240266059SGregory Neil Shapiro errno = ENOMEM; 10340266059SGregory Neil Shapiro return -1; 10440266059SGregory Neil Shapiro } 105