Files
m241Neelima/components/ip_net2-6.9/ipmip/src/ipmip_sysvar.c
T
2026-07-30 11:19:44 +05:30

1096 lines
31 KiB
C

/*
******************************************************************************
* INTERPEAK SOURCE FILE
*
* Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipmip_sysvar.c,v $ $Revision: 1.20.10.1 $
* $Source: /home/interpeak/CVSRoot/ipmip/src/ipmip_sysvar.c,v $
* $Author: jsheng $
* $State: Exp $ $Locker: $
*
* INTERPEAK_COPYRIGHT_STRING
* Design and implementation by Joel Hortelius <joel.hortelis@interpeak.se>
******************************************************************************
*/
/*
****************************************************************************
* 1 DESCRIPTION
****************************************************************************
*/
/*
****************************************************************************
* 2 CONFIGURATION
****************************************************************************
*/
#include "ipmip_config.h"
/*
****************************************************************************
* 3 INCLUDE FILES
****************************************************************************
*/
#define IPCOM_USE_CLIB_PROTO
#include <ipcom_clib.h>
#include <ipcom_err.h>
#include <ipcom_inet.h>
#include <ipcom_sock.h>
#include <ipcom_sock2.h>
#include <ipcom_syslog.h>
#include <ipcom_sysvar.h>
#ifdef IPMIP_USE_INET6
#include <ipcom_sock6.h>
#endif
#include <ipmip.h>
#include <private/ipmip_sysvar.h>
#include <private/ipmip_util.h>
#include <private/ipmip_context.h>
/*
****************************************************************************
* 4 DEFINES
****************************************************************************
*/
#define IPCOM_SYSLOG_PRIORITY IPCOM_LOG_DEBUG2
#define IPCOM_SYSLOG_FACILITY IPCOM_LOG_IPMIP
/*
****************************************************************************
* 5 TYPES
****************************************************************************
*/
/* Information required to process the 'forech' */
typedef struct Ipmip_sysvar_foreach_cbinfo
{
Ip_u32 baselen;
void *opaque;
Ipmip_sysvar_foreach_t cb_func;
Ipmip_proc_t *proc;
} Ipmip_sysvar_foreach_cbinfo_t;
typedef struct Ipmip_sysvar_foreach_cbinfo_ext
{
Ip_u32 baselen;
void *opaque;
void *ctx;
Ipmip_sysvar_foreach_ext_t cb_func;
Ipmip_proc_t *proc;
} Ipmip_sysvar_foreach_cbinfo_ext_t;
/*
****************************************************************************
* 6 EXTERN PROTOTYPES
****************************************************************************
*/
/*
****************************************************************************
* 7 LOCAL PROTOTYPES
****************************************************************************
*/
/*
****************************************************************************
* 8 DATA
****************************************************************************
*/
const char *ipmip_sysvar_mode_desc[] =
{
"disabled",
"optional",
"required"
};
const Ipmip_sysvar_key_map_t ipmip_sysvar_bool_ops[] =
{
{ 1, "enable" },
{ 1, "enabled" },
{ 1, "true" },
{ 1, "on" },
{ 1, "yes" },
{ 0, "disable" },
{ 0, "disabled" },
{ 0, "false" },
{ 0, "off" },
{ 0, "no" },
{ 0, 0 }
};
const Ipmip_sysvar_key_map_t ipmip_sysvar_tunnel_mask[] =
{
{ IPMIP_TUNNELMASK_GRE, "gre" },
{ IPMIP_TUNNELMASK_IP, "ip" },
{ IPMIP_TUNNELMASK_INET6, "inet6" },
{ IPMIP_TUNNELMASK_INET, "inet" },
{ IPMIP_TUNNELMASK_INET_GRE, "inet.gre" },
{ IPMIP_TUNNELMASK_INET6_GRE6, "inet6.gre" },
{ IPMIP_TUNNELMASK_INET_IPIP, "inet.ipip" },
{ IPMIP_TUNNELMASK_INET_IPIP, "inet.ip" },
{ IPMIP_TUNNELMASK_INET6_IP6IP6, "inet6.ip6ip6" },
{ IPMIP_TUNNELMASK_INET6_IP6IP6, "inet6.ip" },
{ IPMIP_TUNNELMASK_INET_MINENC, "inet.minenc" },
{ IPMIP_TUNNELMASK_INET_MINENC, "minenc" },
{ 0, 0 }
};
/*
****************************************************************************
* 9 STATIC FUNCTIONS
****************************************************************************
*/
/*
*===========================================================================
* ipmip_sysvar_foreach_parse
*===========================================================================
* Description:
* Parameters:
* Returns:
*
*/
IP_STATIC int
ipmip_sysvar_foreach_parse(const char *name,
const char *value,
int flags,
Ipmip_sysvar_foreach_cbinfo_t *data)
{
Ip_size_t blen = data->baselen;
(void) (flags);
if (name[blen] == '.')
blen++;
(*data->cb_func) (data->proc,
name,
&name[blen],
value,
data->opaque);
return IPCOM_SUCCESS;
}
IP_STATIC int
ipmip_sysvar_foreach_ext_parse(const char *name,
const char *value,
int flags,
Ipmip_sysvar_foreach_cbinfo_ext_t *data)
{
Ip_size_t blen = data->baselen;
(void) (flags);
if (name[blen] == '.')
blen++;
(*data->cb_func) (data->ctx,
data->proc,
name,
&name[blen],
value,
data->opaque);
return IPCOM_SUCCESS;
}
/*
*===========================================================================
* ipmip_sysvar_get
*===========================================================================
* Description:
* Parameters:
* Returns:
*
*/
IP_STATIC char *
ipmip_sysvar_get(const char *format, va_list ap)
{
char *buf = IP_NULL;
char *result = IP_NULL;
buf = ipmip_util_vstrdup(format, ap);
if (buf == IP_NULL)
goto done_out;
/* Get the sysvar */
result = ipcom_sysvar_get(buf, IP_NULL, IP_NULL);
/* Dont allow zero length results */
if (result && ipcom_strlen(result) == 0)
{
ipcom_free(result);
result = IP_NULL;
}
done_out:
if (buf)
ipcom_free(buf);
return result;
}
/*
****************************************************************************
* 10 GLOBAL FUNCTIONS
****************************************************************************
*/
/*
*===========================================================================
* ipmip_sysvar_cmd_str_to_key
*===========================================================================
* Description: Converts the string representation in map to the numeric value.
* Parameters: map - The int to string map to use.
* key - The protocol number.
* Returns: The string represenstion.
*
*/
IP_GLOBAL int
ipmip_sysvar_cmd_str_to_key(const Ipmip_sysvar_key_map_t *map,
const char *str)
{
int i;
if (str)
{
int ival;
/**/
for (i = 0; map[i].str != IP_NULL; i++)
if (ipcom_strcasecmp(str, map[i].str) == 0)
return map[i].key;
/**/
ival = (int)ipcom_strtol(str, IP_NULL, 10);
for (i = 0; map[i].str != IP_NULL; i++)
if (map[i].key == ival)
return ival;
}
return -1;
}
/*
*===========================================================================
* ipmip_sysvar_set
*===========================================================================
* Description:
* Parameters:
* Returns:
*
*/
IP_GLOBAL void
ipmip_sysvar_set(const char *value,
const char *format,
/* args*/ ...)
{
va_list ap;
char *buf;
va_start(ap, format);
buf = ipmip_util_vstrdup(format, ap);
va_end(ap);
if(IP_NULL == buf)
return;
(void)ipcom_sysvar_set(buf, value, IPCOM_SYSVAR_FLAG_OVERWRITE);
ipcom_free(buf);
}
IP_GLOBAL void
ipmip_sysvar_set_ulong(unsigned long value,
const char *format,
/* args*/ ...)
{
va_list ap;
char *buf;
char *vbuf;;
va_start(ap, format);
buf = ipmip_util_vstrdup(format, ap);
va_end(ap);
if(IP_NULL == buf)
return;
/* Create me a value */
vbuf = ipmip_util_strdup("%u", value);
(void)ipcom_sysvar_set(buf, vbuf, IPCOM_SYSVAR_FLAG_OVERWRITE);
ipcom_free(buf);
ipcom_free(vbuf);
}
/*
*===========================================================================
* ipmip_sysvar_unset
*===========================================================================
* Description:
* Parameters:
* Returns:
*
*/
IP_GLOBAL void
ipmip_sysvar_unset(const char *format,
/* args*/ ...)
{
va_list ap;
char *buf;
va_start(ap, format);
buf = ipmip_util_vstrdup(format, ap);
va_end(ap);
if(IP_NULL == buf)
return;
ipcom_sysvar_unset(buf);
ipcom_free(buf);
}
/*
*===========================================================================
* ipmip_vsysvar
*===========================================================================
* Description: Return the configuration system variable value pointer to
* by the format string and the provided optional arguments.
* The return value is dynamically allocated, and must be
* freed by the caller.
* Parameters: format - Format string
* ap - Optional arguments
* Returns: The configuration string value
*
*/
IP_GLOBAL char *
ipmip_vsysvar(const char *format,
va_list ap)
{
return ipmip_sysvar_get(format, ap);
}
/*
*===========================================================================
* ipmip_sysvar
*===========================================================================
* Description: Return the configuration system variable value pointer to
* by the format string and the provided optional arguments.
* The return value is dynamically allocated, and must be
* freed by the caller.
* Parameters: format - Format string
* ... - Optional arguments
* Returns: The configuration string value
*
*/
IP_GLOBAL char *
ipmip_sysvar(const char *format,
/* args*/ ...)
{
va_list ap;
char *buf;
va_start(ap, format);
buf = ipmip_sysvar_get(format, ap);
va_end(ap);
return buf;
}
/*
*===========================================================================
* ipmip_sysvar_mode
*===========================================================================
* Description: Parse and return a mode value, where mode is either DISABLED,
* OPTIONAL or REQUIRED. DISABLED equals integer 0, or 'disable',
* 'disabled', 'false' or 'no'. OPTIONAL equals integer 1, or
* 'optional' or 'may'. REQUIRED equals 'yes', 'true', integer 2,
* 'enable', 'enabled' or 'required'
* Parameters: defval - The default value.
* format - Format string
* ... - Optional arguments
* Returns: IPMIP4_SYSVAR_MODE_DISABLED, IPMIP4_SYSVAR_MODE_OPTIONAL or
* IPMIP4_SYSVAR_MODE_REQUIRED
*
*/
IP_GLOBAL int
ipmip_sysvar_mode(int defval,
const char *format,
/* args*/ ...)
{
va_list ap;
char *buf;
va_start(ap, format);
buf = ipmip_sysvar_get(format, ap);
va_end(ap);
/* Parse the value */
if (buf)
{
int op_val = -1;
static Ipmip_sysvar_key_map_t ops[] =
{
{ IPMIP_SYSVAR_MODE_REQUIRED, "enable" },
{ IPMIP_SYSVAR_MODE_REQUIRED, "enabled" },
{ IPMIP_SYSVAR_MODE_REQUIRED, "required" },
{ IPMIP_SYSVAR_MODE_REQUIRED, "true" },
{ IPMIP_SYSVAR_MODE_REQUIRED, "on" },
{ IPMIP_SYSVAR_MODE_REQUIRED, "yes" },
{ IPMIP_SYSVAR_MODE_OPTIONAL, "optional" },
{ IPMIP_SYSVAR_MODE_OPTIONAL, "option" },
{ IPMIP_SYSVAR_MODE_OPTIONAL, "may" },
{ IPMIP_SYSVAR_MODE_DISABLED, "disable" },
{ IPMIP_SYSVAR_MODE_DISABLED, "disabled" },
{ IPMIP_SYSVAR_MODE_DISABLED, "false" },
{ IPMIP_SYSVAR_MODE_DISABLED, "off" },
{ IPMIP_SYSVAR_MODE_DISABLED, "no" },
{ 0, 0 }
};
/**/
op_val = ipmip_sysvar_cmd_str_to_key(ops, buf);
if (op_val != -1)
defval = op_val;
ipcom_free(buf);
}
return defval;
}
/*
*===========================================================================
* ipmip_sysvar_key
*===========================================================================
* Description: Parse a sysvar key and map it to an option
* Parameters: defval - Default value
* map - Key options
* format - Format string
* ... - Optional arguments
* Returns: -1 on failure; key value otherwise.
*
*/
IP_GLOBAL int
ipmip_sysvar_key(int defval,
Ipmip_sysvar_key_map_t *map,
const char *format,
/* args*/ ...)
{
va_list ap;
char *buf;
va_start(ap, format);
buf = ipmip_sysvar_get(format, ap);
va_end(ap);
/* Parse the value */
if (buf)
{
/**/
defval = ipmip_sysvar_cmd_str_to_key(map, buf);
ipcom_free(buf);
}
return defval;
}
/*
*===========================================================================
* ipmip_sysvar_bool
*===========================================================================
* Description: Parse and return a boolean value; A boolean value is either
* a numerical value, where != 0,enabled, enable, yes or true
* equals IP_TRUE, or 0, disabled, disable, no or false which equals
* IP_FALSE. If the system variable doesn't exist, the provided
* default value will be returned.
* Parameters: defval - The default value.
* format - Format string
* ... - Optional arguments
* Returns: The configuration value; IP_TRUE or IP_FALSE.
*
*/
IP_GLOBAL Ip_bool
ipmip_sysvar_bool(Ip_bool defval,
const char *format,
/* args*/ ...)
{
va_list ap;
char *buf;
va_start(ap, format);
buf = ipmip_sysvar_get(format, ap);
va_end(ap);
/* Parse the value */
if (buf)
{
int op_val = -1;
/**/
op_val = ipmip_sysvar_cmd_str_to_key(ipmip_sysvar_bool_ops, buf);
if (op_val != -1)
defval = op_val;
ipcom_free(buf);
}
return defval;
}
/*
*===========================================================================
* ipmip_sysvar_ulong
*===========================================================================
* Description: Parse and return an unsigned long value; If the system variable
* doesn't exist, the provided default value will be returned.
* Parameters: defval - The default value.
* format - Format string
* ... - Optional arguments
* Returns: The configuration integer value
*
*/
IP_GLOBAL unsigned long
ipmip_sysvar_ulong(unsigned long defval,
const char *format,
/* args*/ ...)
{
va_list ap;
char *buf;
va_start(ap, format);
buf = ipmip_sysvar_get(format, ap);
va_end(ap);
/* Parse the value */
if (buf)
{
/* Non zero? */
defval = ipcom_strtoul(buf, IP_NULL, 0);
ipcom_free(buf);
}
return defval;
}
/*
*===========================================================================
* ipmip_sysvar_u32
*===========================================================================
* Description: Parse and return an u32; If the system variable
* doesn't exist, the provided default value will be returned.
* Parameters: defval - The default value.
* format - Format string
* ... - Optional arguments
* Returns: The configuration integer value
*
*/
IP_GLOBAL Ip_u32
ipmip_sysvar_u32(Ip_u32 defval,
const char *format,
/* args*/ ...)
{
va_list ap;
char *buf;
va_start(ap, format);
buf = ipmip_sysvar_get(format, ap);
va_end(ap);
/* Parse the value */
if (buf)
{
/* Non zero? */
defval = (Ip_u32)ipcom_strtoul(buf, IP_NULL, 0);
ipcom_free(buf);
}
return defval;
}
/*
*===========================================================================
* ipmip_sysvar_ushort
*===========================================================================
* Description: Parse and return an unsigned long value; If the system variable
* doesn't exist, the provided default value will be returned.
* Parameters: defval - The default value.
* format - Format string
* ... - Optional arguments
* Returns: The configuration integer value
*
*/
IP_GLOBAL unsigned short
ipmip_sysvar_ushort(unsigned short defval,
const char *format,
/* args*/ ...)
{
va_list ap;
char *buf;
va_start(ap, format);
buf = ipmip_sysvar_get(format, ap);
va_end(ap);
/* Parse the value */
if (buf)
{
/* Non zero? */
defval = (unsigned short)ipcom_strtoul(buf, IP_NULL, 0);
ipcom_free(buf);
}
return defval;
}
/*
*===========================================================================
* ipmip_sysvar_long
*===========================================================================
* Description: Parse and return a long value; If the system variable
* doesn't exist, the provided default value will be returned.
* Parameters: defval - The default value.
* format - Format string
* ... - Optional arguments
* Returns: The configuration integer value
*
*/
IP_GLOBAL long
ipmip_sysvar_long(long defval,
const char *format,
/* args*/ ...)
{
va_list ap;
char *buf;
va_start(ap, format);
buf = ipmip_sysvar_get(format, ap);
va_end(ap);
/* Parse the value */
if (buf)
{
/* Non zero? */
defval = ipcom_strtol(buf, IP_NULL, 0);
ipcom_free(buf);
}
return defval;
}
/*
*===========================================================================
* ipmip_sysvar_long
*===========================================================================
* Description: Parse and return a long value; If the system variable
* doesn't exist, the provided default value will be returned.
* Parameters: defval - The default value.
* format - Format string
* ... - Optional arguments
* Returns: The configuration integer value
*
*/
IP_GLOBAL short
ipmip_sysvar_short(short defval,
const char *format,
/* args*/ ...)
{
va_list ap;
char *buf;
va_start(ap, format);
buf = ipmip_sysvar_get(format, ap);
va_end(ap);
/* Parse the value */
if (buf)
{
/* Non zero? */
defval = (short)ipcom_strtol(buf, IP_NULL, 0);
ipcom_free(buf);
}
return defval;
}
/*
*===========================================================================
* ipmip_sysvar_strlist
*===========================================================================
* Description: Parse and return a string array of the format
* <num entries><length><string><length><string> .. where length
* is 1 byte, and string is a zero terminated; the length includes
* the zero termination and the length byte; the array is
* terminated by a length byte with value 0. The returned data is
* dynamically allocated and must be freed by the caller. num
* entries is a one byte entry indicating the number of strings
* stored in the array.
* Parameters: format - Format string
* ... - format arguments
* Returns: The strlist array
*
*/
IP_GLOBAL Ip_u8 *
ipmip_sysvar_strlist(const char *format,
/* args*/ ...)
{
va_list ap;
char *buf;
va_start(ap, format);
buf = ipmip_sysvar_get(format, ap);
va_end(ap);
/* Parse the value */
if (buf)
{
Ip_u8 *dblock = ipmip_util_explode(buf);
ipcom_free(buf);
if (dblock)
{
if (*dblock != 0)
return dblock;
ipcom_free(dblock);
}
}
return IP_NULL;
}
/*
*===========================================================================
* ipmip_sysvar_strarr
*===========================================================================
* Description: Parse and return a string array with the last item set as
* IP_NULL.
* Parameters: format - Format string
* ... - format arguments
* Returns: The string pointer array
*
*/
IP_GLOBAL char **
ipmip_sysvar_strarr(const char *format,
/* args*/ ...)
{
va_list ap;
char *buf;
va_start(ap, format);
buf = ipmip_sysvar_get(format, ap);
va_end(ap);
/* Parse the value */
if (buf)
{
char **arr = ipmip_util_strarr(buf, IP_NULL);
ipcom_free(buf);
return arr;
}
return IP_NULL;
}
/*
*===========================================================================
* ipmip_sysvar_array
*===========================================================================
* Description: Parse and return an array of configuration options where each
* string will be matched to a configuration value and returned
* in a dynamically allocated integer array terminated with the
* value 0xffffffff. The integer array must be freed by the caller.
* Parameters: ops - Options for parsing the strings
* format - Format string
* ... - Optional arguments
* Returns: The integer array.
*
*/
IP_GLOBAL int *
ipmip_sysvar_array(Ipmip_sysvar_key_map_t *ops,
const char *format,
/* args*/ ...)
{
va_list ap;
char *buf;
va_start(ap, format);
buf = ipmip_sysvar_get(format, ap);
va_end(ap);
/* Parse the value */
if (buf)
{
Ip_u8 *dblock = ipmip_util_explode(buf);
Ip_u8 nelem;
Ip_u8 nsize;
Ip_u8 *sptr;
int *iarr;
int idx;
ipcom_free(buf);
if (dblock == IP_NULL)
return IP_NULL;
nelem = *dblock;
sptr = dblock + 1;
if (nelem == 0)
{
ipcom_free(dblock);
return IP_NULL;
}
iarr = ipcom_malloc((nelem + 1) * sizeof(int));
if (iarr == IP_NULL)
{
ipcom_free(dblock);
return IP_NULL;
}
idx = 0;
while ((nsize = *sptr) != 0)
{
int opt_val = ipmip_sysvar_cmd_str_to_key(ops, (char *)(sptr + 1));
if (opt_val != -1)
{
iarr[idx++] = opt_val;
}
sptr += nsize;
}
/* Terminate */
iarr[idx] = -1;
ipcom_free(dblock);
return iarr;
}
return IP_NULL;
}
#ifdef IPMIP_USE_INET
/*
*===========================================================================
* ipmip_sysvar_inet
*===========================================================================
* Description: Read a sysvar variable and convert it to an IPv4 address and
* prefix. If plen is specified; it will look for /<num> prefix
* indicator, if not available, prefix will be 32.
* Parameters: defip - Default value
* addr - The addr to store the result in.
* plen - Prefix length.[may be NULL]
* format - Format string
* ... - Arguments.
* Returns: IP_TRUE on success; IP_FALSE otherwise
*
*/
IP_GLOBAL Ip_bool
ipmip_sysvar_inet(Ip_u32 defip,
Ip_u32 *addr,
Ip_u32 *plen,
const char *format,
/* args*/ ...)
{
char *buf;
va_list ap;
Ip_bool success = IP_FALSE;
va_start(ap, format);
buf = ipmip_sysvar_get(format, ap);
va_end(ap);
/* Set default value */
*addr = defip;
/* Grab the sysvar */
if (buf)
{
success = ipmip_util_inet(buf, addr, plen);
ipcom_free(buf);
}
return success;
}
#endif
#ifdef IPMIP_USE_INET6
/*
*===========================================================================
* ipmip_sysvar_inet6
*===========================================================================
* Description: Read a sysvar variable and convert it to an IPv6 address and
* prefix. If plen is specified; it will look for /<num> prefix
* indicator, if not available, prefix will be 32.
* Parameters: defip - Default value
* addr - The addr to store the result in.
* plen - Prefix length.[may be NULL]
* format - Format string
* ... - Arguments.
* Returns: IP_TRUE on success; IP_FALSE otherwise
*
*/
IP_GLOBAL Ip_bool
ipmip_sysvar_inet6(const struct Ip_in6_addr *defin6,
struct Ip_in6_addr *addr6,
Ip_u8 *plen,
const char *format,
/* args*/ ...)
{
char *buf;
va_list ap;
Ip_bool success = IP_FALSE;
va_start(ap, format);
buf = ipmip_sysvar_get(format, ap);
va_end(ap);
/* Set default value */
IPMIP_IP6_SET_ADDR(addr6, defin6? defin6 : &ip_in6addr_any);
/* Grab the sysvar */
if (buf)
{
success = ipmip_util_inet6(buf, addr6, plen);
ipcom_free(buf);
}
return success;
}
#endif
/*
*===========================================================================
* ipmip_sysvar_foreach
*===========================================================================
* Description: Iterate and expand tables in sysvar.
* Parameters: cb_func - The sysvar foreach callback
* cookie - Opaque data.
* format - The format key
* ... - Arguments
* Returns:
*
*/
IP_GLOBAL void
ipmip_sysvar_foreach(Ipmip_proc_t *proc,
Ipmip_sysvar_foreach_t cb_func,
void *cookie,
const char *format,
/* args*/ ...)
{
Ipmip_sysvar_foreach_cbinfo_t data;
va_list ap;
char *buf;
va_start(ap, format);
buf = ipmip_util_vstrdup(format, ap);
va_end(ap);
/* Overflow or error? */
if (buf == IP_NULL)
goto done_out;
/* Calculate the base length and set up the cb information */
data.baselen = ipcom_strlen(buf);
if (buf[data.baselen - 1] == '*')
data.baselen--;
data.cb_func = cb_func;
data.opaque = cookie;
data.proc = proc;
ipcom_sysvar_for_each(buf,
(Ipcom_sysvar_for_each)ipmip_sysvar_foreach_parse,
&data);
done_out:
if (buf)
ipcom_free(buf);
}
/*
*===========================================================================
* ipmip_sysvar_foreach
*===========================================================================
* Description: Iterate and expand tables in sysvar.
* Parameters: cb_func - The sysvar foreach callback
* cookie - Opaque data.
* format - The format key
* ... - Arguments
* Returns:
*
*/
IP_GLOBAL void
ipmip_sysvar_foreach_ext(struct Ipmip_context *ctx,
Ipmip_proc_t *proc,
Ipmip_sysvar_foreach_ext_t cb_func,
void *cookie,
const char *format,
/* args*/ ...)
{
Ipmip_sysvar_foreach_cbinfo_ext_t data;
va_list ap;
char *buf;
va_start(ap, format);
buf = ipmip_util_vstrdup(format, ap);
va_end(ap);
/* Overflow or error? */
if (buf == IP_NULL)
goto done_out;
/* Calculate the base length and set up the cb information */
data.baselen = ipcom_strlen(buf);
if (buf[data.baselen - 1] == '*')
data.baselen--;
data.cb_func = cb_func;
data.opaque = cookie;
data.proc = proc;
data.ctx = ctx;
ipcom_sysvar_for_each(buf,
(Ipcom_sysvar_for_each)ipmip_sysvar_foreach_ext_parse,
&data);
done_out:
if (buf)
ipcom_free(buf);
}
/*
****************************************************************************
* 11 PUBLIC FUNCTIONS
****************************************************************************
*/
/*
****************************************************************************
* END OF FILE
****************************************************************************
*/