static dbus_bool_t ni_objectmodel_ethtool_set_priv_flags(ni_dbus_object_t *object, const ni_dbus_property_t *property, const ni_dbus_variant_t *argument, DBusError *error) { const ni_dbus_variant_t *dict; ni_ethtool_t *ethtool; unsigned int i, len; dbus_bool_t enabled; ni_stringbuf_t buf; const char *name; if (!ni_dbus_variant_is_dict_array(argument)) return FALSE; if (!(ethtool = ni_objectmodel_ethtool_write_handle(object, error))) return FALSE; ni_ethtool_priv_flags_free(ethtool->priv_flags); if (!(ethtool->priv_flags = ni_ethtool_priv_flags_new())) return FALSE; if ((len = argument->array.len) > 32) len = 32; ni_stringbuf_init(&buf); for (i = 0; i < argument->array.len; ++i) { dict = &argument->variant_array_value[i]; if (!ni_dbus_variant_is_dict(dict)) continue; if (!ni_dbus_dict_get_string(dict, "name", &name) || !ni_dbus_dict_get_bool(dict, "enabled", &enabled)) continue; ni_stringbuf_put(&buf, name, ni_string_len(name)); ni_stringbuf_trim_head(&buf, " \t\n"); ni_stringbuf_trim_tail(&buf, " \t\n"); if (ni_string_empty(buf.string)) continue; if (ni_string_array_append(ðtool->priv_flags->names, buf.string) == 0) { if (enabled) ethtool->priv_flags->bitmap |= NI_BIT(i); } ni_stringbuf_destroy(&buf); } return TRUE; }
static inline int ni_ethtool_get_priv_flags_names(const char *ifname, ni_ethtool_t *ethtool, ni_string_array_t *names) { struct ethtool_gstrings *gstrings; unsigned int count, i; ni_stringbuf_t buf; const char *name; count = ni_ethtool_get_gstring_count(ifname, " priv-flags count", ETH_SS_PRIV_FLAGS); if (!count) { if (errno == EOPNOTSUPP && ethtool->driver_info) count = ethtool->driver_info->supports.n_priv_flags; if (!count) { ni_ethtool_set_supported(ethtool, NI_ETHTOOL_SUPP_GET_PRIV_FLAGS, FALSE); return -EOPNOTSUPP; } } if (count > 32) count = 32; gstrings = ni_ethtool_get_gstrings(ifname, " priv-flags names", ETH_SS_PRIV_FLAGS, count); if (!gstrings) { if (errno == EOPNOTSUPP) ni_ethtool_set_supported(ethtool, NI_ETHTOOL_SUPP_GET_PRIV_FLAGS, FALSE); free(gstrings); return errno ? -errno : -1; } ni_stringbuf_init(&buf); for (i = 0; i < gstrings->len; ++i) { name = (const char *)(gstrings->data + i * ETH_GSTRING_LEN); ni_stringbuf_put(&buf, name, ETH_GSTRING_LEN); ni_stringbuf_trim_head(&buf, " \t\n"); ni_stringbuf_trim_tail(&buf, " \t\n"); ni_string_array_append(names, buf.string); ni_stringbuf_destroy(&buf); } free(gstrings); if (names->count == count) return 0; ni_string_array_destroy(names); return -ENOMEM; /* array append */ }