You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
283 lines
6.0 KiB
283 lines
6.0 KiB
4 months ago
|
/*
|
||
|
* Copyright (c) Hisilicon Technologies Co., Ltd. 2020-2021. All rights reserved.
|
||
|
* Description: This file is for interpreting the configuration file.
|
||
|
* Author: Hisilicon
|
||
|
* Create: 2020-06-11
|
||
|
*/
|
||
|
|
||
|
#include "parse_config_file.h"
|
||
|
|
||
|
#include <string.h>
|
||
|
#include <stdio.h>
|
||
|
#include <ctype.h>
|
||
|
|
||
|
#include "td_type.h"
|
||
|
#include "securec.h"
|
||
|
|
||
|
#define COMMENT_CHARACTER '#'
|
||
|
#define LINE_SIZE 768
|
||
|
#define LINE_BUF_SIZE (LINE_SIZE + 2)
|
||
|
#define KEY_MAX_LEN (188 * 10)
|
||
|
|
||
|
static td_char g_avariables[MAX_VAR_NUM][MAX_VAR_NAME_LEN + 1];
|
||
|
static td_char g_avalues[MAX_VAR_NUM][MAX_VAR_VALUE_LEN + 1];
|
||
|
static td_u32 g_var_num = 0;
|
||
|
|
||
|
static td_void remove_trailing_chars(td_char *path, td_char c)
|
||
|
{
|
||
|
size_t len;
|
||
|
|
||
|
len = strlen(path);
|
||
|
|
||
|
while (len > 0 && path[len - 1] == c) {
|
||
|
path[--len] = '\0';
|
||
|
}
|
||
|
}
|
||
|
|
||
|
static td_s32 _get_key(td_char **key, td_char **linepos)
|
||
|
{
|
||
|
td_char *tmppos = TD_NULL;
|
||
|
|
||
|
if (key == TD_NULL || linepos == TD_NULL) {
|
||
|
return TD_FAILURE;
|
||
|
}
|
||
|
|
||
|
*key = *linepos;
|
||
|
tmppos = *linepos;
|
||
|
|
||
|
while (1) {
|
||
|
tmppos++;
|
||
|
|
||
|
if (tmppos[0] == '\0') {
|
||
|
return TD_FAILURE;
|
||
|
}
|
||
|
|
||
|
if (isspace(tmppos[0])) {
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
if (tmppos[0] == '=') {
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/* terminate key */
|
||
|
tmppos[0] = '\0';
|
||
|
|
||
|
while (1) {
|
||
|
tmppos++;
|
||
|
|
||
|
if (tmppos[0] == '\0') {
|
||
|
return TD_FAILURE;
|
||
|
}
|
||
|
|
||
|
if (isspace(tmppos[0])) {
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
if (tmppos[0] == '=') {
|
||
|
continue;
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
*linepos = tmppos;
|
||
|
return TD_SUCCESS;
|
||
|
}
|
||
|
|
||
|
static td_s32 get_key(td_char **line, td_char **key, td_char **value)
|
||
|
{
|
||
|
td_s32 ret;
|
||
|
td_char *linepos = TD_NULL;
|
||
|
td_char *temp = TD_NULL;
|
||
|
|
||
|
if (key == TD_NULL || line == TD_NULL || value == TD_NULL) {
|
||
|
return TD_FAILURE;
|
||
|
}
|
||
|
|
||
|
linepos = *line;
|
||
|
|
||
|
/* skip whitespace */
|
||
|
while (isspace(linepos[0])) {
|
||
|
linepos++;
|
||
|
}
|
||
|
|
||
|
if (linepos[0] == '\0') {
|
||
|
return TD_FAILURE;
|
||
|
}
|
||
|
|
||
|
ret = _get_key(key, &linepos);
|
||
|
if (ret != TD_SUCCESS) {
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
/* get the value */
|
||
|
if (linepos[0] == '"') {
|
||
|
linepos++;
|
||
|
} else {
|
||
|
return TD_FAILURE;
|
||
|
}
|
||
|
|
||
|
*value = linepos;
|
||
|
|
||
|
temp = strchr(linepos, '"');
|
||
|
if (temp == TD_NULL) {
|
||
|
return TD_FAILURE;
|
||
|
}
|
||
|
|
||
|
temp[0] = '\0';
|
||
|
return TD_SUCCESS;
|
||
|
}
|
||
|
|
||
|
static td_s32 _check_value(const td_char *variable, td_char *value)
|
||
|
{
|
||
|
if (variable == TD_NULL || value == TD_NULL) {
|
||
|
return TD_FAILURE;
|
||
|
}
|
||
|
|
||
|
if (g_var_num >= MAX_VAR_NUM || strlen(variable) > MAX_VAR_NAME_LEN || strlen(value) > MAX_VAR_VALUE_LEN) {
|
||
|
printf("error value\n");
|
||
|
return TD_FAILURE;
|
||
|
}
|
||
|
|
||
|
if (strncpy_s(g_avariables[g_var_num], sizeof(g_avariables[g_var_num]),
|
||
|
variable, strlen(variable)) != EOK) {
|
||
|
printf("call strncpy_s error\n");
|
||
|
return TD_FAILURE;
|
||
|
}
|
||
|
remove_trailing_chars(value, '/');
|
||
|
if (strncpy_s(g_avalues[g_var_num], sizeof(g_avalues[g_var_num]), value, strlen(value)) != EOK) {
|
||
|
printf("call strncpy_s error\n");
|
||
|
return TD_FAILURE;
|
||
|
}
|
||
|
|
||
|
return TD_SUCCESS;
|
||
|
}
|
||
|
|
||
|
static td_s32 priv_read_file(FILE *cfg_file)
|
||
|
{
|
||
|
td_char line[LINE_BUF_SIZE];
|
||
|
td_char *bufline = TD_NULL;
|
||
|
td_char *linepos = TD_NULL;
|
||
|
td_char *value = TD_NULL;
|
||
|
td_char *variable = TD_NULL;
|
||
|
size_t count;
|
||
|
td_s32 lineno, retval, ret;
|
||
|
|
||
|
/* loop through the whole file */
|
||
|
lineno = 0;
|
||
|
while (fgets(line, sizeof(line), cfg_file) != NULL) {
|
||
|
lineno++;
|
||
|
bufline = line;
|
||
|
count = strlen(line);
|
||
|
if (count > LINE_SIZE) {
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
/* eat the whitespace */
|
||
|
while ((count > 0) && isspace(bufline[0])) {
|
||
|
bufline++;
|
||
|
count--;
|
||
|
}
|
||
|
|
||
|
/* see if this is a comment */
|
||
|
if (bufline[0] == COMMENT_CHARACTER || count == 0) {
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
if (memmove_s(line, sizeof(line), bufline, count) != EOK) {
|
||
|
return TD_FAILURE;
|
||
|
}
|
||
|
line[count] = '\0';
|
||
|
|
||
|
linepos = line;
|
||
|
|
||
|
retval = get_key(&linepos, &variable, &value);
|
||
|
if (retval != 0) {
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
ret = _check_value(variable, value);
|
||
|
if (ret != TD_SUCCESS) {
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
g_var_num++;
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
return TD_SUCCESS;
|
||
|
}
|
||
|
|
||
|
td_s32 parse_config_file(const td_char *path_to_config_file, td_s32 *var_num)
|
||
|
{
|
||
|
td_s32 ret;
|
||
|
|
||
|
if (var_num == TD_NULL) {
|
||
|
return TD_FAILURE;
|
||
|
}
|
||
|
|
||
|
FILE *cfg_file = fopen(path_to_config_file, "r");
|
||
|
if (cfg_file == NULL) {
|
||
|
return TD_FAILURE;
|
||
|
}
|
||
|
|
||
|
ret = priv_read_file(cfg_file);
|
||
|
|
||
|
fclose(cfg_file);
|
||
|
cfg_file = NULL;
|
||
|
|
||
|
*var_num = g_var_num;
|
||
|
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
td_char *get_config_var(const td_char *var_name)
|
||
|
{
|
||
|
td_u32 i;
|
||
|
|
||
|
if (var_name == TD_NULL) {
|
||
|
return TD_NULL;
|
||
|
}
|
||
|
|
||
|
for (i = 0; i < g_var_num; i++) {
|
||
|
if (strcasecmp(g_avariables[i], var_name) == 0) {
|
||
|
return g_avalues[i];
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return TD_NULL;
|
||
|
}
|
||
|
|
||
|
td_s32 get_key_value(const td_char *name, td_u8 *key, td_u32 key_len)
|
||
|
{
|
||
|
td_char *value = TD_NULL;
|
||
|
td_s32 i;
|
||
|
td_char tmp_buf[2]; /* just need 2 bytes as a temporary container */
|
||
|
td_s32 read;
|
||
|
|
||
|
if (name == TD_NULL || key == TD_NULL || key_len > KEY_MAX_LEN) {
|
||
|
return TD_FAILURE;
|
||
|
}
|
||
|
|
||
|
value = get_config_var(name);
|
||
|
if (value == TD_NULL) {
|
||
|
return TD_FAILURE;
|
||
|
}
|
||
|
|
||
|
/* value lenth must less than key_len */
|
||
|
read = strlen(value) > (key_len * 2) ? key_len : (strlen(value) / 2); /* Equal to key_len or (size of value)/2 */
|
||
|
for (i = 0; i < read; i++) {
|
||
|
if (memset_s(tmp_buf, sizeof(tmp_buf), 0, sizeof(tmp_buf)) != EOK) {
|
||
|
printf("call memcpy_s error\n");
|
||
|
}
|
||
|
if (memcpy_s(tmp_buf, sizeof(tmp_buf), value + i * 2, 2) != EOK) { /* copy 2 bytes at a time */
|
||
|
printf("call memcpy_s error\n");
|
||
|
}
|
||
|
|
||
|
key[i] = (td_u8)strtol(tmp_buf, NULL, 16); /* 16 means use hexadecimal */
|
||
|
}
|
||
|
|
||
|
return TD_SUCCESS;
|
||
|
}
|