/* * Copyright (c) 2002, 2004, 2005 Sendmail, Inc. and its suppliers. * All rights reserved. * * By using this file, you agree to the terms and conditions set * forth in the LICENSE file which can be found at the top level of * the sendmail distribution. */ #include "sm/generic.h" SM_RCSID("@(#)$Id: fputv.c,v 1.11 2006/07/14 14:42:25 ca Exp $") #include "sm/error.h" #include "sm/io.h" #include "sm/assert.h" #include "sm/varargs.h" #include "sm/limits.h" #include "sm/strrcb.h" #include "sm/rcb.h" #include "sm/str-int.h" #if !SM_NO_CSTR # include "sm/cstr.h" #endif /* ** SM_IO_FPUTV -- put several values into fp buffer ** ** Parameters: ** fp -- the file pointer for the buffer to be written to ** ... -- arguments ** ** Returns: ** usual sm_error code */ sm_ret_T sm_io_fputv(sm_file_T *fp, ...) { int k; uint32_t rt, v; sm_str_P str; #if !SM_NO_CSTR sm_cstr_P cstr; #endif uchar *buf; size_t len; sm_ret_T ret; va_list ap; SM_IS_FP(fp); va_start(ap, fp); for (;;) { k = va_arg(ap, int); if (k == SM_RCBV_END) break; rt = va_arg(ap, uint32_t); switch (k) { case SM_RCBV_INT: v = va_arg(ap, uint32_t); ret = sm_io_fput3uint32(fp, rt, 4, v); if (sm_is_err(ret)) goto err1; break; case SM_RCBV_STR: str = va_arg(ap, sm_str_P); SM_IS_BUF(str); ret = sm_io_fput2uint32(fp, rt, sm_str_getlen(str)); if (sm_is_err(ret)) goto err1; ret = sm_io_fputn(fp, sm_str_data(str), sm_str_getlen(str)); if (sm_is_err(ret)) goto err1; break; #if !SM_NO_CSTR case SM_RCBV_CSTR: cstr = va_arg(ap, sm_cstr_P); if (cstr == NULL) { ret = sm_io_fput2uint32(fp, rt, 0); if (sm_is_err(ret)) goto err1; break; } SM_IS_CSTR(cstr); ret = sm_io_fput2uint32(fp, rt, sm_cstr_getlen(cstr)); if (sm_is_err(ret)) goto err1; ret = sm_io_fputn(fp, sm_cstr_data(cstr), sm_cstr_getlen(cstr)); if (sm_is_err(ret)) goto err1; break; #endif /* !SM_NO_CSTR */ case SM_RCBV_BUF: buf = va_arg(ap, uchar *); len = va_arg(ap, size_t); ret = sm_io_fput2uint32(fp, rt, len); if (sm_is_err(ret)) goto err1; ret = sm_io_fputn(fp, buf, len); if (sm_is_err(ret)) goto err1; break; default: ret = sm_error_perm(SM_EM_RCB, EINVAL); goto err1; } } va_end(ap); return SM_SUCCESS; err1: va_end(ap); return ret; }