/* * Copyright (c) 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: str2args.c,v 1.6 2007/01/11 17:41:08 ca Exp $") #include "sm/assert.h" #include "sm/magic.h" #include "sm/memops.h" #include "sm/ctype.h" #include "sm/rpool.h" #include "sm/strrcb.h" #include "sm/str-int.h" #include "sm/str2rcb.h" /* ** SM_STR2ARGS -- split string into argument names and values ** field1=value SPACE field2=value ... ** =value is optional, if it doesn't exist argvalues[]=0 ** (it is >0 otherwise). [make it an option whether =value is required?] ** ** Parameters: ** str -- string to split ** offset -- offset at which to start ** maxargs -- size of argument vectors ** argnames -- fill in with offsets to argument names ** argvalues -- fill in with offsets to argument values ** ** Returns: ** usual return code ** ** Side Effects: ** replaces space and '=' characters in str with '\0' */ #define SM_EQUAL ((uchar) '=') sm_ret_T sm_str2args(sm_str_P str, uint offset, uint maxargs, uint *argnames, uint *argvalues) { uint i, arg, len; uchar c; SM_REQUIRE(str != NULL); SM_REQUIRE(argnames != NULL); SM_REQUIRE(argvalues != NULL); SM_REQUIRE(maxargs > 0); sm_memzero(argnames, maxargs * sizeof(argnames[0])); sm_memzero(argvalues, maxargs * sizeof(argvalues[0])); len = sm_str_getlen(str); for (i = offset, arg = 0; i < len && (c = sm_str_rd_elem(str, i)) != '\0'; i++) { /* skip over leading spaces */ while (i < len && (c = sm_str_rd_elem(str, i)) != '\0' && ISSPACE(c)) ++i; if (i >= len) break; /* get name of argument */ argnames[arg] = i; while (i < len && (c = sm_str_rd_elem(str, i)) != '\0' && c != SM_EQUAL && ISPRINT(c) && !ISSPACE(c)) ++i; if (i >= len) { argvalues[arg] = 0; ++arg; break; } if (i <= argnames[arg]) return sm_err_perm(EINVAL); if ((c = sm_str_rd_elem(str, i)) != '\0' && SM_EQUAL == c) sm_str_wr_elem(str, i, '\0'); if (SM_EQUAL == c) { if (++i >= len) return sm_err_perm(EINVAL); /* get name of argument */ argvalues[arg] = i; while (i < len && (c = sm_str_rd_elem(str, i)) != '\0' && ISPRINT(c) && !ISSPACE(c)) ++i; if (i <= argvalues[arg]) return sm_err_perm(EINVAL); } else argvalues[arg] = 0; ++arg; if (i >= len) break; if ((c = sm_str_rd_elem(str, i)) != '\0') { if (ISSPACE(c)) sm_str_wr_elem(str, i, '\0'); else return sm_err_perm(EINVAL); } if (arg >= maxargs) return sm_err_perm(E2BIG); } return arg; }