/*
* 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;
}
syntax highlighted by Code2HTML, v. 0.9.1