diff options
Diffstat (limited to 'libnm-core/nm-utils.c')
| -rw-r--r-- | libnm-core/nm-utils.c | 177 |
1 files changed, 122 insertions, 55 deletions
diff --git a/libnm-core/nm-utils.c b/libnm-core/nm-utils.c index 6cc92ec8..ebbbfd3a 100644 --- a/libnm-core/nm-utils.c +++ b/libnm-core/nm-utils.c @@ -36,6 +36,7 @@ #include <linux/pkt_sched.h> #if WITH_JANSSON +#include "nm-json.h" #include <jansson.h> #endif @@ -650,36 +651,82 @@ _nm_utils_ptrarray_find_first (gconstpointer *list, gssize len, gconstpointer ne } gssize -_nm_utils_ptrarray_find_binary_search (gconstpointer *list, gsize len, gconstpointer needle, GCompareDataFunc cmpfcn, gpointer user_data) -{ - gssize imin, imax, imid; +_nm_utils_ptrarray_find_binary_search (gconstpointer *list, + gsize len, + gconstpointer needle, + GCompareDataFunc cmpfcn, + gpointer user_data, + gssize *out_idx_first, + gssize *out_idx_last) +{ + gssize imin, imax, imid, i2min, i2max, i2mid; int cmp; g_return_val_if_fail (list || !len, ~((gssize) 0)); g_return_val_if_fail (cmpfcn, ~((gssize) 0)); imin = 0; - if (len == 0) - return ~imin; - - imax = len - 1; - - while (imin <= imax) { - imid = imin + (imax - imin) / 2; - - cmp = cmpfcn (list[imid], needle, user_data); - if (cmp == 0) - return imid; + if (len > 0) { + imax = len - 1; + + while (imin <= imax) { + imid = imin + (imax - imin) / 2; + + cmp = cmpfcn (list[imid], needle, user_data); + if (cmp == 0) { + /* we found a matching entry at index imid. + * + * Does the caller request the first/last index as well (in case that + * there are multiple entries which compare equal). */ + + if (out_idx_first) { + i2min = imin; + i2max = imid + 1; + while (i2min <= i2max) { + i2mid = i2min + (i2max - i2min) / 2; + + cmp = cmpfcn (list[i2mid], needle, user_data); + if (cmp == 0) + i2max = i2mid -1; + else { + nm_assert (cmp < 0); + i2min = i2mid + 1; + } + } + *out_idx_first = i2min; + } + if (out_idx_last) { + i2min = imid + 1; + i2max = imax; + while (i2min <= i2max) { + i2mid = i2min + (i2max - i2min) / 2; + + cmp = cmpfcn (list[i2mid], needle, user_data); + if (cmp == 0) + i2min = i2mid + 1; + else { + nm_assert (cmp > 0); + i2max = i2mid - 1; + } + } + *out_idx_last = i2min - 1; + } + return imid; + } - if (cmp < 0) - imin = imid + 1; - else - imax = imid - 1; + if (cmp < 0) + imin = imid + 1; + else + imax = imid - 1; + } } /* return the inverse of @imin. This is a negative number, but * also is ~imin the position where the value should be inserted. */ - return ~imin; + imin = ~imin; + NM_SET_OUT (out_idx_first, imin); + NM_SET_OUT (out_idx_last, imin); + return imin; } gssize @@ -4845,6 +4892,41 @@ const char **nm_utils_enum_get_values (GType type, gint from, gint to) /*****************************************************************************/ +static gboolean +_nm_utils_is_json_object_no_validation (const char *str, GError **error) +{ + if (str) { + /* libjansson also requires only utf-8 encoding. */ + if (!g_utf8_validate (str, -1, NULL)) { + g_set_error_literal (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("not valid utf-8")); + return FALSE; + } + while (g_ascii_isspace (str[0])) + str++; + } + + /* do some very basic validation to see if this might be a JSON object. */ + if (str[0] == '{') { + gsize l; + + l = strlen (str) - 1; + while (l > 0 && g_ascii_isspace (str[l])) + l--; + + if (str[l] == '}') + return TRUE; + } + + g_set_error_literal (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("is not a JSON object")); + return FALSE; +} + #if WITH_JANSSON /* Added in Jansson v2.3 (released Jan 27 2012) */ @@ -5151,9 +5233,9 @@ _json_team_normalize_defaults (json_t *json, gboolean reset) _json_delete_object_on_string_match (json, "runner", "hwaddr_policy", NULL, NM_SETTING_TEAM_RUNNER_HWADDR_POLICY_DEFAULT); } else if (nm_streq (runner, NM_SETTING_TEAM_RUNNER_LACP)) { - runner_tx_balancer_interval = 50; + runner_tx_balancer_interval = NM_SETTING_TEAM_RUNNER_TX_BALANCER_INTERVAL_DEFAULT; runner_active = TRUE; - runner_sys_prio = 255; + runner_sys_prio = NM_SETTING_TEAM_RUNNER_SYS_PRIO_DEFAULT; runner_min_ports = 0; _json_delete_object_on_string_match (json, "runner", "agg_select_policy", NULL, NM_SETTING_TEAM_RUNNER_AGG_SELECT_POLICY_DEFAULT); @@ -5185,13 +5267,16 @@ _nm_utils_team_link_watcher_from_json (json_t *json_element) g_return_val_if_fail (json_element, NULL); json_object_foreach (json_element, j_key, j_val) { - if (nm_streq (j_key, "name")) + if (nm_streq (j_key, "name")) { + g_free (name); name = strdup (json_string_value (j_val)); - else if (nm_streq (j_key, "target_host")) + } else if (nm_streq (j_key, "target_host")) { + g_free (target_host); target_host = strdup (json_string_value (j_val)); - else if (nm_streq (j_key, "source_host")) + } else if (nm_streq (j_key, "source_host")) { + g_free (source_host); source_host = strdup (json_string_value (j_val)); - else if (NM_IN_STRSET (j_key, "delay_up", "init_wait")) + } else if (NM_IN_STRSET (j_key, "delay_up", "init_wait")) val1 = json_integer_value (j_val); else if (NM_IN_STRSET (j_key, "delay_down", "interval")) val2 = json_integer_value (j_val); @@ -5314,6 +5399,9 @@ nm_utils_is_json_object (const char *str, GError **error) return FALSE; } + if (!nm_jansson_load ()) + return _nm_utils_is_json_object_no_validation (str, error); + json = json_loads (str, JSON_REJECT_DUPLICATES, &jerror); if (!json) { g_set_error (error, @@ -5364,6 +5452,8 @@ _nm_utils_team_config_equal (const char *conf1, if (nm_streq0 (conf1, conf2)) return TRUE; + else if (!nm_jansson_load ()) + return FALSE; /* A NULL configuration is equivalent to default value '{}' */ json1 = json_loads (conf1 ?: "{}", JSON_REJECT_DUPLICATES, &jerror); @@ -5421,6 +5511,9 @@ _nm_utils_team_config_get (const char *conf, if (!key) return NULL; + if (!nm_jansson_load ()) + return NULL; + json = json_loads (conf ?: "{}", JSON_REJECT_DUPLICATES, &jerror); /* Invalid json in conf */ @@ -5528,6 +5621,9 @@ _nm_utils_team_config_set (char **conf, g_return_val_if_fail (key, FALSE); + if (!nm_jansson_load ()) + return FALSE; + json = json_loads (*conf?: "{}", JSON_REJECT_DUPLICATES, &jerror); if (!json) return FALSE; @@ -5645,19 +5741,6 @@ nm_utils_is_json_object (const char *str, GError **error) { g_return_val_if_fail (!error || !*error, FALSE); - if (str) { - /* libjansson also requires only utf-8 encoding. */ - if (!g_utf8_validate (str, -1, NULL)) { - g_set_error_literal (error, - NM_CONNECTION_ERROR, - NM_CONNECTION_ERROR_INVALID_PROPERTY, - _("not valid utf-8")); - return FALSE; - } - while (g_ascii_isspace (str[0])) - str++; - } - if (!str || !str[0]) { g_set_error_literal (error, NM_CONNECTION_ERROR, @@ -5666,23 +5749,7 @@ nm_utils_is_json_object (const char *str, GError **error) return FALSE; } - /* do some very basic validation to see if this might be a JSON object. */ - if (str[0] == '{') { - gsize l; - - l = strlen (str) - 1; - while (l > 0 && g_ascii_isspace (str[l])) - l--; - - if (str[l] == '}') - return TRUE; - } - - g_set_error_literal (error, - NM_CONNECTION_ERROR, - NM_CONNECTION_ERROR_INVALID_PROPERTY, - _("is not a JSON object")); - return FALSE; + return _nm_utils_is_json_object_no_validation (str, error); } gboolean |