/* * 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 #include #include #include #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; }