@@ -134,13 +134,13 @@ bool is_field_numeric(parsertype p, void *e, const char *path)
return false;
}
-void get_field(parsertype p, void *e, const char *path, void *dest)
+void get_field(parsertype p, void *e, const char *path, void *dest, field_type_t type)
{
switch (p) {
case LIBCFG_PARSER:
- return get_field_cfg((config_setting_t *)e, path, dest);
+ return get_field_cfg((config_setting_t *)e, path, dest, type);
case JSON_PARSER:
- return get_field_json((json_object *)e, path, dest);
+ return get_field_json((json_object *)e, path, dest, type);
default:
(void)e;
(void)path;
@@ -325,9 +325,9 @@ static int read_globals_settings(void *elem, void *data)
WARN("Default Namaspace for SWUpdate vars cannot be set, possible side-effects");
}
- get_field(LIBCFG_PARSER, elem, "verbose", &sw->verbose);
- get_field(LIBCFG_PARSER, elem, "loglevel", &sw->loglevel);
- get_field(LIBCFG_PARSER, elem, "syslog", &sw->syslog_enabled);
+ GET_FIELD_INT(LIBCFG_PARSER, elem, "verbose", &sw->verbose);
+ GET_FIELD_INT(LIBCFG_PARSER, elem, "loglevel", &sw->loglevel);
+ GET_FIELD_BOOL(LIBCFG_PARSER, elem, "syslog", &sw->syslog_enabled);
GET_FIELD_STRING(LIBCFG_PARSER, elem,
"no-downgrading", sw->minimum_version);
tmp[0] = '\0';
@@ -106,11 +106,11 @@ static int download_settings(void *elem, void __attribute__ ((__unused__)) *dat
opt->auth = NULL;
}
- get_field(LIBCFG_PARSER, elem, "retries",
+ GET_FIELD_INT(LIBCFG_PARSER, elem, "retries",
&opt->retries);
- get_field(LIBCFG_PARSER, elem, "retrywait",
+ GET_FIELD_INT(LIBCFG_PARSER, elem, "retrywait",
&opt->retry_sleep);
- get_field(LIBCFG_PARSER, elem, "timeout",
+ GET_FIELD_INT(LIBCFG_PARSER, elem, "timeout",
&opt->low_speed_timeout);
return 0;
@@ -19,9 +19,30 @@
#include "util.h"
#include "parselib.h"
-static void get_value_libconfig(const config_setting_t *e, void *dest)
+static unsigned int map_field_type(field_type_t type)
+{
+ switch (type) {
+ case TYPE_INT:
+ return CONFIG_TYPE_INT;
+ case TYPE_INT64:
+ return CONFIG_TYPE_INT64;
+ case TYPE_STRING:
+ return CONFIG_TYPE_STRING;
+ case TYPE_BOOL:
+ return CONFIG_TYPE_BOOL;
+ case TYPE_FLOAT:
+ return CONFIG_TYPE_FLOAT;
+ default: /* not supported in SWUpdate */
+ return CONFIG_TYPE_NONE;
+ }
+}
+
+
+static void get_value_libconfig(const config_setting_t *e, void *dest, field_type_t expected_type)
{
int type = config_setting_type(e);
+ if (type != map_field_type(expected_type))
+ return;
switch (type) {
case CONFIG_TYPE_INT:
*(int *)dest = config_setting_get_int(e);
@@ -91,7 +112,7 @@ bool is_field_numeric_cfg(config_setting_t *e, const char *path)
type == CONFIG_TYPE_FLOAT;
}
-void get_field_cfg(config_setting_t *e, const char *path, void *dest)
+void get_field_cfg(config_setting_t *e, const char *path, void *dest, field_type_t type)
{
config_setting_t *elem;
@@ -103,7 +124,7 @@ void get_field_cfg(config_setting_t *e, const char *path, void *dest)
if (!elem)
return;
- get_value_libconfig(elem, dest);
+ get_value_libconfig(elem, dest, type);
}
const char *get_field_string_libconfig(config_setting_t *e, const char *path)
@@ -21,6 +21,23 @@
#define MAX_URL_LENGTH 2048
+static json_type map_field_type(field_type_t type)
+{
+ switch (type) {
+ case TYPE_INT:
+ case TYPE_INT64:
+ return json_type_int;
+ case TYPE_STRING:
+ return json_type_string;
+ case TYPE_BOOL:
+ return json_type_boolean;
+ case TYPE_FLOAT:
+ return json_type_double;
+ default: /* not supported in SWUpdate */
+ return json_type_null;
+ }
+}
+
json_object *find_json_recursive_node(json_object *root, const char **names)
{
json_object *node = root;
@@ -102,10 +119,12 @@ const char *get_field_string_json(json_object *e, const char *path)
return NULL;
}
-static void get_value_json(json_object *e, void *dest)
+static void get_value_json(json_object *e, void *dest, field_type_t expected_type)
{
enum json_type type;
type = json_object_get_type(e);
+ if (type != map_field_type(expected_type))
+ return;
switch (type) {
case json_type_boolean:
*(unsigned int *)dest = json_object_get_boolean(e);
@@ -141,15 +160,15 @@ bool is_field_numeric_json(json_object *e, const char *path)
type == json_type_double;
}
-void get_field_json(json_object *e, const char *path, void *dest)
+void get_field_json(json_object *e, const char *path, void *dest, field_type_t type)
{
json_object *fld = NULL;
if (path) {
if (json_object_object_get_ex(e, path, &fld))
- get_value_json(fld, dest);
+ get_value_json(fld, dest, type);
} else {
- get_value_json(e, dest);
+ get_value_json(e, dest, type);
}
}
@@ -20,7 +20,7 @@ int channel_settings(void *elem, void *data)
char tmp[128];
channel_data_t *chan = (channel_data_t *)data;
- get_field(LIBCFG_PARSER, elem, "retry",
+ GET_FIELD_INT(LIBCFG_PARSER, elem, "retry",
&chan->retries);
GET_FIELD_STRING_RESET(LIBCFG_PARSER, elem, "max-download-speed", tmp);
@@ -95,8 +95,8 @@ static int get_run_as(void *elem, void *data)
{
struct run_as *pid = (struct run_as *)data;
- get_field(LIBCFG_PARSER, elem, "userid", &pid->userid);
- get_field(LIBCFG_PARSER, elem, "groupid", &pid->groupid);
+ GET_FIELD_INT(LIBCFG_PARSER, elem, "userid", &pid->userid);
+ GET_FIELD_INT(LIBCFG_PARSER, elem, "groupid", &pid->groupid);
return 0;
}
@@ -15,6 +15,14 @@ typedef enum {
JSON_PARSER
} parsertype;
+typedef enum {
+ TYPE_INT,
+ TYPE_INT64,
+ TYPE_STRING,
+ TYPE_BOOL,
+ TYPE_FLOAT
+} field_type_t;
+
typedef void (*iterate_callback)(const char *name, const char *value,
void *data);
@@ -33,7 +41,7 @@ typedef void (*iterate_callback)(const char *name, const char *value,
#endif
bool is_field_numeric_cfg(config_setting_t *e, const char *path);
-void get_field_cfg(config_setting_t *e, const char *path, void *dest);
+void get_field_cfg(config_setting_t *e, const char *path, void *dest, field_type_t type);
void *get_child_libconfig(void *e, const char *name);
void iterate_field_libconfig(config_setting_t *e, iterate_callback cb,
void *data);
@@ -49,7 +57,7 @@ void *get_node_libconfig(config_t *cfg, const char **nodes);
#define get_field_string_libconfig(e, path) (NULL)
#define get_child_libconfig(e, name) (NULL)
#define iterate_field_libconfig(e, cb, data) { }
-#define get_field_cfg(e, path, dest)
+#define get_field_cfg(e, path, dest, type)
#define find_root_libconfig(cfg, nodes, depth) (NULL)
#define get_node_libconfig(cfg, nodes) (NULL)
#define is_field_numeric_cfg(e, path) (false)
@@ -59,7 +67,7 @@ void *get_node_libconfig(config_t *cfg, const char **nodes);
bool is_field_numeric_json(json_object *e, const char *path);
const char *get_field_string_json(json_object *e, const char *path);
-void get_field_json(json_object *e, const char *path, void *dest);
+void get_field_json(json_object *e, const char *path, void *dest, field_type_t type);
void *get_child_json(json_object *e, const char *name);
void iterate_field_json(json_object *e, iterate_callback cb, void *data);
json_object *find_json_recursive_node(json_object *root, const char **names);
@@ -79,7 +87,7 @@ int get_array_length(parsertype p, void *root);
void *get_elem_from_idx(parsertype p, void *node, int idx);
void *get_child(parsertype p, void *node, const char *name);
void iterate_field(parsertype p, void *e, iterate_callback cb, void *data);
-void get_field(parsertype p, void *e, const char *path, void *dest);
+void get_field(parsertype p, void *e, const char *path, void *dest, field_type_t type);
int exist_field_string(parsertype p, void *e, const char *path);
void get_hash_value(parsertype p, void *elem, unsigned char *hash);
void check_field_string(const char *src, char *dst, const size_t max_len);
@@ -94,3 +102,15 @@ bool set_find_path(const char **nodes, const char *newpath, char **tmp);
d[0] = '\0'; \
GET_FIELD_STRING(p, e, name, d); \
} while (0)
+
+#define GET_FIELD_BOOL(p, e, path, dest) \
+ get_field(p, e, path, dest, TYPE_BOOL)
+
+#define GET_FIELD_INT(p, e, path, dest) \
+ get_field(p, e, path, dest, TYPE_INT)
+
+#define GET_FIELD_INT64(p, e, path, dest) \
+ get_field(p, e, path, dest, TYPE_INT64)
+
+#define GET_FIELD_FLOAT(p, e, path, dest) \
+ get_field(p, e, path, dest, TYPE_FLOAT)
@@ -741,7 +741,7 @@ static int mongoose_settings(void *elem, void __attribute__ ((__unused__)) *dat
opts->root = strdup(tmp);
}
- get_field(LIBCFG_PARSER, elem, "enable_directory_listing",
+ GET_FIELD_BOOL(LIBCFG_PARSER, elem, "enable_directory_listing",
&opts->listing);
GET_FIELD_STRING_RESET(LIBCFG_PARSER, elem, "listening_ports", tmp);
@@ -768,9 +768,9 @@ static int mongoose_settings(void *elem, void __attribute__ ((__unused__)) *dat
if (strlen(tmp)) {
opts->auth_domain = strdup(tmp);
}
- get_field(LIBCFG_PARSER, elem, "run-postupdate", &run_postupdate);
+ GET_FIELD_BOOL(LIBCFG_PARSER, elem, "run-postupdate", &run_postupdate);
- get_field(LIBCFG_PARSER, elem, "timeout", &watchdog_conn);
+ GET_FIELD_INT(LIBCFG_PARSER, elem, "timeout", &watchdog_conn);
return 0;
}
@@ -195,7 +195,7 @@ static bool get_common_fields(parsertype p, void *cfg, struct swupdate_cfg *swcf
} else {
swcfg->bootloader_state_marker = true;
if((setting = find_node(p, cfg, "bootloader_state_marker", swcfg)) != NULL) {
- get_field(p, setting, NULL, &swcfg->bootloader_state_marker);
+ GET_FIELD_BOOL(p, setting, NULL, &swcfg->bootloader_state_marker);
TRACE("Setting bootloader state marker: %s",
swcfg->bootloader_state_marker == true ? "true" : "false");
}
@@ -206,7 +206,7 @@ static bool get_common_fields(parsertype p, void *cfg, struct swupdate_cfg *swcf
} else {
swcfg->bootloader_transaction_marker = true;
if((setting = find_node(p, cfg, "bootloader_transaction_marker", swcfg)) != NULL) {
- get_field(p, setting, NULL, &swcfg->bootloader_transaction_marker);
+ GET_FIELD_BOOL(p, setting, NULL, &swcfg->bootloader_transaction_marker);
TRACE("Setting bootloader transaction marker: %s",
swcfg->bootloader_transaction_marker == true ? "true" : "false");
}
@@ -217,7 +217,7 @@ static bool get_common_fields(parsertype p, void *cfg, struct swupdate_cfg *swcf
*/
swcfg->reboot_required = true;
if((setting = find_node(p, cfg, "reboot", swcfg)) != NULL) {
- get_field(p, setting, NULL, &swcfg->reboot_required);
+ GET_FIELD_BOOL(p, setting, NULL, &swcfg->reboot_required);
}
TRACE("reboot_required %d", swcfg->reboot_required);
@@ -230,7 +230,6 @@ static bool get_common_fields(parsertype p, void *cfg, struct swupdate_cfg *swcf
TRACE("Output file set but not enabled with -o, ignored");
} else {
GET_FIELD_STRING(p, setting, NULL, swcfg->output);
- get_field(p, setting, NULL, &swcfg->output);
TRACE("Incoming SWU stored : %s", swcfg->output);
}
}
@@ -428,7 +427,7 @@ static int parse_common_attributes(parsertype p, void *elem, struct img_type *im
* multiplier suffixes are allowed
*/
if (is_field_numeric(p, elem, "offset")) {
- get_field(p, elem, "offset", &offset);
+ GET_FIELD_INT64(p, elem, "offset", &offset);
image->seek = offset;
} else {
GET_FIELD_STRING(p, elem, "offset", seek_str);
@@ -450,13 +449,15 @@ static int parse_common_attributes(parsertype p, void *elem, struct img_type *im
return -1;
}
} else {
- get_field(p, elem, "compressed", &image->compressed);
+ bool img_compressed = false;
+ GET_FIELD_BOOL(p, elem, "compressed", &img_compressed);
+ image->compressed = img_compressed ? COMPRESSED_TRUE : COMPRESSED_FALSE;
}
- get_field(p, elem, "installed-directly", &image->install_directly);
- get_field(p, elem, "preserve-attributes", &image->preserve_attributes);
- get_field(p, elem, "install-if-different", &image->id.install_if_different);
- get_field(p, elem, "install-if-higher", &image->id.install_if_higher);
- get_field(p, elem, "encrypted", &image->is_encrypted);
+ GET_FIELD_BOOL(p, elem, "installed-directly", &image->install_directly);
+ GET_FIELD_BOOL(p, elem, "preserve-attributes", &image->preserve_attributes);
+ GET_FIELD_BOOL(p, elem, "install-if-different", &image->id.install_if_different);
+ GET_FIELD_BOOL(p, elem, "install-if-higher", &image->id.install_if_higher);
+ GET_FIELD_BOOL(p, elem, "encrypted", &image->is_encrypted);
GET_FIELD_STRING(p, elem, "ivt", image->ivt_ascii);
if (is_image_installed(&cfg->installed_sw_list, image)) {
@@ -521,7 +522,7 @@ static int _parse_partitions(parsertype p, void *cfg, void *setting, const char
return -1;
}
- get_field(p, elem, "size", &partition->partsize);
+ GET_FIELD_INT64(p, elem, "size", &partition->partsize);
add_properties(p, elem, partition);
@@ -591,7 +591,7 @@ static int server_general_settings(void *elem, void __attribute__ ((__unused__)
SETSTRING(server_general.logurl, tmp);
}
- get_field(LIBCFG_PARSER, elem, "polldelay",
+ GET_FIELD_INT(LIBCFG_PARSER, elem, "polldelay",
&server_general.polling_interval);
channel_settings(elem, &channel_data_defaults);
@@ -1726,18 +1726,18 @@ static int server_hawkbit_settings(void *elem, void __attribute__ ((__unused__)
mandatory_argument_count |= URL_BIT;
}
- get_field(LIBCFG_PARSER, elem, "polldelay",
+ GET_FIELD_INT(LIBCFG_PARSER, elem, "polldelay",
&server_hawkbit.polling_interval);
- get_field(LIBCFG_PARSER, elem, "initial-report-resend-period",
+ GET_FIELD_INT(LIBCFG_PARSER, elem, "initial-report-resend-period",
&server_hawkbit.initial_report_resend_period);
channel_settings(elem, &channel_data_defaults);
- get_field(LIBCFG_PARSER, elem, "usetokentodwl",
+ GET_FIELD_BOOL(LIBCFG_PARSER, elem, "usetokentodwl",
&server_hawkbit.usetokentodwl);
- get_field(LIBCFG_PARSER, elem, "connection-timeout",
+ GET_FIELD_INT(LIBCFG_PARSER, elem, "connection-timeout",
&channel_data_defaults.connection_timeout);
GET_FIELD_STRING_RESET(LIBCFG_PARSER, elem, "targettoken", tmp);
@@ -167,7 +167,7 @@ static server_op_res_t suricatta_ipc(int fd)
static int suricatta_settings(void *elem, void __attribute__ ((__unused__)) *data)
{
- get_field(LIBCFG_PARSER, elem, "enable",
+ GET_FIELD_BOOL(LIBCFG_PARSER, elem, "enable",
&enable);
char cfg_server[128];
Attributes in sw-description are strictly typed and SWUpdate expects to get values for the defined type. With the exception of strings, attributes are parsed using a generic get_field() function, that retrieves the value in the format set into sw-description, that can differ from the expected one. Add a set of macros to be used and to replace the generic get_field, that is GET_FIELD_<type>, like GET_FIELD_STRING that already exists, and checks for type before retrieving the value. Signed-off-by: Stefano Babic <stefano.babic@swupdate.org> --- core/parsing_library.c | 6 +++--- core/swupdate.c | 6 +++--- corelib/downloader.c | 6 +++--- corelib/parsing_library_libconfig.c | 27 ++++++++++++++++++++++++--- corelib/parsing_library_libjson.c | 27 +++++++++++++++++++++++---- corelib/server_utils.c | 2 +- corelib/swupdate_settings.c | 4 ++-- include/parselib.h | 28 ++++++++++++++++++++++++---- mongoose/mongoose_interface.c | 6 +++--- parser/parser.c | 25 +++++++++++++------------ suricatta/server_general.c | 2 +- suricatta/server_hawkbit.c | 8 ++++---- suricatta/suricatta.c | 2 +- 13 files changed, 105 insertions(+), 44 deletions(-) -- 2.34.1