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.

295 lines
6.9 KiB

/*
* Copyright (c) Hisilicon Technologies Co., Ltd. 2020-2021. All rights reserved.
* Description: This file is for interpreting the configuration file.
* Author: Hisilicon
* Create: 2020-05-16
*/
#include <string.h>
#include <stdio.h>
#include <ctype.h>
#include <limits.h>
#include "td_type.h"
#include "securec.h"
#include "parse_config_file.h"
#define DMX_COMMENT_CHARACTER '#'
#define DMX_LINE_SIZE 768
#define DMX_LINE_BUF_SIZE (DMX_LINE_SIZE + 2)
static td_char g_dmx_avariables[MAX_VAR_NUM][MAX_VAR_NAME_LEN + 1];
static td_char g_dmx_avalues[MAX_VAR_NUM][MAX_VAR_VALUE_LEN + 1];
static td_s32 g_dmx_var_num = 0;
static td_void dmx_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 dmx_get_key(td_char **line, td_char **key, td_char **value)
{
td_char *tmp_linepos = TD_NULL;
td_char *temp = TD_NULL;
tmp_linepos = *line;
if (tmp_linepos == TD_NULL) {
return TD_FAILURE;
}
/* skip whitespace */
while (isspace(tmp_linepos[0])) {
tmp_linepos++;
}
if (tmp_linepos[0] == '\0') {
return TD_FAILURE;
}
/* get the key */
*key = tmp_linepos;
while (1) {
tmp_linepos++;
if (tmp_linepos[0] == '\0') {
return TD_FAILURE;
}
if (isspace(tmp_linepos[0]) || (tmp_linepos[0] == '=')) {
break;
}
}
/* terminate key */
tmp_linepos[0] = '\0';
while (1) {
tmp_linepos++;
if (tmp_linepos[0] == '\0') {
return TD_FAILURE;
}
if (isspace(tmp_linepos[0]) || (tmp_linepos[0] == '=')) {
continue;
}
break;
}
/* get the value */
if (tmp_linepos[0] == '"') {
tmp_linepos++;
} else {
return TD_FAILURE;
}
*value = tmp_linepos;
temp = strchr(tmp_linepos, '"');
if (temp == TD_NULL) {
return TD_FAILURE;
}
temp[0] = '\0';
return TD_SUCCESS;
}
static td_s32 dmx_get_and_check_key(td_char **line, td_char **key, td_char **value, td_s32 lineno)
{
td_s32 retval;
retval = dmx_get_key(line, key, value);
if (retval != 0) {
printf("error parsing\n");
return TD_FAILURE;
}
if (g_dmx_var_num >= MAX_VAR_NUM) {
printf("too many vars\n");
return TD_FAILURE;
}
if (strlen(*key) > MAX_VAR_NAME_LEN) {
printf("var name to long\n");
return TD_FAILURE;
}
if (strlen(*value) > MAX_VAR_VALUE_LEN) {
printf("value to long \n");
return TD_FAILURE;
}
return TD_SUCCESS;
}
static td_void dmx_save_value(td_char **variable, td_char **value)
{
if (g_dmx_var_num >= MAX_VAR_NUM) {
printf("g_dmx_var_num(%u) is more than MAX_VAR_NUM(%u). \n", g_dmx_var_num, MAX_VAR_NUM);
return;
}
if (strncpy_s(g_dmx_avariables[g_dmx_var_num], sizeof(g_dmx_avariables[g_dmx_var_num]), *variable,
strlen(*variable)) != EOK) {
printf("call strncpy_s error\n");
return;
}
dmx_remove_trailing_chars(*value, '/');
if (strncpy_s(g_dmx_avalues[g_dmx_var_num], sizeof(g_dmx_avalues[g_dmx_var_num]), *value, strlen(*value)) != EOK) {
printf("call strncpy_s error\n");
return;
}
return;
}
static FILE *dmx_open_config_file(const td_char *path_to_config_file)
{
td_char std_file[PATH_MAX] = {0};
if (path_to_config_file == TD_NULL) {
return TD_NULL;
}
if (realpath(path_to_config_file, std_file) == TD_NULL) {
printf("get real path ! origName: %.190s\n", path_to_config_file);
}
return fopen(std_file, "r");
}
td_s32 dmx_parse_config_file(const td_char *path_to_config_file)
{
td_char line[DMX_LINE_BUF_SIZE];
td_char *bufline = TD_NULL;
td_char *linepos = TD_NULL;
td_char *variable = TD_NULL;
td_char *value = TD_NULL;
size_t count;
td_s32 lineno = 0;
g_dmx_var_num = 0;
FILE *cfg_file = dmx_open_config_file(path_to_config_file);
if (cfg_file == TD_NULL) {
printf("Open keyconfig:%s error\n", path_to_config_file);
goto exit;
}
/* loop through the whole file */
while (fgets(line, sizeof(line), cfg_file) != NULL) {
lineno++;
bufline = line;
count = strlen(line);
if (count > DMX_LINE_SIZE) {
continue;
}
/* eat the whitespace */
while ((count > 0) && isspace(bufline[0])) {
bufline++;
count--;
}
/* see if this is a comment or count == 0 */
if ((count == 0) || (bufline[0] == DMX_COMMENT_CHARACTER)) {
continue;
}
if (memcpy_s(line, sizeof(line), bufline, count) != EOK) {
printf("call memcpy_s error\n");
continue;
}
line[count] = '\0';
linepos = line;
if (dmx_get_and_check_key(&linepos, &variable, &value, lineno) != TD_SUCCESS) {
printf("get_and_check_key failed, line %d:%d\n", lineno, (td_s32)(linepos - line));
continue;
}
dmx_save_value(&variable, &value);
g_dmx_var_num++;
continue;
}
exit:
if (cfg_file != TD_NULL) {
fclose(cfg_file);
}
return g_dmx_var_num;
}
td_char *dmx_get_config_var(const td_char *var_name)
{
td_s32 i;
if (var_name == TD_NULL) {
return TD_NULL;
}
for (i = 0; i < g_dmx_var_num; i++) {
if (strcasecmp(g_dmx_avariables[i], var_name) == 0) {
return g_dmx_avalues[i];
}
}
return TD_NULL;
}
td_s32 dmx_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) {
return TD_FAILURE;
}
value = dmx_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 0;
}
td_s32 dmx_get_crypto_alg(uapi_crypto_alg *alg_type)
{
td_char *value = TD_NULL;
if (alg_type == TD_NULL) {
return TD_FAILURE;
}
value = dmx_get_config_var("CRYPTOALG");
if (value == TD_NULL) {
return TD_FAILURE;
}
if (strncmp(value, "AES_ECB", sizeof("AES_ECB")) == 0) {
*alg_type = 0x10; /* UAPI_CRYPTO_ALG_AES_ECB_T */
return TD_SUCCESS;
}
return TD_FAILURE;
}