自主协议库编译通过
This commit is contained in:
889
mmslib/util/cfg_util.c
Normal file
889
mmslib/util/cfg_util.c
Normal file
@@ -0,0 +1,889 @@
|
||||
/************************************************************************/
|
||||
/* SISCO SOFTWARE MODULE HEADER *****************************************/
|
||||
/************************************************************************/
|
||||
/* (c) Copyright Systems Integration Specialists Company, Inc., */
|
||||
/* 1991-2006, All Rights Reserved */
|
||||
/* */
|
||||
/* MODULE NAME : cfg_util.c */
|
||||
/* PRODUCT(S) : */
|
||||
/* */
|
||||
/* MODULE DESCRIPTION : */
|
||||
/* */
|
||||
/* GLOBAL FUNCTIONS DEFINED IN THIS MODULE : */
|
||||
/* */
|
||||
/* MODIFICATION LOG : */
|
||||
/* Date Who Rev Comments */
|
||||
/* -------- --- ------ ------------------------------------------- */
|
||||
/* 02/07/06 EJV 18 cfg_special_char_str: added '$'. */
|
||||
/* 02/20/03 JRB 17 Del PSOS code. */
|
||||
/* 11/29/01 EJV 16 Del code for old LATT, XENIX, ultrix, RMX86. */
|
||||
/* Removed call to strcasecmp (sun) */
|
||||
/* 10/18/01 JRB 15 Add str_util.h (for strcmpi, etc. protos) */
|
||||
/* 01/19/01 EJV 14 Moved strcmpi,stricmp,strnicmp to str_util.c */
|
||||
/* 11/07/00 JRB 13 Del QNX from ifdef. It supports stricmp, etc.*/
|
||||
/* 04/28/00 JRB 12 Lint cleanup */
|
||||
/* 09/13/99 MDE 11 Added SD_CONST modifiers */
|
||||
/* 04/14/99 MDE 10 Replaced SYSTEM_SEL with compiler defines */
|
||||
/* 10/08/98 MDE 09 Migrated to updated SLOG interface */
|
||||
/* 08/24/98 EJV 08 Added __hpux to str* cmp functions */
|
||||
/* 08/06/98 JRB 07 Added cfg_get_octet_string function. */
|
||||
/* 06/15/98 MDE 06 Changes to allow compile under C++ */
|
||||
/* 05/22/98 EJV 05 added _AIX, sun, and __alpha to */
|
||||
/* stricmp, strcmpi, strnicmp functions */
|
||||
/* 04/03/98 RKR 04 added stricmp, strcmpi, strnicmp */
|
||||
/* 12/22/97 JRB 03 Clean up PSOS code. */
|
||||
/* 12/04/97 KCR 02 Added cfg_goto_keyword function */
|
||||
/* 11/05/97 MDE 01 Added VXWORKS support */
|
||||
/* 04/02/97 DTL 7.00 MMSEASE 7.0 release. See MODL70.DOC for */
|
||||
/* history. */
|
||||
/************************************************************************/
|
||||
|
||||
#include "glbtypes.h"
|
||||
#include "sysincs.h"
|
||||
#include "mem_chk.h"
|
||||
#include "cfg_util.h"
|
||||
#include "cfglog.h"
|
||||
#include "str_util.h"
|
||||
#include <ctype.h>
|
||||
|
||||
#include "slog.h"
|
||||
|
||||
/************************************************************************/
|
||||
|
||||
/* #define DEBUG */
|
||||
|
||||
/************************************************************************/
|
||||
/* For debug version, use a static pointer to avoid duplication of */
|
||||
/* __FILE__ strings. */
|
||||
|
||||
#ifdef DEBUG_SISCO
|
||||
SD_CONST static ST_CHAR *SD_CONST thisFileName = __FILE__;
|
||||
#endif
|
||||
|
||||
/************************************************************************/
|
||||
|
||||
/* Externally visable variables */
|
||||
ST_CHAR *cfg_line_buf; /* File line read buffer */
|
||||
ST_INT cfg_curr_line; /* Current line number */
|
||||
ST_INT cfg_line_offset; /* Offset into cfg_line_buf */
|
||||
|
||||
ST_CHAR *cfg_special_char_str;
|
||||
ST_CHAR *cfg_end_of_rval_str;
|
||||
|
||||
ST_BOOLEAN config_stop;
|
||||
ST_RET config_err;
|
||||
ST_BOOLEAN config_eof;
|
||||
|
||||
ST_UINT cfg_log_mask;
|
||||
#ifdef DEBUG_SISCO
|
||||
SD_CONST ST_CHAR *SD_CONST _cfg_err_logstr = "CFG_LOG_ERR";
|
||||
SD_CONST ST_CHAR *SD_CONST _cfg_flow_logstr = "CFG_LOG_FLOW";
|
||||
#endif
|
||||
|
||||
/************************************************************************/
|
||||
|
||||
/* Internal definitions */
|
||||
#define MAX_STRING_LEN 256
|
||||
#define LINE_BUF_SIZE 256
|
||||
|
||||
ST_INT cfg_max_string_len;
|
||||
ST_INT cfg_line_buf_size;
|
||||
ST_INT cfg_max_rval_len;
|
||||
|
||||
#define MAX_CONFIG_NEST 10
|
||||
|
||||
/* Internal variables */
|
||||
static ST_CHAR *cfg_string_buf;
|
||||
static struct cfg_kw_el *curr_table;
|
||||
static ST_BOOLEAN cfg_need_new_line;
|
||||
static FILE *config_fptr; /* Configuration file handle */
|
||||
|
||||
/* Keyword table stack control */
|
||||
static ST_INT num_on_stack;
|
||||
static struct cfg_kw_el **cfg_kw_stack;
|
||||
|
||||
|
||||
/* Internal funtions */
|
||||
static struct cfg_kw_el *cfg_lookup_keyword (struct cfg_kw_el *, ST_CHAR *);
|
||||
static ST_RET cfg_get_next_keyword (FILE *);
|
||||
static ST_CHAR *cfg_get_rval (ST_VOID);
|
||||
static ST_RET cfg_end_of_rval (ST_CHAR c);
|
||||
static ST_RET cfg_special_char (ST_CHAR c);
|
||||
|
||||
/************************************************************************/
|
||||
/************************************************************************/
|
||||
/************************************************************************/
|
||||
/* cfg_process_file */
|
||||
/************************************************************************/
|
||||
|
||||
ST_RET cfg_process_file (ST_CHAR *fileName, struct cfg_kw_el *root_kw_tbl)
|
||||
{
|
||||
ST_RET ret;
|
||||
|
||||
if (cfg_special_char_str == NULL)
|
||||
cfg_special_char_str = ":\\/-_ .{}[]<>@,()$";
|
||||
|
||||
if (cfg_end_of_rval_str == NULL)
|
||||
cfg_end_of_rval_str = "|";
|
||||
|
||||
if (cfg_max_string_len == 0)
|
||||
cfg_max_string_len = MAX_STRING_LEN;
|
||||
|
||||
if (cfg_line_buf_size == 0)
|
||||
cfg_line_buf_size = LINE_BUF_SIZE;
|
||||
|
||||
if (cfg_max_rval_len == 0)
|
||||
cfg_max_rval_len = MAX_RVAL_LEN;
|
||||
|
||||
/* Open the configuration file */
|
||||
if ((config_fptr = fopen (fileName,"r"))==NULL)
|
||||
{
|
||||
CFG_LOG_ERR1 ("Config File (%s) Open Error",fileName);
|
||||
return (SD_FAILURE);
|
||||
}
|
||||
|
||||
CFG_LOG_FLOW1 ("Config File (%s) Opened OK",fileName);
|
||||
|
||||
/* If a previous call to the function ended in error there may be some */
|
||||
/* old keyword table pushed on the stack. The keywords table stack is */
|
||||
/* initialized to zero to process the current configuration file */
|
||||
|
||||
num_on_stack = 0;
|
||||
|
||||
/* Allocate required buffers */
|
||||
|
||||
cfg_line_buf = (ST_CHAR *) chk_calloc (cfg_line_buf_size,
|
||||
sizeof(ST_CHAR));
|
||||
cfg_string_buf = (ST_CHAR *) chk_calloc (cfg_max_string_len+1,
|
||||
sizeof(ST_CHAR));
|
||||
cfg_kw_stack = (struct cfg_kw_el **) chk_calloc (MAX_CONFIG_NEST,
|
||||
sizeof (struct cfg_kw_el *));
|
||||
|
||||
/* Start with the ROOT keyword table */
|
||||
|
||||
cfg_tbl_push (root_kw_tbl);
|
||||
|
||||
/* Process the configuration file */
|
||||
|
||||
cfg_need_new_line = SD_TRUE;
|
||||
cfg_line_offset = 0;
|
||||
cfg_curr_line = 0;
|
||||
config_err = SD_FALSE;
|
||||
config_stop = SD_FALSE;
|
||||
config_eof = SD_FAILURE;
|
||||
|
||||
/* Process keywords while not done and no error is detected */
|
||||
|
||||
while ( ( config_stop == SD_FALSE ) && ( config_err == SD_FALSE ) )
|
||||
{
|
||||
if ( cfg_get_next_keyword( config_fptr ) )
|
||||
break;
|
||||
}
|
||||
|
||||
/* All done, see if it went OK */
|
||||
|
||||
if ( ( config_stop == SD_TRUE ) && ( config_err == SD_FALSE ) )
|
||||
{
|
||||
CFG_LOG_CFLOW0 ("Config File Read OK");
|
||||
ret = SD_SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
CFG_LOG_ERR3 ("Config Error, Line %d, \"%s\", Column %d",
|
||||
cfg_curr_line, cfg_line_buf, cfg_line_offset);
|
||||
|
||||
ret = SD_FAILURE;
|
||||
}
|
||||
|
||||
/* Free allocated buffers */
|
||||
chk_free (cfg_line_buf);
|
||||
chk_free (cfg_string_buf);
|
||||
chk_free (cfg_kw_stack);
|
||||
|
||||
/* Close the file so the calling program can reopen it if necessary. */
|
||||
|
||||
fclose( config_fptr );
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
/************************************************************************/
|
||||
/************************************************************************/
|
||||
/* cfg_get_next_keyword */
|
||||
/************************************************************************/
|
||||
/* This function is used to get the next keyword */
|
||||
|
||||
static ST_RET cfg_get_next_keyword (FILE *fptr)
|
||||
{
|
||||
struct cfg_kw_el *ptr;
|
||||
ST_INT i;
|
||||
ST_CHAR c;
|
||||
|
||||
/* Look for 'yyy =' string */
|
||||
|
||||
while (SD_TRUE) /* While looking for the next word */
|
||||
{
|
||||
if (cfg_need_new_line)
|
||||
{
|
||||
if ( fgets( cfg_line_buf, cfg_line_buf_size - 1, fptr ) == NULL )
|
||||
{
|
||||
CFG_LOG_CFLOW0 ("No More Keywords : End Of File");
|
||||
|
||||
/* The following piece of logic exists to allow the state functions to */
|
||||
/* declare when it is ok for the file to be out of keywords. If a user */
|
||||
/* state function set 'config_eof == SD_SUCCESS' then config_stop is set */
|
||||
/* to true when ENDFILE is encountered. */
|
||||
|
||||
if ( config_eof == SD_SUCCESS )
|
||||
{
|
||||
config_stop = SD_TRUE;
|
||||
}
|
||||
return( SD_FAILURE );
|
||||
}
|
||||
|
||||
/* Wack the \n */
|
||||
for (i = 0; i < cfg_line_buf_size; ++i)
|
||||
{
|
||||
if (cfg_line_buf[i] == '\n')
|
||||
{
|
||||
cfg_line_buf[i] = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
cfg_line_offset = 0; /* Offset is 0 for new line */
|
||||
++cfg_curr_line;
|
||||
if (cfg_line_buf[0] == '#')
|
||||
continue; /* Discard comment lines */
|
||||
|
||||
cfg_need_new_line = SD_FALSE; /* Got a new line */
|
||||
}
|
||||
|
||||
/* We now have a line to work on, with cfg_line_offset the 1st char */
|
||||
/* Extract the keyword from the string (alpha numeric characters) */
|
||||
/* '=' means end of rval */
|
||||
/* 0 is end of line */
|
||||
|
||||
i = 0;
|
||||
c = cfg_line_buf[cfg_line_offset++];
|
||||
while (c && c != '#' && /* End of line or comment start */
|
||||
c != '=' && /* end of keyword */
|
||||
c != '|' &&
|
||||
i < cfg_max_string_len)
|
||||
{
|
||||
if (c != ' ' && c != '\t') /* Ignore spaces and tabs */
|
||||
{
|
||||
cfg_string_buf[i] = c;
|
||||
++i;
|
||||
}
|
||||
c = cfg_line_buf[cfg_line_offset++];
|
||||
}
|
||||
|
||||
if (i >= cfg_max_string_len)
|
||||
{
|
||||
CFG_LOG_ERR1 ("Error : Line %d too long", cfg_curr_line);
|
||||
return (SD_FAILURE);
|
||||
}
|
||||
|
||||
if (c == '#' || !c) /* See if we need a new line next time */
|
||||
cfg_need_new_line = SD_TRUE;
|
||||
|
||||
/* i is the index to the char position that terminated the scan */
|
||||
cfg_string_buf[i]=0x0; /* NULL terminate the keyword */
|
||||
|
||||
/* if we have a keyword, then search look it up in the currently active */
|
||||
/* keyword table and execute the selected function */
|
||||
|
||||
if (strlen (cfg_string_buf))
|
||||
{ /* Find the keyword */
|
||||
if ((ptr = cfg_lookup_keyword (curr_table, cfg_string_buf)) != NULL)
|
||||
{
|
||||
CFG_LOG_CFLOW1 ("Keyword : %s",cfg_string_buf);
|
||||
(*ptr->extract)();
|
||||
break;
|
||||
}
|
||||
else /* invalid keyword */
|
||||
{
|
||||
CFG_LOG_ERR1 ("Unknown Keyword : %s",cfg_string_buf);
|
||||
return (SD_FAILURE);
|
||||
}
|
||||
}
|
||||
} /* While SD_TRUE */
|
||||
|
||||
return(SD_SUCCESS);
|
||||
}
|
||||
|
||||
/************************************************************************/
|
||||
/* cfg_get_rval() */
|
||||
/************************************************************************/
|
||||
|
||||
static ST_CHAR *cfg_get_rval(ST_VOID)
|
||||
{
|
||||
ST_INT i;
|
||||
ST_CHAR c;
|
||||
|
||||
cfg_string_buf[0]=0x0;
|
||||
|
||||
/* Now get the rval (value). */
|
||||
/* search for 0 to note end of line */
|
||||
|
||||
i = 0;
|
||||
c = cfg_line_buf[cfg_line_offset++];
|
||||
|
||||
/* First strip leading white space (' ', '\t') */
|
||||
while (c == ' ' || c == '\t')
|
||||
c = cfg_line_buf[cfg_line_offset++];
|
||||
|
||||
while (c &&
|
||||
c != '#' &&
|
||||
!cfg_end_of_rval (c) &&
|
||||
i < cfg_max_rval_len-1)
|
||||
{
|
||||
if (isalnum (c) || cfg_special_char (c))
|
||||
{
|
||||
cfg_string_buf[i] = c;
|
||||
++i;
|
||||
}
|
||||
c = cfg_line_buf[cfg_line_offset++];
|
||||
}
|
||||
|
||||
if (c == '#' || !c) /* See if we need a new line next time */
|
||||
cfg_need_new_line = SD_TRUE;
|
||||
|
||||
/* Strip trailing spaces and tabs */
|
||||
while (i && (cfg_string_buf[i-1] == ' ' ||
|
||||
cfg_string_buf[i-1] == '\t'))
|
||||
i--;
|
||||
|
||||
/* Null terminate the string */
|
||||
cfg_string_buf[i] = 0x0;
|
||||
|
||||
if (!strlen (cfg_string_buf))
|
||||
{
|
||||
CFG_LOG_ERR2 ("Bad rval, line #%d \"%s\"",cfg_curr_line,cfg_line_buf);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
CFG_LOG_CFLOW1 ("Rval : '%s'",cfg_string_buf);
|
||||
return (cfg_string_buf);
|
||||
}
|
||||
|
||||
/************************************************************************/
|
||||
/* cfg_lookup_keyword */
|
||||
/************************************************************************/
|
||||
|
||||
static struct cfg_kw_el *cfg_lookup_keyword(struct cfg_kw_el *tbl_ptr,
|
||||
ST_CHAR *name)
|
||||
{
|
||||
ST_INT i;
|
||||
struct cfg_kw_el *ret = NULL;
|
||||
|
||||
for (i = 0; i < MAX_NUM_KEYWORDS; ++i)
|
||||
{
|
||||
if (tbl_ptr[i].extract == NULL) /* End of table */
|
||||
break;
|
||||
else if (!strcmpi (name, tbl_ptr[i].name))
|
||||
{ /* we have a match */
|
||||
if (tbl_ptr[i].valid !=NULL) /* Want to validate? */
|
||||
{
|
||||
if ((*tbl_ptr[i].valid)())
|
||||
ret = &tbl_ptr[i];
|
||||
}
|
||||
else
|
||||
ret = &tbl_ptr[i];
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return(ret);
|
||||
}
|
||||
|
||||
/************************************************************************/
|
||||
/* cfg_end_of_rval */
|
||||
/************************************************************************/
|
||||
/* CONFIG calls back to this function while looking the rval over */
|
||||
/* If this function returns SD_TRUE, CONFIG will assume that the */
|
||||
/* character is a keyword/rval pair seperator */
|
||||
/* Used to allow multiple pairs per line */
|
||||
|
||||
|
||||
static ST_RET cfg_end_of_rval (ST_CHAR c)
|
||||
{
|
||||
ST_INT i;
|
||||
ST_INT str_len;
|
||||
|
||||
str_len = strlen (cfg_end_of_rval_str);
|
||||
for (i = 0; i < str_len; ++i)
|
||||
{
|
||||
if (c == cfg_end_of_rval_str[i])
|
||||
return (SD_TRUE);
|
||||
}
|
||||
return (SD_FALSE);
|
||||
}
|
||||
|
||||
/************************************************************************/
|
||||
/* cfg_special_char */
|
||||
/************************************************************************/
|
||||
|
||||
static ST_RET cfg_special_char (ST_CHAR c)
|
||||
{
|
||||
ST_INT i;
|
||||
ST_INT str_len;
|
||||
|
||||
str_len = strlen (cfg_special_char_str);
|
||||
for (i = 0; i < str_len; ++i)
|
||||
{
|
||||
if (c == cfg_special_char_str[i])
|
||||
return (SD_TRUE);
|
||||
}
|
||||
|
||||
return (SD_FALSE);
|
||||
}
|
||||
|
||||
|
||||
/************************************************************************/
|
||||
/************************************************************************/
|
||||
/************************************************************************/
|
||||
/* cfg_tbl_push (new_table) */
|
||||
/************************************************************************/
|
||||
|
||||
ST_RET cfg_tbl_push (struct cfg_kw_el *new_table)
|
||||
{
|
||||
if (num_on_stack >= MAX_CONFIG_NEST)
|
||||
{
|
||||
CFG_LOG_ERR0 ("Too many pushes - configuration nesting exceeded");
|
||||
config_stop = SD_TRUE;
|
||||
config_err = CFG_UTIL_ERR;
|
||||
return (SD_FAILURE);
|
||||
}
|
||||
|
||||
cfg_kw_stack[num_on_stack] = new_table;
|
||||
++num_on_stack;
|
||||
curr_table = new_table;
|
||||
return (SD_SUCCESS);
|
||||
}
|
||||
|
||||
/************************************************************************/
|
||||
/* cfg_tbl_pop (num_to_pop) */
|
||||
/************************************************************************/
|
||||
|
||||
ST_RET cfg_tbl_pop (ST_INT num_to_pop)
|
||||
{
|
||||
if ((num_on_stack-num_to_pop-1)<0)
|
||||
{
|
||||
CFG_LOG_ERR0 ("Too many pops off configuration stack");
|
||||
config_stop = SD_TRUE;
|
||||
config_err = CFG_UTIL_ERR;
|
||||
return (SD_FAILURE);
|
||||
}
|
||||
num_on_stack -= num_to_pop;
|
||||
curr_table = cfg_kw_stack[num_on_stack-1];
|
||||
return (SD_SUCCESS);
|
||||
}
|
||||
|
||||
/************************************************************************/
|
||||
/* cfg_get_short */
|
||||
/************************************************************************/
|
||||
|
||||
ST_RET cfg_get_short (ST_INT16 *out_ptr)
|
||||
{
|
||||
ST_INT d;
|
||||
ST_INT16 ret;
|
||||
|
||||
ret = cfg_get_value ("%d", &d);
|
||||
if (!ret)
|
||||
*out_ptr = (ST_INT16) d;
|
||||
return (ret);
|
||||
}
|
||||
|
||||
/************************************************************************/
|
||||
/* cfg_get_ushort */
|
||||
/************************************************************************/
|
||||
|
||||
ST_RET cfg_get_ushort (ST_UINT16 *out_ptr)
|
||||
{
|
||||
ST_UINT d;
|
||||
ST_RET ret;
|
||||
|
||||
ret = cfg_get_value ("%u", &d);
|
||||
if (!ret)
|
||||
*out_ptr = (ST_UINT16) d;
|
||||
return (ret);
|
||||
}
|
||||
|
||||
/************************************************************************/
|
||||
/* cfg_get_int */
|
||||
/************************************************************************/
|
||||
|
||||
ST_RET cfg_get_int (ST_INT *out_ptr)
|
||||
{
|
||||
ST_INT d;
|
||||
ST_RET ret;
|
||||
|
||||
ret = cfg_get_value ("%d", &d);
|
||||
if (!ret)
|
||||
*out_ptr = d;
|
||||
return (ret);
|
||||
}
|
||||
|
||||
/************************************************************************/
|
||||
/* cfg_get_uint */
|
||||
/************************************************************************/
|
||||
|
||||
ST_RET cfg_get_uint (ST_UINT *out_ptr)
|
||||
{
|
||||
ST_UINT d;
|
||||
ST_RET ret;
|
||||
|
||||
ret = cfg_get_value ("%u", &d);
|
||||
if (!ret)
|
||||
*out_ptr = d;
|
||||
return (ret);
|
||||
}
|
||||
|
||||
/************************************************************************/
|
||||
/* cfg_get_long */
|
||||
/************************************************************************/
|
||||
|
||||
ST_RET cfg_get_long (ST_LONG *out_ptr)
|
||||
{
|
||||
return (cfg_get_value ("%ld", out_ptr));
|
||||
}
|
||||
|
||||
/************************************************************************/
|
||||
/* cfg_get_ulong */
|
||||
/************************************************************************/
|
||||
|
||||
ST_RET cfg_get_ulong (ST_ULONG *out_ptr)
|
||||
{
|
||||
return (cfg_get_value ("%lu", out_ptr));
|
||||
}
|
||||
|
||||
|
||||
/************************************************************************/
|
||||
/* cfg_get_double */
|
||||
/************************************************************************/
|
||||
|
||||
ST_RET cfg_get_double (ST_DOUBLE *out_ptr)
|
||||
{
|
||||
return (cfg_get_value ("%lf", out_ptr));
|
||||
}
|
||||
|
||||
|
||||
/************************************************************************/
|
||||
/* cfg_get_hex_ushort */
|
||||
/************************************************************************/
|
||||
|
||||
ST_RET cfg_get_hex_ushort (ST_UINT16 *out_ptr)
|
||||
{
|
||||
ST_UINT d;
|
||||
ST_RET ret;
|
||||
|
||||
ret = cfg_get_value ("%x", &d);
|
||||
if (!ret)
|
||||
*out_ptr = (ST_UINT16) d;
|
||||
return (ret);
|
||||
|
||||
/* return (cfg_get_value ("%x", out_ptr)); */
|
||||
}
|
||||
|
||||
/************************************************************************/
|
||||
/* cfg_get_hex_uint */
|
||||
/************************************************************************/
|
||||
|
||||
ST_RET cfg_get_hex_uint (ST_UINT *out_ptr)
|
||||
{
|
||||
ST_UINT d;
|
||||
ST_RET ret;
|
||||
|
||||
ret = cfg_get_value ("%x", &d);
|
||||
if (!ret)
|
||||
*out_ptr = d;
|
||||
return (ret);
|
||||
|
||||
/* return (cfg_get_value ("%x", out_ptr)); */
|
||||
}
|
||||
|
||||
/************************************************************************/
|
||||
/* cfg_get_hex_ulong */
|
||||
/************************************************************************/
|
||||
|
||||
ST_RET cfg_get_hex_ulong (ST_ULONG *out_ptr)
|
||||
{
|
||||
return (cfg_get_value ("%lx", out_ptr));
|
||||
}
|
||||
|
||||
/************************************************************************/
|
||||
/* cfg_get_value */
|
||||
/************************************************************************/
|
||||
|
||||
ST_RET cfg_get_value (ST_CHAR *format_string, ST_VOID *out_ptr)
|
||||
{
|
||||
ST_CHAR *rval;
|
||||
|
||||
rval = cfg_get_rval (); /* get the rvalue string */
|
||||
if (!rval)
|
||||
{
|
||||
config_err = CFG_GET_RVAL_ERR;
|
||||
CFG_LOG_ERR0 ("Get Rval Error");
|
||||
}
|
||||
else
|
||||
{ /* Convert to desired data format*/
|
||||
if (!sscanf (rval,format_string,out_ptr))
|
||||
{
|
||||
config_err = CFG_CONVERT_ERR;
|
||||
CFG_LOG_ERR0 ("Data Conversion Error");
|
||||
}
|
||||
}
|
||||
|
||||
if (config_err) /* if error detected ... */
|
||||
{
|
||||
config_stop = SD_TRUE;
|
||||
return (SD_FAILURE);
|
||||
}
|
||||
|
||||
return (SD_SUCCESS);
|
||||
}
|
||||
|
||||
|
||||
/************************************************************************/
|
||||
/************************************************************************/
|
||||
/* *cfg_get_alloc_string */
|
||||
/************************************************************************/
|
||||
|
||||
ST_CHAR *cfg_get_alloc_string (ST_VOID)
|
||||
{
|
||||
ST_CHAR *ret_ptr;
|
||||
ST_CHAR *rval;
|
||||
|
||||
rval = cfg_get_rval (); /* get the rvalue string */
|
||||
if (!rval)
|
||||
{
|
||||
config_stop = SD_TRUE;
|
||||
config_err = CFG_GET_RVAL_ERR;
|
||||
CFG_LOG_ERR0 ("Get Rval Error");
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/* allocate storage for string */
|
||||
ret_ptr = (ST_CHAR *) chk_calloc (1,strlen (rval) +1);
|
||||
strcpy (ret_ptr,rval);
|
||||
return (ret_ptr);
|
||||
}
|
||||
|
||||
|
||||
/************************************************************************/
|
||||
/* *cfg_get_string_ptr */
|
||||
/************************************************************************/
|
||||
|
||||
ST_CHAR *cfg_get_string_ptr (ST_VOID)
|
||||
{
|
||||
ST_CHAR *rval;
|
||||
|
||||
rval = cfg_get_rval (); /* get the rvalue string */
|
||||
if (!rval)
|
||||
{
|
||||
config_stop = SD_TRUE;
|
||||
config_err = CFG_GET_RVAL_ERR;
|
||||
CFG_LOG_ERR0 ("Get Rval Error");
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
return (rval);
|
||||
}
|
||||
|
||||
/************************************************************************/
|
||||
/* cfg_get_octet_string */
|
||||
/************************************************************************/
|
||||
|
||||
ST_RET cfg_get_octet_string (ST_UCHAR *ostr, /* ptr to user's ostr */
|
||||
ST_UINT *len_out_ptr, /* addr of len var to be set */
|
||||
ST_UINT len_max) /* maximum len to allow. */
|
||||
{
|
||||
ST_UINT j;
|
||||
ST_INT digit;
|
||||
ST_BOOLEAN nibble; /* SD_TRUE if nibble read, SD_FALSE if whole byte read*/
|
||||
ST_CHAR *rval;
|
||||
|
||||
rval = cfg_get_rval (); /* get the rvalue string */
|
||||
if (!rval)
|
||||
{
|
||||
config_stop = SD_TRUE;
|
||||
config_err = CFG_GET_RVAL_ERR;
|
||||
CFG_LOG_ERR0 ("Get Rval Error");
|
||||
return (SD_FAILURE);
|
||||
}
|
||||
|
||||
j = 0;
|
||||
nibble = SD_FALSE;
|
||||
while (isxdigit (*rval)) /* get hex number */
|
||||
{
|
||||
if (j >= len_max)
|
||||
return (SD_FAILURE); /* Selector longer than allowed */
|
||||
|
||||
digit = *rval++; /* separate nibbles */
|
||||
digit = isdigit (digit) ? digit - '0' : 10 + (toupper (digit) - 'A');
|
||||
if (nibble)
|
||||
{
|
||||
nibble = SD_FALSE;
|
||||
ostr[j] = (ostr[j] | (ST_UCHAR) digit); /* set low */
|
||||
j++;
|
||||
|
||||
while (isspace (*rval) && *rval != '\n')
|
||||
++rval;
|
||||
}
|
||||
else
|
||||
{
|
||||
nibble = SD_TRUE;
|
||||
ostr[j] = (ST_UCHAR) digit << 4; /* set high byte */
|
||||
}
|
||||
}
|
||||
|
||||
if (nibble)
|
||||
{ /* Only got half of byte. */
|
||||
config_stop = SD_TRUE;
|
||||
config_err = CFG_CONVERT_ERR;
|
||||
CFG_LOG_ERR0 ("Incomplete byte in Octet string");
|
||||
return (SD_FAILURE);
|
||||
}
|
||||
|
||||
/* set selector length */
|
||||
*len_out_ptr = j;
|
||||
return (SD_SUCCESS);
|
||||
}
|
||||
|
||||
/************************************************************************/
|
||||
/* cfg_set_config_err */
|
||||
/************************************************************************/
|
||||
|
||||
ST_VOID cfg_set_config_err(ST_VOID)
|
||||
{
|
||||
config_err = SD_TRUE;
|
||||
}
|
||||
|
||||
/************************************************************************/
|
||||
/* cfg_set_endfile_ok */
|
||||
/************************************************************************/
|
||||
|
||||
ST_VOID cfg_set_endfile_ok(ST_VOID)
|
||||
{
|
||||
config_eof = SD_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/************************************************************************/
|
||||
/************************************************************************/
|
||||
/* cfg_goto_keyword */
|
||||
/************************************************************************/
|
||||
/* This function is used to skip over a section to the specified keyword*/
|
||||
|
||||
ST_RET cfg_goto_keyword (ST_CHAR *keyword)
|
||||
{
|
||||
ST_INT i, cfgStringLen, keywordLen;
|
||||
ST_CHAR c;
|
||||
|
||||
/* Look for 'yyy =' string */
|
||||
|
||||
keywordLen = strlen (keyword);
|
||||
while (SD_TRUE) /* While looking for the specified word */
|
||||
{
|
||||
if (cfg_need_new_line)
|
||||
{
|
||||
if ( fgets( cfg_line_buf, cfg_line_buf_size - 1, config_fptr ) == NULL )
|
||||
{
|
||||
CFG_LOG_CFLOW0 ("No More Keywords : End Of File");
|
||||
|
||||
/* The following piece of logic exists to allow the state functions to */
|
||||
/* declare when it is ok for the file to be out of keywords. If a user */
|
||||
/* state function set 'config_eof == SD_SUCCESS' then config_stop is set */
|
||||
/* to true when ENDFILE is encountered. */
|
||||
|
||||
if ( config_eof == SD_SUCCESS )
|
||||
{
|
||||
config_stop = SD_TRUE;
|
||||
}
|
||||
return( SD_FAILURE );
|
||||
}
|
||||
|
||||
/* Wack the \n */
|
||||
for (i = 0; i < cfg_line_buf_size; ++i)
|
||||
{
|
||||
if (cfg_line_buf[i] == '\n')
|
||||
{
|
||||
cfg_line_buf[i] = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
cfg_line_offset = 0; /* Offset is 0 for new line */
|
||||
++cfg_curr_line;
|
||||
if (cfg_line_buf[0] == '#')
|
||||
continue; /* Discard comment lines */
|
||||
|
||||
cfg_need_new_line = SD_FALSE; /* Got a new line */
|
||||
}
|
||||
|
||||
/* We now have a line to work on, with cfg_line_offset the 1st char */
|
||||
/* Extract the keyword from the string (alpha numeric characters) */
|
||||
/* '=' means end of rval */
|
||||
/* 0 is end of line */
|
||||
|
||||
i = 0;
|
||||
c = cfg_line_buf[cfg_line_offset++];
|
||||
while (c && c != '#' && /* End of line or comment start */
|
||||
c != '=' && /* end of keyword */
|
||||
c != '|' &&
|
||||
i < cfg_max_string_len)
|
||||
{
|
||||
if (c != ' ' && c != '\t') /* Ignore spaces and tabs */
|
||||
{
|
||||
cfg_string_buf[i] = c;
|
||||
++i;
|
||||
}
|
||||
c = cfg_line_buf[cfg_line_offset++];
|
||||
}
|
||||
|
||||
if (i >= cfg_max_string_len)
|
||||
{
|
||||
CFG_LOG_ERR1 ("Error : Line %d too long", cfg_curr_line);
|
||||
return (SD_FAILURE);
|
||||
}
|
||||
|
||||
if (c == '#' || !c) /* See if we need a new line next time */
|
||||
cfg_need_new_line = SD_TRUE;
|
||||
|
||||
/* i is the index to the char position that terminated the scan */
|
||||
cfg_string_buf[i]=0x0; /* NULL terminate the keyword */
|
||||
|
||||
/* if we have a keyword, then search look it up in the currently active */
|
||||
/* keyword table and execute the selected function */
|
||||
|
||||
if ((cfgStringLen = strlen (cfg_string_buf)) > 0)
|
||||
{ /* Find the keyword */
|
||||
if ((cfgStringLen == keywordLen) && !strcmpi (keyword, cfg_string_buf))
|
||||
break;
|
||||
else /* keyword not found */
|
||||
cfg_need_new_line = SD_TRUE;
|
||||
}
|
||||
} /* While SD_TRUE */
|
||||
|
||||
return(SD_SUCCESS);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user