// // Created by xajhu on 2021/7/30 0030. // #include #include #include #include #include #include #include "uthash/uthash.h" #include "config.h" #include "misc.h" #include "user_errno.h" #include "crypto.h" #include "hardware.h" typedef struct { CONFIG_ITEM_ID cfgId; const char *cfgPath; CONFIG_VALUE_TYPE valType; const char *defValue; const char *readme; const char *pStrId; } CFG_ITEM, *PCFG_ITEM; #define CFG_INT_VALUE(p) (p->value.longValue) #define CFG_BOOL_VALUE(p) (p->value.longValue == FALSE ? FALSE : TRUE) #define CFG_FLOAT_VALUE(p) (p->value.floatValue) #define CFG_STRING_VALUE(p) (p->value.strValue) #define ENC_HEAD ("AES@") typedef union { long long longValue; char *strValue; long double floatValue; c_vector array; } CFG_VALUE, *PCFG_VALUE; typedef struct { CONFIG_ITEM_ID cfgId; const char *pcfgKey; CONFIG_VALUE_TYPE valType; const char *defaultValue; int isChanged; const char *pMessage; const char *pStrId; CFG_VALUE value; UT_hash_handle hh; } CONFIG_ITEM, *PCONFIG_ITEM; static config_t g_cfgContent; static const char *g_cfgFilePath; static const char *g_pCfgKey = NULL; PCONFIG_ITEM g_pConfigItem = NULL; #define DEF_CFG_ITEM(id, key, type, defVal, desc) \ { .cfgId = (id), .cfgPath = (key), .valType = (type), .defValue = (defVal), .readme = (desc), .pStrId = (#id) } // clang-format off static CFG_ITEM g_cfgItem[] = { DEF_CFG_ITEM(CFG_DIRECTORY, "system.config_file_path", VAL_STR, ".", "Configuration files location path"), DEF_CFG_ITEM(CFG_CURL_CA_PATH, "system.ssl_ca_file_path", VAL_STR, "~/.ssh/ca.crt", "Libcurl access HTTPS CA File"), DEF_CFG_ITEM(CFG_BANNER_SHOW, "system.show_banner", VAL_BOOL, "1", "Enable/Disable show banner"), DEF_CFG_ITEM(CFG_HARDWARE_WATCH, "system.system_info_watch", VAL_BOOL, "1", "Monitor cpu, memory, disk, fan, temperature ..."), DEF_CFG_ITEM(CFG_HARDWARE_REFRESH, "system.system_info_refresh", VAL_INT, "10", "Monitor hardware information upgrade frequency"), /* 系统监控设备相配置 */ DEF_CFG_ITEM(CFG_WATCH_CPU, "watch_params.cpu", VAL_BOOL, "1", "Monitor cpu information"), DEF_CFG_ITEM(CFG_WATCH_MEMORY, "watch_params.memory", VAL_BOOL, "1", "Monitor memory information"), DEF_CFG_ITEM(CFG_WATCH_DISK, "watch_params.disk", VAL_BOOL, "1", "Monitor disk partition information"), DEF_CFG_ITEM(CFG_WATCH_SENSOR, "watch_params.sensor", VAL_BOOL, "1", "Sensor information refresh frequency"), /* 系统监控设备刷频率 */ DEF_CFG_ITEM(CFG_CPU_REFRESH, "watch_params.cpu_refresh", VAL_INT, "10", "CPU information refresh frequency"), DEF_CFG_ITEM(CFG_MEM_REFRESH, "watch_params.mem_refresh", VAL_INT, "10", "Memory information refresh frequency"), DEF_CFG_ITEM(CFG_DISK_REFRESH, "watch_params.disk_refresh", VAL_INT, "10", "Disk information refresh frequency"), DEF_CFG_ITEM(CFG_SENSOR_REFRESH, "watch_params.sensor_refresh", VAL_INT, "10", "Sensor information refresh frequency"), /* 数据库相配置 */ /* Redis配置 */ #ifdef USED_REDIS DEF_CFG_ITEM(CFG_DB_REDIS_SERVER, "database.redis_server", VAL_STR, "127.0.0.1", "Redis database server ip address"), DEF_CFG_ITEM(CFG_DB_REDIS_PORT, "database.redis_port", VAL_INT, "6379", "Redis database server port"), DEF_CFG_ITEM(CFG_DB_REDIS_PASSWD, "database.redis_passwd", VAL_STR, "", "Redis database server password"), #endif /* MySQL配置 */ #ifdef USED_MYSQL DEF_CFG_ITEM(CFG_DB_MYSQL_SERVER, "database.mysql_server", VAL_STR, "127.0.0.1", "MySQL database server ip address"), DEF_CFG_ITEM(CFG_DB_MYSQL_PORT, "database.mysql_port", VAL_INT, "3306", "MySQL database server port"), DEF_CFG_ITEM(CFG_DB_MYSQL_USER, "database.mysql_user", VAL_STR, "", "MySQL database user name"), DEF_CFG_ITEM(CFG_DB_MYSQL_PASSWD, "database.mysql_passwd", VAL_STR, "", "MySQL database server password"), DEF_CFG_ITEM(CFG_DB_MYSQL_DB_NAME, "database.mysql_database", VAL_STR, ".main", "MySQL database used"), #endif /* SQLite3配置 */ #ifdef USED_SQLITE DEF_CFG_ITEM(CFG_DB_SQLITE_DB_NAME, "database.sqlite_dbname", VAL_STR, "", "SQLite3 database file name"), DEF_CFG_ITEM(CFG_DB_SQLITE_PASSWD, "database.sqlite_passwd", VAL_STR, ".main", "SQLite3 database password"), #endif /* 消息队列相配置 */ /* ZeroMq配置 */ DEF_CFG_ITEM(CFG_MQ_SVR_PORT, "zero_mq.svr_port", VAL_INT, "6278", "ZeroMQ server port"), DEF_CFG_ITEM(CFG_MQ_DATA_PATH, "zero_mq.agent_addr", VAL_STR, "ipc:///tmp/msg_fifo0", "ZeroMQ Agent data path"), /* vxLan 隧道配置 */ DEF_CFG_ITEM(CFG_VXLAN_NIC_NAME, "vxlan_wan.nic", VAL_STR, "", "Network card name to send data"), DEF_CFG_ITEM(CFG_VXLAN_SUPPORT, "vxlan_wan.enable", VAL_BOOL, "1", "Is support vxLan tune"), DEF_CFG_ITEM(CFG_VXLAN_PEER_IP, "vxlan_wan.peer_ip", VAL_STR, "", "vxLan peer ip address"), DEF_CFG_ITEM(CFG_VXLAN_PEER_MAC, "vxlan_wan.peer_mac", VAL_STR, "", "vxLan peer mac address"), DEF_CFG_ITEM(CFG_VXLAN_PKG_FILTER, "vxlan_wan.pkg_filter", VAL_STR, "", "vxLan package filter"), /*HTTP Server 配置*/ DEF_CFG_ITEM(CFG_HTTP_SVR_ADDR, "http_svr.listen_addr", VAL_STR, "0.0.0.0", "Network address to listen on"), DEF_CFG_ITEM(CFG_HTTP_SVR_PORT, "http_svr.listen_port", VAL_INT, "6789", "Network port to listen on"), DEF_CFG_ITEM(CFG_HTTP_SVR_TCP_NODELAY, "http_svr.tcp_nodelay", VAL_BOOL, "1", "TCP delay switch"), DEF_CFG_ITEM(CFG_PROTO_CRYPTO, "protocol.crypto_type", VAL_INT, "0", "Protocol crypto algorithm"), DEF_CFG_ITEM(CFG_PROTO_CRYPTO_KEY, "protocol.crypto_key", VAL_STR, "", "Protocol crypto keys"), #ifdef OPENDHCPD_ON // 配置DHCP服务器 DEF_CFG_ITEM(CFG_DHCP_LEASE_TIME, "dhcp_server.lease_time", VAL_INT, "36000", "DHCP server lease time"), DEF_CFG_ITEM(CFG_DHCP_LISTEN_ON, "dhcp_server.listen_on", VAL_ARRAY_STR, "", "DHCP listen interface"), DEF_CFG_ITEM(CFG_DHCP_REPLICATION_SVR, "dhcp_server.replication", VAL_ARRAY_STR, "", "DHCP replication server configure"), DEF_CFG_ITEM(CFG_DHCP_RANGE_SET, "dhcp_server.range_set", VAL_ARRAY_OBJ, "", "DHCP IP pool"), DEF_CFG_ITEM(CFG_DHCP_MAC_FILTER, "dhcp_server.mac_filter", VAL_ARRAY_STR, "", "DHCP client MAC address black list"), #endif }; // clang-format on static int cfg_is_upgrade(PCONFIG_ITEM pItem) { if (pItem->isChanged) { pItem->isChanged = FALSE; return TRUE; } return FALSE; } static const char *load_string_value(const char *pKeyName) { const char *pCfgVal; if (config_lookup_string(&g_cfgContent, pKeyName, &pCfgVal) != CONFIG_TRUE) { dzlog_error("No {%s} setting in configuration file.\n", pKeyName); return NULL; } if (strncmp(ENC_HEAD, pCfgVal, strlen(ENC_HEAD)) == 0) { if (g_pCfgKey == NULL || strlen(g_pCfgKey) == 0) { return NULL; } else { const char *pKey = get_config_key(g_pCfgKey); int bufSize, outSize; unsigned char *buf; unsigned char *pBuf = base64_decode(&pCfgVal[strlen(ENC_HEAD)], (unsigned int *)&bufSize); if (pBuf == NULL || bufSize <= 0) { dzlog_error("{%s} setting [%s] maybe a encryption message, base64 decode error.\n", pKeyName, pCfgVal); return NULL; } if (symmetric_decrypto(AES128_ECB_PKCS7PADDING_SHA1PRNG, pBuf, bufSize, &buf, &outSize, pKey) != ERR_SUCCESS) { free((void *)pKey); free(pBuf); return NULL; } free(pBuf); free((void *)pKey); buf[outSize] = 0; return (const char *)buf; } } else { return strdup(pCfgVal); } } static int load_boolean_value(const char *pKeyName) { int val; if (config_lookup_bool(&g_cfgContent, pKeyName, &val) != CONFIG_TRUE) { dzlog_error("No {%s} setting in configuration file.\n", pKeyName); return DEFAULT_INTEGRAL_ERR_VALUE; } return val; } static long long int load_integral_value(const char *pKeyName) { long long val; if (config_lookup_int64(&g_cfgContent, pKeyName, &val) != CONFIG_TRUE) { dzlog_error("No {%s} setting in configuration file.\n", pKeyName); return DEFAULT_INTEGRAL_ERR_VALUE; } return val; } static double load_float_value(const char *pKeyName) { double val; if (config_lookup_float(&g_cfgContent, pKeyName, &val) != CONFIG_TRUE) { dzlog_error("No {%s} setting in configuration file.\n", pKeyName); return DEFAULT_INTEGRAL_ERR_VALUE; } return val; } static int cmp_str(const void *a, const void *b) { return strcmp((const char *)a, (const char *)b); } static int load_array_str(const char *pKeyName, PCONFIG_ITEM pValue) { int i; config_setting_t *pItem = config_lookup(&g_cfgContent, pKeyName); if (pItem) { for (i = 0; i < config_setting_length(pItem); i++) { const char *pVal = config_setting_get_string_elem(pItem, i); if (pVal) { zvect_index idx = 0; if (!vect_bsearch(pValue->value.array, pVal, cmp_str, &idx)) { vect_push(pValue->value.array, pVal); pValue->isChanged = TRUE; } } } vect_shrink(pValue->value.array); return ERR_SUCCESS; } return -ERR_ITEM_UNEXISTS; } static int cmp_dhcp_obj(const void *a, const void *b) { POBJ_DHCP_RNG pV1 = (POBJ_DHCP_RNG)a; POBJ_DHCP_RNG pV2 = (POBJ_DHCP_RNG)b; if (strcmp(pV1->rangAddr, pV2->rangAddr) == 0 && strcmp(pV1->subnet, pV2->subnet) == 0 && strcmp(pV1->dnsSvr, pV2->dnsSvr) == 0 && strcmp(pV1->gateway, pV2->gateway) == 0 && pV1->lease == pV2->lease) { return 0; } return -1; } static int load_array_obj(const char *pKeyName, PCONFIG_ITEM pValue) { int i; config_setting_t *pItem = config_lookup(&g_cfgContent, pKeyName); if (!pItem) { return -ERR_ITEM_UNEXISTS; } for (i = 0; i < config_setting_length(pItem); i++) { OBJ_DHCP_RNG v, k; config_setting_t *pObj = config_setting_get_elem(pItem, i); switch (pValue->cfgId) { case CFG_DHCP_RANGE_SET: { zvect_index idx = -1; const char *rangAddr, *subnet, *dnsSvr, *gateway; memset(&v, 0, sizeof(OBJ_DHCP_RNG)); if (config_setting_lookup_string(pObj, "dhcp_range", &rangAddr)) { strcpy(v.rangAddr, rangAddr); } if (config_setting_lookup_string(pObj, "subnet_mask", &subnet)) { strcpy(v.subnet, subnet); } if (config_setting_lookup_string(pObj, "domain_server", &dnsSvr)) { strcpy(v.dnsSvr, dnsSvr); } if (config_setting_lookup_string(pObj, "gateway", &gateway)) { strcpy(v.gateway, gateway); } if (!config_setting_lookup_int(pObj, "lease_time", (int *)&v.lease)) { v.lease = 0xFFFFFFFF; } if (!vect_bsearch(pValue->value.array, &v, cmp_dhcp_obj, &idx)) { memcpy(&k, &v, sizeof(OBJ_DHCP_RNG)); vect_push(pValue->value.array, &k); pValue->isChanged = TRUE; } } break; default: break; } } return ERR_SUCCESS; } static int setConfigItemValue(PCONFIG_ITEM pItem, const char *pValue) { errno = 0; if (pItem->valType == VAL_STR) { if (pItem->value.strValue != NULL) { free(pItem->value.strValue); } pItem->value.strValue = strdup(pValue); } else if (pItem->valType == VAL_INT || pItem->valType == VAL_BOOL) { char *pOver; long long val = strtoll(pValue, &pOver, 10); if ((pOver != NULL && strlen(pOver)) || errno != 0) { return -ERR_STRING_TO_NUMBER; } pItem->value.longValue = val; } else if (pItem->valType == VAL_FLOAT) { char *pOver; long double val = strtold(pValue, &pOver); if ((pOver != NULL && strlen(pOver)) || errno != 0) { return -ERR_STRING_TO_NUMBER; } pItem->value.floatValue = val; } else if (pItem->valType == VAL_ARRAY_STR) { pItem->value.array = vect_create(128, 512, ZV_SEC_WIPE); } else if (pItem->valType == VAL_ARRAY_OBJ) { pItem->value.array = vect_create(128, sizeof(OBJ_DHCP_RNG), ZV_SEC_WIPE); } else { return -ERR_UN_SUPPORT; } return ERR_SUCCESS; } static int add_new_cfg_item(CONFIG_ITEM_ID id, const char *pKey, CONFIG_VALUE_TYPE valType, const char *pDefVal, const char *pStrId, const char *pDesc) { PCONFIG_ITEM pItem; int ret; HASH_FIND_INT(g_pConfigItem, &id, pItem); if (pItem != NULL) { return -ERR_ITEM_EXISTS; } pItem = (PCONFIG_ITEM)malloc(sizeof(CONFIG_ITEM)); if (pItem == NULL) { return -ERR_MALLOC_MEMORY; } memset(pItem, 0, sizeof(CONFIG_ITEM)); pItem->cfgId = id; pItem->pcfgKey = pKey; pItem->valType = valType; pItem->defaultValue = pDefVal; pItem->pMessage = pDesc; pItem->pStrId = pStrId; ret = setConfigItemValue(pItem, pItem->defaultValue); if (ret != ERR_SUCCESS) { free(pItem); return ret; } HASH_ADD_INT(g_pConfigItem, cfgId, pItem); return ERR_SUCCESS; } static PCFG_VALUE cfg_get_value(CONFIG_ITEM_ID id) { PCONFIG_ITEM pItem; HASH_FIND_INT(g_pConfigItem, &id, pItem); if (pItem != NULL) { return &pItem->value; } return NULL; } static void refreshCfgFileCb() { PCONFIG_ITEM pItem, pTmp; int cfgUpgrade = FALSE; if (!config_read_file(&g_cfgContent, g_cfgFilePath)) { dzlog_error("%s:%d - %s\n", config_error_file(&g_cfgContent), config_error_line(&g_cfgContent), config_error_text(&g_cfgContent)); return; } HASH_ITER(hh, g_pConfigItem, pItem, pTmp) { char *pStr; long long iVal; double fVal; sds realKey = sdsnew("application."); realKey = sdscat(realKey, pItem->pcfgKey); switch (pItem->valType) { case VAL_STR: pStr = (char *)load_string_value(realKey); if (pStr) { if (strcmp(pItem->value.strValue, pStr) != 0) { if (pItem->value.strValue != NULL) { free(pItem->value.strValue); } pItem->value.strValue = strdup(pStr); pItem->isChanged = TRUE; } free(pStr); } break; case VAL_BOOL: iVal = load_boolean_value(realKey); if (iVal != DEFAULT_INTEGRAL_ERR_VALUE) { if (pItem->value.longValue != iVal) { pItem->value.longValue = iVal; pItem->isChanged = TRUE; } } break; case VAL_INT: iVal = load_integral_value(realKey); if (iVal != DEFAULT_INTEGRAL_ERR_VALUE) { if (pItem->value.longValue != iVal) { pItem->value.longValue = iVal; pItem->isChanged = TRUE; } } break; case VAL_FLOAT: fVal = load_float_value(realKey); if (fVal != DEFAULT_INTEGRAL_ERR_VALUE) { if (pItem->value.floatValue != fVal) { pItem->value.floatValue = fVal; pItem->isChanged = TRUE; } } break; case VAL_ARRAY_STR: load_array_str(realKey, pItem); break; case VAL_ARRAY_OBJ: load_array_obj(realKey, pItem); break; default: break; } if (pItem->isChanged) { cfgUpgrade = TRUE; } sdsfree(realKey); } if (cfgUpgrade) { config_item_dump("Configuration upgrade"); } } const char *config_item_dump_fmt(const char *titleMessage) { int i; const char *pResp; PCONFIG_ITEM pItem, pTmp; char tmp2[256]; sds tmp; sds s = sdsempty(); if (titleMessage && strlen(titleMessage) > 0) { s = sdscatprintf(s, "%s:\n", titleMessage); } s = sdscat(s, "--------------------------------------------------------------------------------" "-----------------------------------------------------------------------\n"); s = sdscat(s, "| id | Key Name | Configuration file key |" " value |\n"); s = sdscat(s, "--------------------------------------------------------------------------------" "-----------------------------------------------------------------------\n"); HASH_ITER(hh, g_pConfigItem, pItem, pTmp) { memset(tmp2, 0, 256); sprintf(tmp2, "%s%s", cfg_is_upgrade(pItem) ? "*" : " ", pItem->pStrId); switch (pItem->valType) { case VAL_BOOL: s = sdscatprintf(s, "|%4d | %-25s | %-45s | %-64s |\n", pItem->cfgId, tmp2, pItem->pcfgKey, CFG_BOOL_VALUE(pItem) ? "True" : "False"); break; case VAL_INT: s = sdscatprintf(s, "|%4d | %-25s | %-45s | %-64lld |\n", pItem->cfgId, tmp2, pItem->pcfgKey, CFG_INT_VALUE(pItem)); break; case VAL_FLOAT: s = sdscatprintf(s, "|%4d | %-25s | %-45s | %-64Lf |\n", pItem->cfgId, tmp2, pItem->pcfgKey, CFG_FLOAT_VALUE(pItem)); break; case VAL_STR: tmp = sdsempty(); tmp = sdscatprintf(tmp, "\"%s\"", CFG_STRING_VALUE(pItem)); if (sdslen(tmp) > 63) { sdsrange(tmp, 0, 59); tmp = sdscat(tmp, "...\""); } s = sdscatprintf(s, "|%4d | %-25s | %-45s | %-64s |\n", pItem->cfgId, tmp2, pItem->pcfgKey, tmp); sdsfree(tmp); break; case VAL_ARRAY_STR: tmp = sdsempty(); tmp = sdscat(tmp, "["); for (i = 0; i < vect_size(pItem->value.array); i++) { const char *p = (const char *)vect_get_at(pItem->value.array, i); if (p) { tmp = sdscatfmt(tmp, "\"%s\",", p); } } sdsrange(tmp, 0, -2); tmp = sdscat(tmp, "]"); //tmp = sdscatprintf(tmp, "\"%s\"", CFG_STRING_VALUE(pItem)); if (sdslen(tmp) > 63) { sdsrange(tmp, 0, 58); tmp = sdscat(tmp, "...\"]"); } s = sdscatprintf(s, "|%4d | %-25s | %-45s | %-64s |\n", pItem->cfgId, tmp2, pItem->pcfgKey, tmp); sdsfree(tmp); break; case VAL_ARRAY_OBJ: for (i = 0; i < vect_size(pItem->value.array); i++) { POBJ_DHCP_RNG p = (POBJ_DHCP_RNG)vect_get_at(pItem->value.array, i); if (!p) { continue; } sds title = sdsempty(); sds keyRang = sdsempty(); sds keySubnet = sdsempty(); sds keyDns = sdsempty(); sds keyGateway = sdsempty(); title = sdscatprintf(title, "%s[%d]", pItem->pcfgKey, i); keyRang = sdscatprintf(keyRang, "\"%s\"", p->rangAddr); keySubnet = sdscatprintf(keySubnet, "\"%s\"", p->subnet); keyDns = sdscatprintf(keyDns, "\"%s\"", p->dnsSvr); keyGateway = sdscatprintf(keyGateway, "\"%s\"", p->gateway); s = sdscatprintf(s, "|%4d | %-25s | %-45s | %-64s |\n", pItem->cfgId, tmp2, title, ""); s = sdscatprintf(s, "| | %-25s | %-45s | %-64s |\n", "", " .dhcp_range", keyRang); s = sdscatprintf(s, "| | %-25s | %-45s | %-64s |\n", "", " .subnet_mask", keySubnet); s = sdscatprintf(s, "| | %-25s | %-45s | %-64s |\n", "", " .domain_server", keyDns); s = sdscatprintf(s, "| | %-25s | %-45s | %-64s |\n", "", " .gateway", keyGateway); s = sdscatprintf(s, "| | %-25s | %-45s | %-64u |\n", "", " .lease_time", p->lease); sdsfree(title); sdsfree(keyRang); sdsfree(keySubnet); sdsfree(keyDns); sdsfree(keyGateway); } break; default: break; } } s = sdscat(s, "--------------------------------------------------------------------------------" "-----------------------------------------------------------------------\n"); pResp = strdup(s); sdsfree(s); return pResp; } void config_item_dump(const char *titleMessage) { const char *pMsg = config_item_dump_fmt(titleMessage); dzlog_info("%s", pMsg); free((char *)pMsg); #if 0 PCONFIG_ITEM pItem, pTmp; //int i, k = ARRAY_SIZE(g_sysConfigMap); dzlog_info("================== %s ===================\n", titleMessage == NULL ? "" : titleMessage); HASH_ITER(hh, g_pConfigItem, pItem, pTmp) { switch (pItem->valType) { case VAL_BOOL: dzlog_info("%s%-25s: [%-45s] = %s\n", cfg_is_upgrade(pItem) ? "*" : " ", pItem->pStrId, pItem->pcfgKey, CFG_BOOL_VALUE(pItem) ? "True" : "False"); break; case VAL_INT: dzlog_info("%s%-25s: [%-45s] = %lld\n", cfg_is_upgrade(pItem) ? "*" : " ", pItem->pStrId, pItem->pcfgKey, CFG_INT_VALUE(pItem)); break; case VAL_FLOAT: dzlog_info("%s%-25s: [%-45s] = %Lf\n", cfg_is_upgrade(pItem) ? "*" : " ", pItem->pStrId, pItem->pcfgKey, CFG_FLOAT_VALUE(pItem)); break; case VAL_STR: dzlog_info("%s%-25s: [%-45s] = \"%s\"\n", cfg_is_upgrade(pItem) ? "*" : " ", pItem->pStrId, pItem->pcfgKey, CFG_STRING_VALUE(pItem)); break; default: break; } } #endif } long double cfg_get_float_value(CONFIG_ITEM_ID id) { PCFG_VALUE pVal = cfg_get_value(id); if (pVal) { return pVal->floatValue; } else { return DEFAULT_INTEGRAL_ERR_VALUE; } } long long cfg_get_integral_value(CONFIG_ITEM_ID id) { PCFG_VALUE pVal = cfg_get_value(id); if (pVal) { return pVal->longValue; } else { return DEFAULT_INTEGRAL_ERR_VALUE; } } int cfg_get_bool_value(CONFIG_ITEM_ID id) { PCFG_VALUE pVal = cfg_get_value(id); if (pVal) { return pVal->longValue == FALSE ? FALSE : TRUE; } else { return DEFAULT_INTEGRAL_ERR_VALUE; } } const char *cfg_get_string_value(CONFIG_ITEM_ID id) { PCFG_VALUE pVal = cfg_get_value(id); if (pVal) { return pVal->strValue; } else { return NULL; } } c_vector cfg_get_vector(CONFIG_ITEM_ID id) { PCFG_VALUE pVal = cfg_get_value(id); if (pVal) { return pVal->array; } else { return NULL; } } int init_config_system(const char *pCfgFile, const char *pKey) { int i; if (!file_exists(pCfgFile)) { dzlog_error("Configuration file [%s] not exists\n", pCfgFile); return -ERR_FILE_NOT_EXISTS; } g_pCfgKey = strdup(pKey == NULL ? "" : pKey); g_cfgFilePath = strdup(pCfgFile); config_init(&g_cfgContent); for (i = 0; i < ARRAY_SIZE(g_cfgItem); i++) { add_new_cfg_item(g_cfgItem[i].cfgId, g_cfgItem[i].cfgPath, g_cfgItem[i].valType, g_cfgItem[i].defValue, g_cfgItem[i].pStrId, g_cfgItem[i].readme); } // clang-format on refreshCfgFileCb(); return ERR_SUCCESS; } void uninit_config_system() { PCONFIG_ITEM pItem, pTmp; HASH_ITER(hh, g_pConfigItem, pItem, pTmp) { switch (pItem->valType) { case VAL_ARRAY_STR: case VAL_ARRAY_OBJ: vect_destroy(pItem->value.array); break; default: break; } } config_destroy(&g_cfgContent); } const char *get_config_keygen() { char buf[MAX_PATH]; CPU_INFO cpuInfo; get_cpu_info(&cpuInfo); memset(buf, 0, MAX_PATH); sprintf(buf, "%d#%s", cpuInfo.nLogicCores, cpuInfo.cpuCoreDesc.cpuName); return strdup(buf); } const char *get_config_key(const char *pKeygen) { int outSize; unsigned char *buf = NULL; const char *strRet; const char *pKey = get_config_keygen(); unsigned char *pBase64 = (unsigned char *)base64_decode(pKeygen, (unsigned int *)&outSize); if (pBase64 == NULL) { dzlog_error("Base64 decode error: %s\n", pKeygen); return NULL; } if (symmetric_decrypto(DES3_CBC_PKCS7PADDING, pBase64, outSize, &buf, &outSize, pKey) != ERR_SUCCESS) { free((void *)pKey); free((void *)pBase64); if (buf) { free(buf); } return NULL; } else { buf[outSize] = 0; strRet = strdup((const char *)buf); } free(buf); free((void *)pKey); free((void *)pBase64); return strRet; }