OCT 配置文件增加DHCP Server配置支持
This commit is contained in:
parent
da06daecd6
commit
ff84d9e173
|
@ -76,23 +76,23 @@ application:
|
||||||
};
|
};
|
||||||
|
|
||||||
# DHCP Server Config
|
# DHCP Server Config
|
||||||
#dhcp_server: {
|
dhcp_server: {
|
||||||
# listen_on = ["192.168.30.1", "192.168.100.1"];
|
listen_on = ["192.168.30.1", "192.168.100.1"];
|
||||||
# http_client = ["192.168.30.1", "192.168.30.110", "192.168.100.1", "192.168.100.110"];
|
http_client = ["192.168.30.1", "192.168.30.110", "192.168.100.1", "192.168.100.110"];
|
||||||
#
|
|
||||||
# range_set: (
|
range_set: (
|
||||||
# { dhcp_range = "192.168.30.110-192.168.30.120";
|
{ dhcp_range = "192.168.30.110-192.168.30.120";
|
||||||
# subnet_mask = "255.255.255.0";
|
subnet_mask = "255.255.255.0";
|
||||||
# domain_server = "114.114.114.114, 8.8.8.8";
|
domain_server = "114.114.114.114,8.8.8.8";
|
||||||
# gateway = "192.168.30.1";
|
gateway = "192.168.30.1";
|
||||||
# lease_time = 360;
|
lease_time = 360;
|
||||||
# },
|
},
|
||||||
# { dhcp_range = "192.168.100.110-192.168.100.200";
|
{ dhcp_range = "192.168.100.110-192.168.100.200";
|
||||||
# subnet_mask = "255.255.255.0";
|
subnet_mask = "255.255.255.0";
|
||||||
# domain_server = "114.114.114.114, 8.8.8.8";
|
domain_server = "114.114.114.114,8.8.8.8";
|
||||||
# gateway = "192.168.100.1";
|
gateway = "192.168.100.1";
|
||||||
# lease_time = 360;
|
lease_time = 360;
|
||||||
# }
|
}
|
||||||
# );
|
);
|
||||||
#};
|
};
|
||||||
}
|
}
|
|
@ -8,7 +8,7 @@ INCLUDE_DIRECTORIES(include
|
||||||
./ ./include ../lwip/src/include ../lwip/src/arch_linux/include ../include
|
./ ./include ../lwip/src/include ../lwip/src/arch_linux/include ../include
|
||||||
../httpserver/include ../httpserver/src/haywire ../httpserver/src/haywire/configuration
|
../httpserver/include ../httpserver/src/haywire ../httpserver/src/haywire/configuration
|
||||||
${COMMON_INCLUDE})
|
${COMMON_INCLUDE})
|
||||||
FILE(GLOB C_HEADS include/*.h include/uthash/*.h include/s2j/*.h)
|
FILE(GLOB C_HEADS include/*.h include/uthash/*.h include/s2j/*.h vector/*.h)
|
||||||
|
|
||||||
AUX_SOURCE_DIRECTORY(json C_SRC)
|
AUX_SOURCE_DIRECTORY(json C_SRC)
|
||||||
|
|
||||||
|
@ -24,9 +24,12 @@ AUX_SOURCE_DIRECTORY(mq C_SRC)
|
||||||
AUX_SOURCE_DIRECTORY(cmdline C_SRC)
|
AUX_SOURCE_DIRECTORY(cmdline C_SRC)
|
||||||
AUX_SOURCE_DIRECTORY(crypto C_SRC)
|
AUX_SOURCE_DIRECTORY(crypto C_SRC)
|
||||||
AUX_SOURCE_DIRECTORY(hardware C_SRC)
|
AUX_SOURCE_DIRECTORY(hardware C_SRC)
|
||||||
|
AUX_SOURCE_DIRECTORY(vector C_SRC)
|
||||||
|
|
||||||
SET(CMAKE_C_STANDARD 99)
|
SET(CMAKE_C_STANDARD 99)
|
||||||
|
|
||||||
|
SET_SOURCE_FILES_PROPERTIES(vector/zvector.c PROPERTIES COMPILE_FLAGS "-Wall -Wextra -flto")
|
||||||
|
|
||||||
ADD_DEFINITIONS(-DBUILD_VERSION="${GIT_VERSION}" ${COMMON_DEFINE})
|
ADD_DEFINITIONS(-DBUILD_VERSION="${GIT_VERSION}" ${COMMON_DEFINE})
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
#include "user_errno.h"
|
#include "user_errno.h"
|
||||||
#include "crypto.h"
|
#include "crypto.h"
|
||||||
#include "hardware.h"
|
#include "hardware.h"
|
||||||
|
#include "zvector/zvector.h"
|
||||||
|
|
||||||
#define CFG_INT_VALUE(p) (p->value.longValue)
|
#define CFG_INT_VALUE(p) (p->value.longValue)
|
||||||
#define CFG_BOOL_VALUE(p) (p->value.longValue == FALSE ? FALSE : TRUE)
|
#define CFG_BOOL_VALUE(p) (p->value.longValue == FALSE ? FALSE : TRUE)
|
||||||
|
@ -65,13 +66,24 @@ do {
|
||||||
ADD_CFG_ITEM(CFG_HTTP_SVR_ADDR, "application.http_svr.listen_addr", VALUE_TYPE_STRING, "0.0.0.0", "Network address to listen on"); \
|
ADD_CFG_ITEM(CFG_HTTP_SVR_ADDR, "application.http_svr.listen_addr", VALUE_TYPE_STRING, "0.0.0.0", "Network address to listen on"); \
|
||||||
ADD_CFG_ITEM(CFG_HTTP_SVR_PORT, "application.http_svr.listen_port", VALUE_TYPE_INTEGRAL, "6789", "Network port to listen on"); \
|
ADD_CFG_ITEM(CFG_HTTP_SVR_PORT, "application.http_svr.listen_port", VALUE_TYPE_INTEGRAL, "6789", "Network port to listen on"); \
|
||||||
ADD_CFG_ITEM(CFG_HTTP_SVR_TCP_NODELAY, "application.http_svr.tcp_nodelay", VALUE_TYPE_BOOL, "1", "TCP delay switch"); \
|
ADD_CFG_ITEM(CFG_HTTP_SVR_TCP_NODELAY, "application.http_svr.tcp_nodelay", VALUE_TYPE_BOOL, "1", "TCP delay switch"); \
|
||||||
|
ADD_CFG_ITEM(CFG_DHCP_LISTEN_ON, "application.dhcp_server.listen_on", VALUE_TYPE_ARRAY_STR, "", "DHCP listen interface"); \
|
||||||
|
ADD_CFG_ITEM(CFG_DHCP_HTTP_CLIENT, "application.dhcp_server.http_client", VALUE_TYPE_ARRAY_STR, "", "DHCP http server client write list"); \
|
||||||
|
ADD_CFG_ITEM(CFG_DHCP_RANGE_SET, "application.dhcp_server.range_set", VALUE_TYPE_ARRAY_OBJ, "", "DHCP IP pool"); \
|
||||||
} while (0)// clang-format on
|
} while (0)// clang-format on
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
char rangAddr[256];
|
||||||
|
char subnet[20];
|
||||||
|
char dnsSvr[256];
|
||||||
|
char gateway[20];
|
||||||
|
unsigned int lease;
|
||||||
|
} OBJ_DHCP_RNG, *POBJ_DHCP_RNG;
|
||||||
|
|
||||||
typedef union {
|
typedef union {
|
||||||
long long longValue;
|
long long longValue;
|
||||||
char *strValue;
|
char *strValue;
|
||||||
long double floatValue;
|
long double floatValue;
|
||||||
|
vector array;
|
||||||
} CFG_VALUE, *PCFG_VALUE;
|
} CFG_VALUE, *PCFG_VALUE;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@ -173,6 +185,103 @@ static double load_float_value(const char *pKeyName, double defValue) {
|
||||||
return val;
|
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 (pValue->value.array == NULL) {
|
||||||
|
pValue->value.array = vect_create(128, sizeof(OBJ_DHCP_RNG), ZV_SEC_WIPE);
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
printf("++++Add %s\n", k.rangAddr);
|
||||||
|
}
|
||||||
|
} break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ERR_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
static int setConfigItemValue(PCONFIG_ITEM pItem, const char *pValue) {
|
static int setConfigItemValue(PCONFIG_ITEM pItem, const char *pValue) {
|
||||||
errno = 0;
|
errno = 0;
|
||||||
|
|
||||||
|
@ -200,6 +309,11 @@ static int setConfigItemValue(PCONFIG_ITEM pItem, const char *pValue) {
|
||||||
}
|
}
|
||||||
|
|
||||||
pItem->value.floatValue = val;
|
pItem->value.floatValue = val;
|
||||||
|
} else if (pItem->valType == VALUE_TYPE_ARRAY_STR) {
|
||||||
|
pItem->value.array = vect_create(128, 512, ZV_SEC_WIPE);
|
||||||
|
} else if (pItem->valType == VALUE_TYPE_ARRAY_OBJ) {
|
||||||
|
pItem->value.array = NULL;
|
||||||
|
vect_create(128, sizeof(int), ZV_SEC_WIPE | ZV_BYREF);
|
||||||
} else {
|
} else {
|
||||||
return -ERR_UN_SUPPORT;
|
return -ERR_UN_SUPPORT;
|
||||||
}
|
}
|
||||||
|
@ -323,6 +437,14 @@ static void refreshCfgFileCb() {
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
case VALUE_TYPE_ARRAY_STR:
|
||||||
|
load_array_str(pItem->pcfgKey, pItem);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case VALUE_TYPE_ARRAY_OBJ:
|
||||||
|
load_array_obj(pItem->pcfgKey, pItem);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -338,9 +460,11 @@ static void refreshCfgFileCb() {
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *config_item_dump_fmt(const char *titleMessage) {
|
const char *config_item_dump_fmt(const char *titleMessage) {
|
||||||
|
int i;
|
||||||
const char *pResp;
|
const char *pResp;
|
||||||
PCONFIG_ITEM pItem, pTmp;
|
PCONFIG_ITEM pItem, pTmp;
|
||||||
sds tmp, tmp2;
|
char tmp2[256];
|
||||||
|
sds tmp;
|
||||||
sds s = sdsempty();
|
sds s = sdsempty();
|
||||||
|
|
||||||
if (titleMessage && strlen(titleMessage) > 0) {
|
if (titleMessage && strlen(titleMessage) > 0) {
|
||||||
|
@ -349,7 +473,7 @@ const char *config_item_dump_fmt(const char *titleMessage) {
|
||||||
|
|
||||||
s = sdscat(s,
|
s = sdscat(s,
|
||||||
"--------------------------------------------------------------------------------"
|
"--------------------------------------------------------------------------------"
|
||||||
"---------------------------------------------------\n");
|
"-----------------------------------------------------------------------\n");
|
||||||
|
|
||||||
s = sdscat(s,
|
s = sdscat(s,
|
||||||
"| id | Key Name | Configuration file key |"
|
"| id | Key Name | Configuration file key |"
|
||||||
|
@ -357,15 +481,15 @@ const char *config_item_dump_fmt(const char *titleMessage) {
|
||||||
|
|
||||||
s = sdscat(s,
|
s = sdscat(s,
|
||||||
"--------------------------------------------------------------------------------"
|
"--------------------------------------------------------------------------------"
|
||||||
"---------------------------------------------------\n");
|
"-----------------------------------------------------------------------\n");
|
||||||
|
|
||||||
HASH_ITER(hh, g_pConfigItem, pItem, pTmp) {
|
HASH_ITER(hh, g_pConfigItem, pItem, pTmp) {
|
||||||
tmp2 = sdsempty();
|
memset(tmp2, 0, 256);
|
||||||
tmp2 = sdscatprintf(tmp2, "%s%s", cfg_is_upgrade(pItem) ? "*" : " ", pItem->pStrId);
|
sprintf(tmp2, "%s%s", cfg_is_upgrade(pItem) ? "*" : " ", pItem->pStrId);
|
||||||
switch (pItem->valType) {
|
switch (pItem->valType) {
|
||||||
case VALUE_TYPE_BOOL:
|
case VALUE_TYPE_BOOL:
|
||||||
s = sdscatprintf(s,
|
s = sdscatprintf(s,
|
||||||
"|%4d | %-25s | %-45s | %-44s |\n",
|
"|%4d | %-25s | %-45s | %-64s |\n",
|
||||||
pItem->cfgId,
|
pItem->cfgId,
|
||||||
tmp2,
|
tmp2,
|
||||||
pItem->pcfgKey,
|
pItem->pcfgKey,
|
||||||
|
@ -373,11 +497,11 @@ const char *config_item_dump_fmt(const char *titleMessage) {
|
||||||
break;
|
break;
|
||||||
case VALUE_TYPE_INTEGRAL:
|
case VALUE_TYPE_INTEGRAL:
|
||||||
s = sdscatprintf(
|
s = sdscatprintf(
|
||||||
s, "|%4d | %-25s | %-45s | %-44lld |\n", pItem->cfgId, tmp2, pItem->pcfgKey, CFG_INT_VALUE(pItem));
|
s, "|%4d | %-25s | %-45s | %-64lld |\n", pItem->cfgId, tmp2, pItem->pcfgKey, CFG_INT_VALUE(pItem));
|
||||||
break;
|
break;
|
||||||
case VALUE_TYPE_FLOAT:
|
case VALUE_TYPE_FLOAT:
|
||||||
s = sdscatprintf(s,
|
s = sdscatprintf(s,
|
||||||
"|%4d | %-25s | %-45s | %-44Lf |\n",
|
"|%4d | %-25s | %-45s | %-64Lf |\n",
|
||||||
pItem->cfgId,
|
pItem->cfgId,
|
||||||
tmp2,
|
tmp2,
|
||||||
pItem->pcfgKey,
|
pItem->pcfgKey,
|
||||||
|
@ -386,22 +510,74 @@ const char *config_item_dump_fmt(const char *titleMessage) {
|
||||||
case VALUE_TYPE_STRING:
|
case VALUE_TYPE_STRING:
|
||||||
tmp = sdsempty();
|
tmp = sdsempty();
|
||||||
tmp = sdscatprintf(tmp, "\"%s\"", CFG_STRING_VALUE(pItem));
|
tmp = sdscatprintf(tmp, "\"%s\"", CFG_STRING_VALUE(pItem));
|
||||||
if (sdslen(tmp) > 43) {
|
if (sdslen(tmp) > 63) {
|
||||||
sdsrange(tmp, 0, 39);
|
sdsrange(tmp, 0, 59);
|
||||||
sdscat(tmp, "...\"");
|
tmp = sdscat(tmp, "...\"");
|
||||||
}
|
}
|
||||||
s = sdscatprintf(s, "|%4d | %-25s | %-45s | %-44s |\n", pItem->cfgId, tmp2, pItem->pcfgKey, tmp);
|
s = sdscatprintf(s, "|%4d | %-25s | %-45s | %-64s |\n", pItem->cfgId, tmp2, pItem->pcfgKey, tmp);
|
||||||
sdsfree(tmp);
|
sdsfree(tmp);
|
||||||
break;
|
break;
|
||||||
|
case VALUE_TYPE_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 VALUE_TYPE_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:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
sdsfree(tmp2);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
s = sdscat(s,
|
s = sdscat(s,
|
||||||
"--------------------------------------------------------------------------------"
|
"--------------------------------------------------------------------------------"
|
||||||
"---------------------------------------------------\n");
|
"-----------------------------------------------------------------------\n");
|
||||||
|
|
||||||
pResp = strdup(s);
|
pResp = strdup(s);
|
||||||
sdsfree(s);
|
sdsfree(s);
|
||||||
|
@ -494,7 +670,6 @@ const char *cfg_get_string_value(CONFIG_ITEM_ID id) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int init_config_system(const char *pCfgFile, const char *pKey) {
|
int init_config_system(const char *pCfgFile, const char *pKey) {
|
||||||
if (!file_exists(pCfgFile)) {
|
if (!file_exists(pCfgFile)) {
|
||||||
dzlog_error("Configuration file [%s] not exists\n", pCfgFile);
|
dzlog_error("Configuration file [%s] not exists\n", pCfgFile);
|
||||||
|
|
|
@ -15,7 +15,8 @@ typedef enum {
|
||||||
VALUE_TYPE_FLOAT = 1,
|
VALUE_TYPE_FLOAT = 1,
|
||||||
VALUE_TYPE_STRING = 2,
|
VALUE_TYPE_STRING = 2,
|
||||||
VALUE_TYPE_BOOL = 3,
|
VALUE_TYPE_BOOL = 3,
|
||||||
VALUE_TYPE_ARRAY = 4,
|
VALUE_TYPE_ARRAY_STR = 4,
|
||||||
|
VALUE_TYPE_ARRAY_OBJ = 5,
|
||||||
} CONFIG_VALUE_TYPE;
|
} CONFIG_VALUE_TYPE;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
|
@ -50,6 +51,9 @@ typedef enum {
|
||||||
CFG_HTTP_SVR_ADDR = 29,
|
CFG_HTTP_SVR_ADDR = 29,
|
||||||
CFG_HTTP_SVR_PORT = 30,
|
CFG_HTTP_SVR_PORT = 30,
|
||||||
CFG_HTTP_SVR_TCP_NODELAY = 31,
|
CFG_HTTP_SVR_TCP_NODELAY = 31,
|
||||||
|
CFG_DHCP_LISTEN_ON = 32,
|
||||||
|
CFG_DHCP_HTTP_CLIENT = 33,
|
||||||
|
CFG_DHCP_RANGE_SET = 34,
|
||||||
CONFIG_ITEM_ID_MAX
|
CONFIG_ITEM_ID_MAX
|
||||||
} CONFIG_ITEM_ID;
|
} CONFIG_ITEM_ID;
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,642 @@
|
||||||
|
/*
|
||||||
|
* Name: ZVector (Header)
|
||||||
|
* Purpose: Library to use Dynamic Arrays (Vectors) in C Language
|
||||||
|
* Author: Paolo Fabio Zaino
|
||||||
|
* Domain: General
|
||||||
|
* License: Copyright by Paolo Fabio Zaino, all rights reserved
|
||||||
|
* Distributed under MIT license
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef SRC_ZVECTOR_H_
|
||||||
|
#define SRC_ZVECTOR_H_
|
||||||
|
|
||||||
|
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||||
|
# pragma once
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef _cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Requires standard C libraries:
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
// First library included is zvector_checks,
|
||||||
|
// so we know on which platform and which features
|
||||||
|
// we can use:
|
||||||
|
#include "zvector_checks.h"
|
||||||
|
|
||||||
|
// Include vector configuration header
|
||||||
|
#include "zvector_config.h"
|
||||||
|
|
||||||
|
// Declare required structs:
|
||||||
|
typedef struct p_vector * vector;
|
||||||
|
|
||||||
|
// Declare required enums:
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Vector Properties Flags can be used to tell ZVector
|
||||||
|
* which types of properties we want to enable for each
|
||||||
|
* given vector we are creating.
|
||||||
|
* Each vector can have multiple properties enabled at the
|
||||||
|
* same time, you can use the typical C form to specify multiple
|
||||||
|
* properties for the same vector:
|
||||||
|
*
|
||||||
|
* ZV_SEC_WIPE | ZV_BYREF
|
||||||
|
*
|
||||||
|
* The above will create a vector that supports passing items to
|
||||||
|
* it by reference (instead of copying them into the vector) and
|
||||||
|
* having Secure Wipe enabled, so that when an element is deleted
|
||||||
|
* its reference will also be fully zeroed out before freeing it.
|
||||||
|
*/
|
||||||
|
enum ZVECT_PROPERTIES {
|
||||||
|
ZV_NONE = 0, // Sets or Resets all vector's properties to 0.
|
||||||
|
ZV_SEC_WIPE = 1 << 0, // Sets the vector for automatic Secure Wipe of items.
|
||||||
|
ZV_BYREF = 1 << 1, // Sets the vector to store items by reference instead of copying them as per default.
|
||||||
|
ZV_CIRCULAR = 1 << 2, // Sets the vector to be a circular vector (so it will not grow in capacity automatically). Elements will be overwritten as in typical circular buffers!
|
||||||
|
ZV_NOLOCKING = 1 << 3, // This Property means the vector will not use mutexes, be careful using it!
|
||||||
|
};
|
||||||
|
|
||||||
|
enum ZVECT_ERR {
|
||||||
|
ZVERR_VECTUNDEF = -1,
|
||||||
|
ZVERR_IDXOUTOFBOUND = -2,
|
||||||
|
ZVERR_OUTOFMEM = -3,
|
||||||
|
ZVERR_VECTCORRUPTED = -4,
|
||||||
|
ZVERR_RACECOND = -5,
|
||||||
|
ZVERR_VECTTOOSMALL = -6,
|
||||||
|
ZVERR_VECTDATASIZE = -7,
|
||||||
|
ZVERR_VECTEMPTY = -8,
|
||||||
|
ZVERR_OPNOTALLOWED = -9
|
||||||
|
};
|
||||||
|
|
||||||
|
/*****************************
|
||||||
|
** Public API declaration: **
|
||||||
|
*****************************/
|
||||||
|
|
||||||
|
// Vector construction/Destruction and memory control:
|
||||||
|
|
||||||
|
/*
|
||||||
|
* vect_create creates and returns a new vector
|
||||||
|
* of the specified "capacity", with a storage area that
|
||||||
|
* can store items of "item_size" size and, if we want to
|
||||||
|
* have an automatic secure erasing enabled (ZV_SEC_WIPE
|
||||||
|
* ), we can simply pass ZV_SAFE_WIPE (or other flags too)
|
||||||
|
* after item_size. Flags syntax is the usual C flag sets:
|
||||||
|
* ZV_SEC_WIPE | ZV_BYREF etc.
|
||||||
|
*/
|
||||||
|
vector vect_create(zvect_index capacity, size_t item_size, uint32_t properties);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* vect_destroy destroys the specified vector and, if
|
||||||
|
* secure_wipe is enabled, also ensure erasing each single
|
||||||
|
* value in the vector before destroying it.
|
||||||
|
*/
|
||||||
|
void vect_destroy(vector);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* vect_shrink is useful when operating on systems with
|
||||||
|
* small amount of RAM, and it basically allows to shrink
|
||||||
|
* the vector capacity to match the actual used size, to
|
||||||
|
* save unused memory locations.
|
||||||
|
*/
|
||||||
|
void vect_shrink(vector const v);
|
||||||
|
#define vect_shrink_to_fit(x) vect_shrink(x)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* vect_set_wipefunct allows you to pass ZVector a pointer to a custom
|
||||||
|
* function (of your creation) to securely wipe data from the vector v
|
||||||
|
* when automatic safe wipe is called.
|
||||||
|
*/
|
||||||
|
void vect_set_wipefunct(vector const v, void (*f1)(const void *item, size_t size));
|
||||||
|
|
||||||
|
// Vector state checks:
|
||||||
|
|
||||||
|
/*
|
||||||
|
* vect_is_empty returns true if the vector is empty
|
||||||
|
* and false if the vector is NOT empty.
|
||||||
|
*/
|
||||||
|
bool vect_is_empty(vector const v);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* vect_size returns the actual size (the number of)
|
||||||
|
* USED slots in the vector storage.
|
||||||
|
*/
|
||||||
|
zvect_index vect_size(vector const v);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* vect_clear clears out a vector and also resizes it
|
||||||
|
* to its initial capacity.
|
||||||
|
*/
|
||||||
|
void vect_clear(vector const v);
|
||||||
|
|
||||||
|
bool vect_check_status(const vector v, zvect_index flag_id);
|
||||||
|
|
||||||
|
bool vect_set_status(const vector v, zvect_index flag_id);
|
||||||
|
|
||||||
|
bool vect_clear_status(const vector v, zvect_index flag_id);
|
||||||
|
|
||||||
|
#if ( ZVECT_THREAD_SAFE == 1 )
|
||||||
|
// Vector Thread Safe functions:
|
||||||
|
|
||||||
|
/*
|
||||||
|
* vect_lock_enable allows you to enable thread safe
|
||||||
|
* code at runtime. It doesn't lock anything, it just
|
||||||
|
* enables globally ZVector thread safe code at
|
||||||
|
* runtime.
|
||||||
|
*
|
||||||
|
* Example of use:
|
||||||
|
* vect_lock_enable;
|
||||||
|
*/
|
||||||
|
void vect_lock_enable(void);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* vect_lock_disable allows you to disable thread safe
|
||||||
|
* code at runtime. It doesn't lock anything, it just
|
||||||
|
* disables globally ZVector thread safe code at
|
||||||
|
* runtime.
|
||||||
|
*
|
||||||
|
* Example of use:
|
||||||
|
* vect_lock_disable;
|
||||||
|
*/
|
||||||
|
void vect_lock_disable(void);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* vect_lock allows you to lock the given vector to
|
||||||
|
* have exclusive write access from your own thread.
|
||||||
|
* When you lock a vector directly then ZVector will
|
||||||
|
* NOT use its internal locking mechanism for that
|
||||||
|
* specific vector.
|
||||||
|
*
|
||||||
|
* Example of use: To lock a vector called v
|
||||||
|
* vect_lock(v);
|
||||||
|
*/
|
||||||
|
zvect_retval vect_lock(vector const v);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* vect_trylock will try to lock the given vector to
|
||||||
|
* have exclusive write access from your own thread.
|
||||||
|
* When you lock a vector directly then ZVector will
|
||||||
|
* NOT use its internal locking mechanism for that
|
||||||
|
* specific vector.
|
||||||
|
*
|
||||||
|
* Example of use: To lock a vector called v
|
||||||
|
* vect_trylock(v);
|
||||||
|
*/
|
||||||
|
zvect_retval vect_trylock(vector const v);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* vect_lock allows you to unlock the given vector that
|
||||||
|
* you have previously locked with vect_lock.
|
||||||
|
*
|
||||||
|
* Example of use: To unlock a vector called v
|
||||||
|
* vect_unlock(v);
|
||||||
|
*/
|
||||||
|
zvect_retval vect_unlock(vector const v);
|
||||||
|
|
||||||
|
/* TODO:
|
||||||
|
* zvect_retval vect_wait_for_signal(const vector v);
|
||||||
|
*
|
||||||
|
* zvect_retval vect_lock_after_signal(const vector v);
|
||||||
|
*/
|
||||||
|
|
||||||
|
zvect_retval vect_move_on_signal(vector const v1, vector v2,
|
||||||
|
const zvect_index s2,
|
||||||
|
const zvect_index e2,
|
||||||
|
zvect_retval (*f2)(void *, void *));
|
||||||
|
|
||||||
|
zvect_retval vect_send_signal(const vector v);
|
||||||
|
|
||||||
|
zvect_retval vect_broadcast_signal(const vector v);
|
||||||
|
|
||||||
|
zvect_retval vect_sem_wait(const vector v);
|
||||||
|
|
||||||
|
zvect_retval vect_sem_post(const vector v);
|
||||||
|
|
||||||
|
#endif // ( ZVECT_THREAD_SAFE == 1 )
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////
|
||||||
|
// Vector Data Storage functions:
|
||||||
|
|
||||||
|
/*
|
||||||
|
* vect_push and vect_pop are used to use the
|
||||||
|
* vector as a dynamic stack.
|
||||||
|
*
|
||||||
|
* int i = 3;
|
||||||
|
* vect_push(v, &i) pushes the element 3 at the
|
||||||
|
* back of the vector v, which
|
||||||
|
* corresponds to the top of a
|
||||||
|
* Stack.
|
||||||
|
*/
|
||||||
|
void vect_push(vector const v, const void *item);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* vect_pop(v) "pops" (returns) the element
|
||||||
|
* at the back of the vector as
|
||||||
|
* a regular pop would do with
|
||||||
|
* an element at the top of a
|
||||||
|
* stack. Remember when you use
|
||||||
|
* vect_pop the element you
|
||||||
|
* receive is also removed from
|
||||||
|
* the vector!
|
||||||
|
*/
|
||||||
|
void *vect_pop(vector const v);
|
||||||
|
#define vect_pop_back(x) vect_pop(x)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* vect_add adds a new item into the vector and,
|
||||||
|
* if required, will also reorganize the vector.
|
||||||
|
*
|
||||||
|
* int i = 3;
|
||||||
|
* vect_add(v, &i) will add the new item 3 in
|
||||||
|
* the vector v at the end
|
||||||
|
* (or back) of the vector v.
|
||||||
|
*/
|
||||||
|
void vect_add(vector const v, const void *item);
|
||||||
|
#define vect_push_back(x, y) vect_add(x, y)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* int i = 4;
|
||||||
|
* vect_add_at(v, &i, 2) will add the new item 4 at
|
||||||
|
* position 2 in the vector v
|
||||||
|
* and move all the elements
|
||||||
|
* from the original 2nd onward
|
||||||
|
* of a position to make space
|
||||||
|
* for the new item 4.
|
||||||
|
*/
|
||||||
|
void vect_add_at(vector const v, const void *item, zvect_index index);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* int i = 5;
|
||||||
|
* vect_add_front(v, &i) will add the new item 5 at
|
||||||
|
* the beginning of the vector
|
||||||
|
* v (or front) and will also
|
||||||
|
* move all the existing
|
||||||
|
* elements of one position in
|
||||||
|
* the vector to make space for
|
||||||
|
* the new item 5 at the front
|
||||||
|
* of vector v.
|
||||||
|
*/
|
||||||
|
void vect_add_front(vector const v, const void *item);
|
||||||
|
#define vect_push_front(x, y) vect_add_front(x, y)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* vect_get returns an item from the specified vector
|
||||||
|
*
|
||||||
|
* vect_get(v) will return the ast element in
|
||||||
|
* the v vector (but will not remove
|
||||||
|
* the element as it happens in
|
||||||
|
* vect_pop(v)).
|
||||||
|
*/
|
||||||
|
void *vect_get(vector const v);
|
||||||
|
#define vect_back(v) vect_get(v)
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
* vect_get_at(v, 3) will return the element at location
|
||||||
|
* 3 in the vector v.
|
||||||
|
*/
|
||||||
|
void *vect_get_at(vector const v, const zvect_index i);
|
||||||
|
#define vect_at(v, x) vect_get_at(v, x)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* vect_get_front(v) will return the first element in
|
||||||
|
* the vector v.
|
||||||
|
*/
|
||||||
|
void *vect_get_front(vector const v);
|
||||||
|
#define vect_front(v) vect_get_front(v)
|
||||||
|
|
||||||
|
/*
|
||||||
|
*vect_put allows you to REPLACE an item
|
||||||
|
* in the vector.
|
||||||
|
*
|
||||||
|
* int i = 3;
|
||||||
|
* vect_put(v, &i) will replace the last element
|
||||||
|
* in the vector with 3.
|
||||||
|
*/
|
||||||
|
void vect_put(vector const v, const void *item);
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
* int i = 4;
|
||||||
|
* vect_put_at(v, &i, 2) will replace the 3rd element
|
||||||
|
* (2 + 1, as vector's 1st item
|
||||||
|
* starts at v[0]) with the
|
||||||
|
* item 4.
|
||||||
|
*/
|
||||||
|
void vect_put_at(vector const v, const void *item, const zvect_index i);
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
* int i = 5;
|
||||||
|
* vect_put_front(v, &i) will replace the 1st element
|
||||||
|
* of the vector with the item
|
||||||
|
* 5.
|
||||||
|
*/
|
||||||
|
void vect_put_front(vector const v, const void *item);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* vect_remove removes an item from the vector
|
||||||
|
* and reorganise the vector. It also returns
|
||||||
|
* the item remove from the vector, so you can
|
||||||
|
* use it to simulate a stack behaviour as well.
|
||||||
|
*
|
||||||
|
* vect_remove(v) will remove and return the
|
||||||
|
* last item in the vector.
|
||||||
|
*/
|
||||||
|
void *vect_remove(vector const v);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* vect_remove_at(v, 3) will remove the 3rd item in
|
||||||
|
* the vector and return it.
|
||||||
|
*/
|
||||||
|
void *vect_remove_at(vector const v, const zvect_index i);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* vect_remove_front(v) will remove the 1st item in
|
||||||
|
* the vector and return it.
|
||||||
|
*/
|
||||||
|
void *vect_remove_front(vector const v);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* vect_delete deletes an item from the vector
|
||||||
|
* and reorganise the vector. It does not return
|
||||||
|
* the item like remove.
|
||||||
|
*
|
||||||
|
* vect_delete(v) will delete and the last
|
||||||
|
* item in the vector.
|
||||||
|
*/
|
||||||
|
void vect_delete(vector const v);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* vect_delete_at(v, 3) will delete the 3rd item in
|
||||||
|
* the vector.
|
||||||
|
*/
|
||||||
|
void vect_delete_at(vector const v, const zvect_index i);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* vect_delete_range(v, 20, 30)
|
||||||
|
* will delete items from item
|
||||||
|
* 20 to item 30 in the vector
|
||||||
|
* v.
|
||||||
|
*/
|
||||||
|
void vect_delete_range(vector const v, const zvect_index first_element, const zvect_index last_element);
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
* vect_delete_front(v) will delete the 1st item in
|
||||||
|
* the vector.
|
||||||
|
*/
|
||||||
|
void vect_delete_front(vector const v);
|
||||||
|
|
||||||
|
////////////
|
||||||
|
// Vector Data manipulation functions:
|
||||||
|
////////////
|
||||||
|
|
||||||
|
#ifdef ZVECT_DMF_EXTENSIONS
|
||||||
|
// Data Manipulation Functions extensions:
|
||||||
|
|
||||||
|
/*
|
||||||
|
* vect_swap is a function that allows you to swap two
|
||||||
|
* items in the same vector.
|
||||||
|
* You just pass the vector and the index of both the
|
||||||
|
* two items to swap.
|
||||||
|
*
|
||||||
|
* For example to swap item 3 with item 22 on vector v
|
||||||
|
* use:
|
||||||
|
* vect_swap(v, 3, 22);
|
||||||
|
*/
|
||||||
|
void vect_swap(vector const v, const zvect_index s, const zvect_index e);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* vect_swap_range is a function that allows to swap
|
||||||
|
* a range of items in the same vector.
|
||||||
|
* You just pass the vector, the index of the first item
|
||||||
|
* to swap, the index of the last item to swap and the
|
||||||
|
* index of the first item to swap with.
|
||||||
|
*
|
||||||
|
* For example to swap items from 10 to 20 with items
|
||||||
|
* from 30 to 40 on vector v, use:
|
||||||
|
* vect_swap_range(v, 10, 20, 30);
|
||||||
|
*/
|
||||||
|
void vect_swap_range(vector const v, const zvect_index s1, const zvect_index e1, const zvect_index s2);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* vect_rotate_left is a function that allows to rotate
|
||||||
|
* a vector of "i" positions to the left (or from the
|
||||||
|
* "front" to the "end").
|
||||||
|
*
|
||||||
|
* For example to rotate a vector called v of 5 positions
|
||||||
|
* to the left, use:
|
||||||
|
* vect_rotate_left(v, 5);
|
||||||
|
*/
|
||||||
|
void vect_rotate_left(vector const v, const zvect_index i);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* vect_rotate_right is a function that allows to rotate
|
||||||
|
* a vector of "i" positions to the right (or from the
|
||||||
|
* "end" to the "front").
|
||||||
|
*
|
||||||
|
* For example to rotate a vector called v of 5 positions
|
||||||
|
* to the right, use:
|
||||||
|
* vect_rotate_right(v, 5);
|
||||||
|
*/
|
||||||
|
void vect_rotate_right(vector const v, const zvect_index i);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* vect_qsort allows you to sort a given vector.
|
||||||
|
* The algorithm used to sort a vector is Quicksort with
|
||||||
|
* 3 ways partitioning which is generally much faster than
|
||||||
|
* traditional quicksort.
|
||||||
|
*
|
||||||
|
* To sort a vector you need to provide a custom function
|
||||||
|
* that allows vect_sort to determine the order and which
|
||||||
|
* elements of a vector are used to order it in the way
|
||||||
|
* you desire. It pretty much works as a regular C qsort
|
||||||
|
* function. It quite fast given that it only reorders
|
||||||
|
* pointers to your datastructures stored in the vector.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void vect_qsort(vector const v, int (*compare_func)(const void *, const void*));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* vect_bsearch is a function that allows to perform
|
||||||
|
* a binary search over the vector we pass to it to
|
||||||
|
* find the item "key" using the comparison function
|
||||||
|
* "f1".
|
||||||
|
*
|
||||||
|
* The specific algorithm used to implement vect_bsearch
|
||||||
|
* if my own re-implementation of the Adaptive Binary
|
||||||
|
* Search algorithm (from Igor van den Hoven) which has
|
||||||
|
* some improvements over the original one (look at the
|
||||||
|
* sources for more details).
|
||||||
|
*
|
||||||
|
* For example to search for the number 5 in a vector
|
||||||
|
* called v using a compare function called "my_compare"
|
||||||
|
* use:
|
||||||
|
* int i = 5;
|
||||||
|
* vect_bsearch(v, &i, my_compare);
|
||||||
|
*/
|
||||||
|
bool vect_bsearch(vector const v, const void *key, int (*f1)(const void *, const void *), zvect_index *item_index);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* vect_add_ordered allows the insertion of new items in
|
||||||
|
* an ordered fashion. Please note that for this to work
|
||||||
|
* fine you should always use only ordered vectors or if
|
||||||
|
* an empty vector use vect_add_ordered only to add new
|
||||||
|
* values to it!
|
||||||
|
*
|
||||||
|
* As for any other ordered function you must provide
|
||||||
|
* your own compare function (syntax is the usual one,
|
||||||
|
* and it's the same as for regular CLib qsort function)
|
||||||
|
*
|
||||||
|
* To add item 3 to a vector called v using vect_add_ordered
|
||||||
|
* (assuming your compare function is called my_compare),
|
||||||
|
* use:
|
||||||
|
*
|
||||||
|
* vect_Add_ordered(v, 3, my_compare);
|
||||||
|
*/
|
||||||
|
void vect_add_ordered(vector const v, const void *value, int (*f1)(const void *, const void *));
|
||||||
|
|
||||||
|
#endif // ZVECT_DMF_EXTENSIONS
|
||||||
|
|
||||||
|
#ifdef ZVECT_SFMD_EXTENSIONS
|
||||||
|
// Single Function Multiple Data extensions:
|
||||||
|
|
||||||
|
/*
|
||||||
|
* vect_apply allows you to apply a C function to
|
||||||
|
* each item in the vector, so you just pass the vector,
|
||||||
|
* the function you want to execute against each item on
|
||||||
|
* a vector and make sure such function is declared and
|
||||||
|
* defined to accept a "void *" pointer which will be the
|
||||||
|
* pointer to the single item in the vector passed to your
|
||||||
|
* function. The function has no return value because it's
|
||||||
|
* not necessary if you receive the pointer to the item.
|
||||||
|
* You can simply update the content of the memory pointed
|
||||||
|
* by the item passed and that is much faster than having
|
||||||
|
* to deal with return values especially when you'll be
|
||||||
|
* using complex data structures as item of the vector.
|
||||||
|
*/
|
||||||
|
void vect_apply(vector const v, void (*f1)(void *));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* vect_apply_if is a function that will apply "f1" C function
|
||||||
|
* to each and every item in vector v1, IF the return value of
|
||||||
|
* function f2 is true. So it allows what is known as conditional
|
||||||
|
* application. f2 will receive an item from v1 as first parameter
|
||||||
|
* and an item from v2 (at the same position of the item in v1) as
|
||||||
|
* second parameter. So, for example, if we want to increment all
|
||||||
|
* items in v1 of 10 if they are smaller than the corresponded item
|
||||||
|
* in v2 then we can simply use:
|
||||||
|
*
|
||||||
|
* vect_apply_if(v1, v2, increment_item, is_item_too_small);
|
||||||
|
*
|
||||||
|
* and make sure we have defined 'increment_item' and
|
||||||
|
* 'is_item_too_small' as:
|
||||||
|
*
|
||||||
|
* void increment_item(void *item1)
|
||||||
|
* {
|
||||||
|
* int *value = (int *)item1;
|
||||||
|
* *value +=10;
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* bool is_item_too_small(void *item1, void *item2)
|
||||||
|
* {
|
||||||
|
* if (*((int *)item1) < *((int *)item2))
|
||||||
|
* return true;
|
||||||
|
* return false;
|
||||||
|
* }
|
||||||
|
*/
|
||||||
|
void vect_apply_if(vector const v1, vector const v2, void (*f1)(void *), bool (*f2)(void *, void *));
|
||||||
|
|
||||||
|
// Operations with multiple vectors:
|
||||||
|
|
||||||
|
/*
|
||||||
|
* vect_copy is a function that allows to copy a specified
|
||||||
|
* set of elements from a vector to another.
|
||||||
|
* Please note: only vectors with the same data size (the
|
||||||
|
* parameter we pass during the creation of both vectors)
|
||||||
|
* can be copied into the other!
|
||||||
|
*
|
||||||
|
* vect_copy(v1, v2, 3, 5) will copy all the items in
|
||||||
|
* vector v2, from the 4th item
|
||||||
|
* till the 9th (3 + 5, remember
|
||||||
|
* vector items start from 0) in
|
||||||
|
* the vector v1. So at the end
|
||||||
|
* of the process you'll have such
|
||||||
|
* items copied at the end of v1.
|
||||||
|
*/
|
||||||
|
void vect_copy(vector const v1, vector const v2, zvect_index start, zvect_index max_elements);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* vect_insert is a function that allows to copy a specified
|
||||||
|
* set of elements from a vector to another and "insert"
|
||||||
|
* them from a specified position in the destination vector.
|
||||||
|
* Please note: only vectors with the same data size (the
|
||||||
|
* parameter we pass during the creation of both vectors)
|
||||||
|
* can be copied into the other!
|
||||||
|
*
|
||||||
|
* vect_insert(v1, v2, 3, 5, 7) will copy all the items in
|
||||||
|
* vector v2, from the 4th item
|
||||||
|
* till the 9th (3 + 5, remember
|
||||||
|
* vector items start from 0) in
|
||||||
|
* the vector v1 from position 7.
|
||||||
|
* So at the end of the process
|
||||||
|
* you'll have such items "inserted"
|
||||||
|
* inside v1.
|
||||||
|
*/
|
||||||
|
void vect_insert(vector const v1, vector const v2, const zvect_index s2,
|
||||||
|
const zvect_index e2, const zvect_index s1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* vect_move is a function that allows to move a specified
|
||||||
|
* set of items from one vector to another.
|
||||||
|
* It will also re-organise the source vector and (obviously)
|
||||||
|
* expand the destination vector if needed.
|
||||||
|
* Please note: only vectors of the same data size can be moved
|
||||||
|
* one into the other!
|
||||||
|
*
|
||||||
|
* vect_move(v1, v2, 2, 2) will move items in v2 from the
|
||||||
|
* 3rd item in v2 till the 5th at
|
||||||
|
* the end of v1.
|
||||||
|
*/
|
||||||
|
void vect_move(vector const v1, vector const v2, zvect_index start, zvect_index max_elements);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* vect_move_if is a function that allows to move a specified
|
||||||
|
* set of items from one vector to another if the condition
|
||||||
|
* returned by the function pointed by f2 function pointer
|
||||||
|
* is true.
|
||||||
|
* It will also re-organise the source vector and (obviously)
|
||||||
|
* expand the destination vector if needed.
|
||||||
|
* Please note: only vectors of the same data size can be moved
|
||||||
|
* one into the other!
|
||||||
|
*
|
||||||
|
* vect_move(v1, v2, 2, 2, check_data) will move items in v2 from the
|
||||||
|
* 3rd item in v2 till the 5th at
|
||||||
|
* the end of v1 if check_data returns
|
||||||
|
* true.
|
||||||
|
*/
|
||||||
|
zvect_retval vect_move_if(vector const v1, vector v2, const zvect_index s2,
|
||||||
|
const zvect_index e2, zvect_retval (*f2)(void *, void *));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* vect_merge is a function that merges together 2 vectors of
|
||||||
|
* the same data size. At the end of the process, the source
|
||||||
|
* vector will be destroyed.
|
||||||
|
*
|
||||||
|
* vect_merge(v1, v2) will merge vector v2 to v1 and then
|
||||||
|
* destroy v2. So at the end of the job
|
||||||
|
* v1 will contain the old v1 items +
|
||||||
|
* all v2 items.
|
||||||
|
*/
|
||||||
|
void vect_merge(vector const v1, vector v2);
|
||||||
|
|
||||||
|
#endif // ZVECT_SFMD_EXTENSIONS
|
||||||
|
|
||||||
|
#ifdef _cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // SRC_ZVECTOR_H_
|
|
@ -0,0 +1,144 @@
|
||||||
|
/*
|
||||||
|
* Name: ZVector_Checks
|
||||||
|
* Purpose: Header used by ZVector Library to identify for which
|
||||||
|
* platform ZVector is being compiled.
|
||||||
|
* Author: Paolo Fabio Zaino
|
||||||
|
* Domain: General
|
||||||
|
* License: Copyright 2021 by Paolo Fabio Zaino, all rights reserved
|
||||||
|
* Distributed under MIT license
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef SRC_ZVECTOR_CHECKS_H_
|
||||||
|
#define SRC_ZVECTOR_CHECKS_H_
|
||||||
|
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||||
|
#pragma once
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Try to determine the Operating System being used:
|
||||||
|
#if defined(__APPLE__) && defined(__MACH__)
|
||||||
|
# define macOS
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if ( defined(__GNU__) || defined(__gnu_linux__) || \
|
||||||
|
defined(__linux__) || defined(macOS) )
|
||||||
|
# define OS_TYPE 1
|
||||||
|
#elif ( defined(__WIN32__) || defined(WIN32) || defined(_WIN32) )
|
||||||
|
# define OS_TYPE 2
|
||||||
|
#else
|
||||||
|
# define OS_TYPE 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Try to determine compiler being used:
|
||||||
|
#if defined(__GNUC__)
|
||||||
|
# define compiler gcc
|
||||||
|
# define ZVECT_COMPTYPE 1
|
||||||
|
# define COMP_MAJRELEASE (__GNUC__)
|
||||||
|
# define COMP_MINRELEASE (__GNUC_MINOR__)
|
||||||
|
# define COMP_PATRELEASE (__GNUC_PATCHLEVEL__)
|
||||||
|
#elif defined(_MSC_VER)
|
||||||
|
# define compiler msc
|
||||||
|
# define ZVECT_COMPTYPE 2
|
||||||
|
# define COMP_MAJRELEASE (_MSC_VER)
|
||||||
|
# define COMP_MINRELEASE 0
|
||||||
|
# define COMP_PATRELEASE 0
|
||||||
|
#elif defined(__clang__)
|
||||||
|
# define compiler clang
|
||||||
|
# define ZVECT_COMPTYPE 3
|
||||||
|
# define COMP_MAJRELEASE (__clang_major__)
|
||||||
|
# define COMP_MINRELEASE (__clang_minor__)
|
||||||
|
# define COMP_PATRELEASE (__clang_patchlevel__)
|
||||||
|
#elif defined(__INTEL_COMPILER) || defined(__ICC) || \
|
||||||
|
defined(__ECC) || defined(__ICL)
|
||||||
|
// For intel c compiler please remember to specify:
|
||||||
|
// /Qstd=c99 (on Windows)
|
||||||
|
// -std=c99 on Linux and/or macOS
|
||||||
|
# define compiler intelc
|
||||||
|
# define ZVECT_COMPTYPE 4
|
||||||
|
# define COMP_MAJRELEASE (__INTEL_COMPILER)
|
||||||
|
# define COMP_MINRELEASE 0
|
||||||
|
# define COMP_PATRELEASE 0
|
||||||
|
#elif defined (__LCC__)
|
||||||
|
# define compiler lcc
|
||||||
|
# define ZVECT_COMPTYPE 5
|
||||||
|
# define COMP_MAJRELEASE (__LCC)
|
||||||
|
# define COMP_MINRELEASE 0
|
||||||
|
# define COMP_PATRELEASE 0
|
||||||
|
#elif defined(__NORCROFT_C__) || defined(__CC_NORCROFT) || \
|
||||||
|
defined(__ARMCC_VERSION)
|
||||||
|
// For Norcroft C please remember to specify:
|
||||||
|
// -c99
|
||||||
|
# define compiler norcroftc
|
||||||
|
# define ZVECT_COMPTYPE 6
|
||||||
|
# define COMP_MAJRELEASE (__ARMCC_VERSION)
|
||||||
|
#elif defined(_CRAYC)
|
||||||
|
// For Cray C please remember to specify:
|
||||||
|
// -hc99
|
||||||
|
# define compiler crayc
|
||||||
|
# define ZVECT_COMPTYPE 10
|
||||||
|
# define COMP_MAJRELEASE (_RELEASE)
|
||||||
|
# define COMP_MINRELEASE (_RELEASE_MINOR)
|
||||||
|
# define COMP_PATRELEASE 0
|
||||||
|
#elif defined(__HP_cc)
|
||||||
|
// For HP CC please remember to specify:
|
||||||
|
// -ansi -std=c99
|
||||||
|
# define compiler hpc
|
||||||
|
# define ZVECT_COMPTYPE 11
|
||||||
|
# define COMP_MAJRELEASE 1
|
||||||
|
# define COMP_MINRELEASE 21
|
||||||
|
# define COMP_PATRELEASE 0
|
||||||
|
#elif defined(__IBMC__)
|
||||||
|
// For IBM C please remember to specify:
|
||||||
|
// C99 flags
|
||||||
|
# define compiler ibmc
|
||||||
|
# define ZVECT_COMPTYPE 12
|
||||||
|
#elif defined(__TINYC__)
|
||||||
|
# define compiler tinyc
|
||||||
|
# define ZVECT_COMPTYPE 6
|
||||||
|
# define COMP_MAJRELEASE 0
|
||||||
|
# define COMP_MINRELEASE 0
|
||||||
|
# define COMP_PATRELEASE 0
|
||||||
|
#else
|
||||||
|
# define compiler unknown
|
||||||
|
# define ZVECT_COMPTYPE 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Try to determine CPU Architecture:
|
||||||
|
#if defined(__aarch64__)
|
||||||
|
# define CPU_TYPE ARM64
|
||||||
|
# define Arch64
|
||||||
|
#elif defined(__aarch32__)
|
||||||
|
# define CPU_TYPE ARM32
|
||||||
|
# define Arch32
|
||||||
|
#elif defined(__amd64__) || defined(__x86_64__) || \
|
||||||
|
defined(__ia64__) || defined(_M_IA64) || \
|
||||||
|
defined(_M_AMD64) || defined(_M_X64)
|
||||||
|
# define CPU_TYPE x86_64
|
||||||
|
# define Arch64
|
||||||
|
#else
|
||||||
|
# define CPU_TYPE unknown
|
||||||
|
# define Arch32
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Start setting up macros based on the platform we detected
|
||||||
|
// above.
|
||||||
|
|
||||||
|
#if ( OS_TYPE == 1 )
|
||||||
|
// We are on a Unix-like OS so we can use pthreads!
|
||||||
|
# define MUTEX_TYPE 1
|
||||||
|
# elif ( OS_TYPE == 2 ) && ( defined(__CYGWIN__) || \
|
||||||
|
defined(__MINGW32__) || defined(__MINGW64__) )
|
||||||
|
// We are on MS Windows using CIGWIN so we can use pthreads!
|
||||||
|
# define MUTEX_TYPE 1
|
||||||
|
# elif ( OS_TYPE == 2 ) && ( !defined(__CYGWIN__) && \
|
||||||
|
!defined(__MINGW32__) && !defined(__MINGW64__) )
|
||||||
|
// We are on MS Windows, so we need to use
|
||||||
|
// Windows stuff:
|
||||||
|
# define MUTEX_TYPE 2
|
||||||
|
#else
|
||||||
|
// I have no idea on which platform are we,
|
||||||
|
// hence I have to use fake mutexes and go with the flow!
|
||||||
|
# define MUTEX_TYPE 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // SRC_ZVECTOR_CHECKS_H_
|
|
@ -0,0 +1,84 @@
|
||||||
|
/*
|
||||||
|
* Name: Vector_config
|
||||||
|
* Purpose: Base configuration for the ZVector library
|
||||||
|
* Author: Paolo Fabio Zaino
|
||||||
|
* Domain: General
|
||||||
|
* License: Copyright by Paolo Fabio Zaino, all rights reserved
|
||||||
|
* Distributed under MIT license
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef SRC_ZVECTOR_CONFIG_H_
|
||||||
|
#define SRC_ZVECTOR_CONFIG_H_
|
||||||
|
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||||
|
#pragma once
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Include some standard C lib header
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
// Data alignment configuration
|
||||||
|
#if ( ZVECT_COMPTYPE == 1 )
|
||||||
|
#define ZVECT_DATAALIGN __attribute__((aligned))
|
||||||
|
#define ZVECT_PACKING __attribute__((__packed__))
|
||||||
|
#define ZVECT_ALWAYSINLINE __attribute__ ((__always_inline__))
|
||||||
|
#else
|
||||||
|
#define ZVECT_DATAALIGN
|
||||||
|
#define ZVECT_PACKING
|
||||||
|
#define ZVECT_ALWAYSINLINE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Default vector Index type
|
||||||
|
// This is set to unsigned int of 32bit
|
||||||
|
// size (so all different architectures
|
||||||
|
// and OS behaves in a similar way)
|
||||||
|
// If you want a larger index you can
|
||||||
|
// change it to, for example, uint64_t
|
||||||
|
typedef uint32_t zvect_index;
|
||||||
|
#define zvect_index_max 4294967295 // If you change zvect_index type make sure you update this value
|
||||||
|
// it's the maximum number that can be stored in a zvect_index.
|
||||||
|
|
||||||
|
// Default vector return type for
|
||||||
|
// error codes.
|
||||||
|
// Generally negative numbers identify
|
||||||
|
// an error.
|
||||||
|
// 0 identify completed successful
|
||||||
|
// Positive numbers identify return
|
||||||
|
// attributes, like 1 is generally true
|
||||||
|
typedef int32_t zvect_retval;
|
||||||
|
|
||||||
|
// Default vector storage size
|
||||||
|
// This will be used when the user
|
||||||
|
// specifies 0 (zero) as data type
|
||||||
|
// size.
|
||||||
|
#define ZVECT_DEFAULT_DATA_SIZE sizeof(int)
|
||||||
|
|
||||||
|
// Default vector capacity
|
||||||
|
// This will be used when the user
|
||||||
|
// does NOT specify an Initial Capacity
|
||||||
|
// or set it to 0 (zero):
|
||||||
|
#define ZVECT_INITIAL_CAPACITY 8
|
||||||
|
|
||||||
|
// The following options are handled by Make
|
||||||
|
// So you should not need to modify them here.
|
||||||
|
|
||||||
|
// Choose which type of memory functions you want
|
||||||
|
// to use for your case:
|
||||||
|
// 0 = Use Standard memcpy and memmove
|
||||||
|
// 1 = Use Optimized memcpy and memmove
|
||||||
|
#define ZVECT_MEMX_METHOD 0
|
||||||
|
|
||||||
|
// Enable/Disable thread safe code:
|
||||||
|
#define ZVECT_THREAD_SAFE 1
|
||||||
|
|
||||||
|
// Enable/Disbale reentrant code:
|
||||||
|
#define ZVECT_FULL_REENTRANT 0
|
||||||
|
|
||||||
|
// Enable/Disable DMF Extensions:
|
||||||
|
#define ZVECT_DMF_EXTENSIONS 1
|
||||||
|
|
||||||
|
// Enable/Disable SFMD Extensions:
|
||||||
|
#define ZVECT_SFMD_EXTENSIONS 1
|
||||||
|
|
||||||
|
#endif // SRC_ZVECTOR_CONFIG_H_
|
File diff suppressed because it is too large
Load Diff
|
@ -15,6 +15,7 @@
|
||||||
|
|
||||||
#ifdef OPENDHCPD_ON
|
#ifdef OPENDHCPD_ON
|
||||||
#include "user_errno.h"
|
#include "user_errno.h"
|
||||||
|
#include "libs/misc/sdsalloc.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef OPENDHCPDDNS_ON
|
#ifdef OPENDHCPDDNS_ON
|
||||||
|
@ -46,7 +47,7 @@ static void lwip_init_env() {
|
||||||
|
|
||||||
int main(int argc, char **argv) {
|
int main(int argc, char **argv) {
|
||||||
int ret;
|
int ret;
|
||||||
|
hiredisResetAllocators();
|
||||||
#ifdef OPENDHCPDDNS_ON
|
#ifdef OPENDHCPDDNS_ON
|
||||||
return dual_server_main(argc, argv);
|
return dual_server_main(argc, argv);
|
||||||
#else
|
#else
|
||||||
|
|
Loading…
Reference in New Issue