SR_PRIV int sr_variant_type_check(uint32_t key, GVariant *value) { const struct sr_key_info *info; const GVariantType *type, *expected; char *expected_string, *type_string; info = sr_key_info_get(SR_KEY_CONFIG, key); if (!info) return SR_OK; expected = sr_variant_type_get(info->datatype); type = g_variant_get_type(value); if (!g_variant_type_equal(type, expected) && !g_variant_type_is_subtype_of(type, expected)) { expected_string = g_variant_type_dup_string(expected); type_string = g_variant_type_dup_string(type); sr_err("Wrong variant type for key '%s': expected '%s', got '%s'", info->name, expected_string, type_string); g_free(expected_string); g_free(type_string); return SR_ERR_ARG; } return SR_OK; }
/** * secret_prompt_perform_finish: * @self: a prompt * @result: the asynchronous result passed to the callback * @error: location to place an error on failure * * Complete asynchronous operation to run a prompt and perform the prompting. * * Returns a variant result if the prompt was completed and not dismissed. The * type of result depends on the action the prompt is completing, and is * defined in the Secret Service DBus API specification. * * Returns: (transfer full): %NULL if the prompt was dismissed or an error occurred, * a variant result if the prompt was successful */ GVariant * secret_prompt_perform_finish (SecretPrompt *self, GAsyncResult *result, GError **error) { PerformClosure *closure; GSimpleAsyncResult *res; gchar *string; g_return_val_if_fail (SECRET_IS_PROMPT (self), NULL); g_return_val_if_fail (error == NULL || *error == NULL, NULL); g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (self), secret_prompt_perform), NULL); res = G_SIMPLE_ASYNC_RESULT (result); if (_secret_util_propagate_error (res, error)) return NULL; closure = g_simple_async_result_get_op_res_gpointer (res); if (closure->result == NULL) return NULL; if (closure->return_type != NULL && !g_variant_is_of_type (closure->result, closure->return_type)) { string = g_variant_type_dup_string (closure->return_type); g_warning ("received unexpected result type %s from Completed signal instead of expected %s", g_variant_get_type_string (closure->result), string); g_free (string); return NULL; } return g_variant_ref (closure->result); }
static GVariant * go_conf_get (GOConfNode *node, gchar const *key, GVariantType const *t) { GVariant *res = g_settings_get_value (node->settings, key); if (res == NULL) { d (g_warning ("Unable to load key '%s'", key)); return NULL; } if (!g_variant_is_of_type (res, t)) { char *tstr = g_variant_type_dup_string (t); g_warning ("Expected `%s' got `%s' for key %s", tstr, g_variant_get_type_string (res), key); g_free (tstr); g_variant_unref (res); return NULL; } return res; }
static void start_element (GMarkupParseContext *context, const gchar *element_name, const gchar **attribute_names, const gchar **attribute_values, gpointer user_data, GError **error) { ParseState *state = user_data; const GSList *element_stack; const gchar *container; element_stack = g_markup_parse_context_get_element_stack (context); container = element_stack->next ? element_stack->next->data : NULL; #define COLLECT(first, ...) \ g_markup_collect_attributes (element_name, \ attribute_names, attribute_values, error, \ first, __VA_ARGS__, G_MARKUP_COLLECT_INVALID) #define OPTIONAL G_MARKUP_COLLECT_OPTIONAL #define STRDUP G_MARKUP_COLLECT_STRDUP #define STRING G_MARKUP_COLLECT_STRING #define NO_ATTRS() COLLECT (G_MARKUP_COLLECT_INVALID, NULL) if (container == NULL) { if (strcmp (element_name, "schemalist") == 0) { COLLECT (OPTIONAL | STRDUP, "gettext-domain", &state->schemalist_domain); return; } } else if (strcmp (container, "schemalist") == 0) { if (strcmp (element_name, "schema") == 0) { const gchar *id, *path; if (COLLECT (STRING, "id", &id, OPTIONAL | STRING, "path", &path, OPTIONAL | STRDUP, "gettext-domain", &state->schema_domain)) { if (!g_hash_table_lookup (state->schemas, id)) { state->schema = gvdb_hash_table_new (state->schemas, id); state->schema_root = gvdb_hash_table_insert (state->schema, ""); if (path != NULL) gvdb_hash_table_insert_string (state->schema, ".path", path); } else g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, "<schema id='%s'> already specified", id); } return; } } else if (strcmp (container, "schema") == 0) { if (strcmp (element_name, "key") == 0) { const gchar *name, *type; if (COLLECT (STRING, "name", &name, STRING, "type", &type)) { if (!is_valid_keyname (name, error)) return; if (!g_hash_table_lookup (state->schema, name)) { state->key = gvdb_hash_table_insert (state->schema, name); gvdb_item_set_parent (state->key, state->schema_root); } else { g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, "<key name='%s'> already specified", name); return; } if (g_variant_type_string_is_valid (type)) state->type = g_variant_type_new (type); else { g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, "invalid GVariant type string '%s'", type); return; } g_variant_builder_init (&state->key_options, G_VARIANT_TYPE ("a{sv}")); } return; } else if (strcmp (element_name, "child") == 0) { const gchar *name, *schema; if (COLLECT (STRING, "name", &name, STRING, "schema", &schema)) { gchar *childname; if (!is_valid_keyname (name, error)) return; childname = g_strconcat (name, "/", NULL); if (!g_hash_table_lookup (state->schema, childname)) gvdb_hash_table_insert_string (state->schema, childname, schema); else g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, "<child name='%s'> already specified", name); g_free (childname); return; } } } else if (strcmp (container, "key") == 0) { if (strcmp (element_name, "default") == 0) { const gchar *l10n; if (COLLECT (STRING | OPTIONAL, "l10n", &l10n, STRDUP | OPTIONAL, "context", &state->context)) { if (l10n != NULL) { if (!g_hash_table_lookup (state->schema, ".gettext-domain")) { const gchar *domain = state->schema_domain ? state->schema_domain : state->schemalist_domain; if (domain == NULL) { g_set_error_literal (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, "l10n requested, but no " "gettext domain given"); return; } gvdb_hash_table_insert_string (state->schema, ".gettext-domain", domain); if (strcmp (l10n, "messages") == 0) state->l10n = 'm'; else if (strcmp (l10n, "time") == 0) state->l10n = 't'; else { g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, "unsupported l10n category: %s", l10n); return; } } } else { state->l10n = '\0'; if (state->context != NULL) { g_set_error_literal (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, "translation context given for " " value without l10n enabled"); return; } } state->string = g_string_new (NULL); } return; } else if (strcmp (element_name, "summary") == 0 || strcmp (element_name, "description") == 0) { state->string = g_string_new (NULL); NO_ATTRS (); return; } else if (strcmp (element_name, "range") == 0) { const gchar *min_str, *max_str; if (!type_allows_range (state->type)) { gchar *type = g_variant_type_dup_string (state->type); g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, "Element <%s> not allowed for keys of type \"%s\"\n", element_name, type); g_free (type); return; } if (!COLLECT (STRING, "min", &min_str, STRING, "max", &max_str)) return; state->min = g_variant_parse (state->type, min_str, NULL, NULL, error); if (state->min == NULL) return; state->max = g_variant_parse (state->type, max_str, NULL, NULL, error); if (state->max == NULL) return; if (g_variant_compare (state->min, state->max) > 0) { g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, "Element <%s> specified minimum is greater than maxmimum", element_name); return; } g_variant_builder_add (&state->key_options, "{sv}", "range", g_variant_new ("(@?@?)", state->min, state->max)); return; } else if (strcmp (element_name, "choices") == 0) { if (!type_allows_choices (state->type)) { gchar *type = g_variant_type_dup_string (state->type); g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, "Element <%s> not allowed for keys of type \"%s\"\n", element_name, type); g_free (type); return; } state->choices = g_string_new ("\xff"); NO_ATTRS (); return; } } else if (strcmp (container, "choices") == 0) { if (strcmp (element_name, "choice") == 0) { const gchar *value; if (COLLECT (STRING, "value", &value)) g_string_append_printf (state->choices, "%s\xff", value); return; } } if (container) g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_UNKNOWN_ELEMENT, "Element <%s> not allowed inside <%s>\n", element_name, container); else g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_UNKNOWN_ELEMENT, "Element <%s> not allowed at toplevel\n", element_name); }
/** * g_dbus_method_invocation_return_value: * @invocation: A #GDBusMethodInvocation. * @parameters: A #GVariant tuple with out parameters for the method or %NULL if not passing any parameters. * * Finishes handling a D-Bus method call by returning @parameters. * If the @parameters GVariant is floating, it is consumed. * * It is an error if @parameters is not of the right format. * * This method will free @invocation, you cannot use it afterwards. * * Since: 2.26 */ void g_dbus_method_invocation_return_value (GDBusMethodInvocation *invocation, GVariant *parameters) { GDBusMessage *reply; GError *error; g_return_if_fail (G_IS_DBUS_METHOD_INVOCATION (invocation)); g_return_if_fail ((parameters == NULL) || g_variant_is_of_type (parameters, G_VARIANT_TYPE_TUPLE)); if (parameters == NULL) parameters = g_variant_new_tuple (NULL, 0); /* if we have introspection data, check that the signature of @parameters is correct */ if (invocation->method_info != NULL) { GVariantType *type; type = _g_dbus_compute_complete_signature (invocation->method_info->out_args); if (!g_variant_is_of_type (parameters, type)) { gchar *type_string = g_variant_type_dup_string (type); g_warning (_("Type of return value is incorrect, got `%s', expected `%s'"), g_variant_get_type_string (parameters), type_string); g_variant_type_free (type); g_free (type_string); goto out; } g_variant_type_free (type); } if (G_UNLIKELY (_g_dbus_debug_return ())) { _g_dbus_debug_print_lock (); g_print ("========================================================================\n" "GDBus-debug:Return:\n" " >>>> METHOD RETURN\n" " in response to %s.%s()\n" " on object %s\n" " to name %s\n" " reply-serial %d\n", invocation->interface_name, invocation->method_name, invocation->object_path, invocation->sender, g_dbus_message_get_serial (invocation->message)); _g_dbus_debug_print_unlock (); } reply = g_dbus_message_new_method_reply (invocation->message); g_dbus_message_set_body (reply, parameters); error = NULL; if (!g_dbus_connection_send_message (g_dbus_method_invocation_get_connection (invocation), reply, G_DBUS_SEND_MESSAGE_FLAGS_NONE, NULL, &error)) { g_warning (_("Error sending message: %s"), error->message); g_error_free (error); } g_object_unref (reply); out: g_object_unref (invocation); }
static void g_dbus_method_invocation_return_value_internal (GDBusMethodInvocation *invocation, GVariant *parameters, GUnixFDList *fd_list) { GDBusMessage *reply; GError *error; g_return_if_fail (G_IS_DBUS_METHOD_INVOCATION (invocation)); g_return_if_fail ((parameters == NULL) || g_variant_is_of_type (parameters, G_VARIANT_TYPE_TUPLE)); if (parameters == NULL) parameters = g_variant_new_tuple (NULL, 0); /* if we have introspection data, check that the signature of @parameters is correct */ if (invocation->method_info != NULL) { GVariantType *type; type = _g_dbus_compute_complete_signature (invocation->method_info->out_args); if (!g_variant_is_of_type (parameters, type)) { gchar *type_string = g_variant_type_dup_string (type); g_warning ("Type of return value is incorrect: expected '%s', got '%s''", type_string, g_variant_get_type_string (parameters)); g_variant_type_free (type); g_free (type_string); goto out; } g_variant_type_free (type); } /* property_info is only non-NULL if set that way from * GDBusConnection, so this must be the case of async property * handling on either 'Get', 'Set' or 'GetAll'. */ if (invocation->property_info != NULL) { if (g_str_equal (invocation->method_name, "Get")) { GVariant *nested; if (!g_variant_is_of_type (parameters, G_VARIANT_TYPE ("(v)"))) { g_warning ("Type of return value for property 'Get' call should be '(v)' but got '%s'", g_variant_get_type_string (parameters)); goto out; } /* Go deeper and make sure that the value inside of the * variant matches the property type. */ g_variant_get (parameters, "(v)", &nested); if (!g_str_equal (g_variant_get_type_string (nested), invocation->property_info->signature)) { g_warning ("Value returned from property 'Get' call for '%s' should be '%s' but is '%s'", invocation->property_info->name, invocation->property_info->signature, g_variant_get_type_string (nested)); g_variant_unref (nested); goto out; } g_variant_unref (nested); } else if (g_str_equal (invocation->method_name, "GetAll")) { if (!g_variant_is_of_type (parameters, G_VARIANT_TYPE ("(a{sv})"))) { g_warning ("Type of return value for property 'GetAll' call should be '(a{sv})' but got '%s'", g_variant_get_type_string (parameters)); goto out; } /* Could iterate the list of properties and make sure that all * of them are actually on the interface and with the correct * types, but let's not do that for now... */ } else if (g_str_equal (invocation->method_name, "Set")) { if (!g_variant_is_of_type (parameters, G_VARIANT_TYPE_UNIT)) { g_warning ("Type of return value for property 'Set' call should be '()' but got '%s'", g_variant_get_type_string (parameters)); goto out; } } else g_assert_not_reached (); } if (G_UNLIKELY (_g_dbus_debug_return ())) { _g_dbus_debug_print_lock (); g_print ("========================================================================\n" "GDBus-debug:Return:\n" " >>>> METHOD RETURN\n" " in response to %s.%s()\n" " on object %s\n" " to name %s\n" " reply-serial %d\n", invocation->interface_name, invocation->method_name, invocation->object_path, invocation->sender, g_dbus_message_get_serial (invocation->message)); _g_dbus_debug_print_unlock (); } reply = g_dbus_message_new_method_reply (invocation->message); g_dbus_message_set_body (reply, parameters); #ifdef G_OS_UNIX if (fd_list != NULL) g_dbus_message_set_unix_fd_list (reply, fd_list); #endif error = NULL; if (!g_dbus_connection_send_message (g_dbus_method_invocation_get_connection (invocation), reply, G_DBUS_SEND_MESSAGE_FLAGS_NONE, NULL, &error)) { g_warning ("Error sending message: %s", error->message); g_error_free (error); } g_object_unref (reply); out: g_object_unref (invocation); }
GVariant * g_settings_set_mapping (const GValue *value, const GVariantType *expected_type, gpointer user_data) { gchar *type_string; if (G_VALUE_HOLDS_BOOLEAN (value)) { if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_BOOLEAN)) return g_variant_new_boolean (g_value_get_boolean (value)); } else if (G_VALUE_HOLDS_CHAR (value) || G_VALUE_HOLDS_UCHAR (value)) { if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_BYTE)) { if (G_VALUE_HOLDS_CHAR (value)) return g_variant_new_byte (g_value_get_char (value)); else return g_variant_new_byte (g_value_get_uchar (value)); } } else if (G_VALUE_HOLDS_INT (value) || G_VALUE_HOLDS_INT64 (value)) return g_settings_set_mapping_int (value, expected_type); else if (G_VALUE_HOLDS_DOUBLE (value)) return g_settings_set_mapping_float (value, expected_type); else if (G_VALUE_HOLDS_UINT (value) || G_VALUE_HOLDS_UINT64 (value)) return g_settings_set_mapping_unsigned_int (value, expected_type); else if (G_VALUE_HOLDS_STRING (value)) { if (g_value_get_string (value) == NULL) return NULL; else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_STRING)) return g_variant_new_string (g_value_get_string (value)); else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_BYTESTRING)) return g_variant_new_bytestring (g_value_get_string (value)); else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_OBJECT_PATH)) return g_variant_new_object_path (g_value_get_string (value)); else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_SIGNATURE)) return g_variant_new_signature (g_value_get_string (value)); } else if (G_VALUE_HOLDS (value, G_TYPE_STRV)) { if (g_value_get_boxed (value) == NULL) return NULL; return g_variant_new_strv ((const gchar **) g_value_get_boxed (value), -1); } else if (G_VALUE_HOLDS_ENUM (value)) { GEnumValue *enumval; GEnumClass *eclass; /* GParamSpecEnum holds a ref on the class so we just peek... */ eclass = g_type_class_peek (G_VALUE_TYPE (value)); enumval = g_enum_get_value (eclass, g_value_get_enum (value)); if (enumval) return g_variant_new_string (enumval->value_nick); else return NULL; } else if (G_VALUE_HOLDS_FLAGS (value)) { GVariantBuilder builder; GFlagsValue *flagsval; GFlagsClass *fclass; guint flags; fclass = g_type_class_peek (G_VALUE_TYPE (value)); flags = g_value_get_flags (value); g_variant_builder_init (&builder, G_VARIANT_TYPE ("as")); while (flags) { flagsval = g_flags_get_first_value (fclass, flags); if (flagsval == NULL) { g_variant_builder_clear (&builder); return NULL; } g_variant_builder_add (&builder, "s", flagsval->value_nick); flags &= ~flagsval->value; } return g_variant_builder_end (&builder); } type_string = g_variant_type_dup_string (expected_type); g_critical ("No GSettings bind handler for type \"%s\".", type_string); g_free (type_string); return NULL; }
EosUpdateInfo * run_fetchers (EosMetadataFetchData *fetch_data, GPtrArray *fetchers, GPtrArray *source_variants, GArray *sources) { guint idx; g_autoptr(GHashTable) source_to_update = g_hash_table_new_full (NULL, NULL, NULL, (GDestroyNotify) g_object_unref); g_return_val_if_fail (EOS_IS_METADATA_FETCH_DATA (fetch_data), NULL); g_return_val_if_fail (fetchers != NULL, NULL); g_return_val_if_fail (source_variants != NULL, NULL); g_return_val_if_fail (sources != NULL, NULL); g_return_val_if_fail (fetchers->len == source_variants->len, NULL); g_return_val_if_fail (source_variants->len == sources->len, NULL); for (idx = 0; idx < fetchers->len; ++idx) { MetadataFetcher fetcher = g_ptr_array_index (fetchers, idx); GVariant *source_variant = g_ptr_array_index (source_variants, idx); g_autoptr(EosUpdateInfo) info = NULL; EosUpdaterDownloadSource source = g_array_index (sources, EosUpdaterDownloadSource, idx); const gchar *name = download_source_to_string (source); g_autoptr(GError) local_error = NULL; const GVariantType *source_variant_type = g_variant_get_type (source_variant); if (!g_variant_type_equal (source_variant_type, G_VARIANT_TYPE_VARDICT)) { g_autofree gchar *expected = g_variant_type_dup_string (G_VARIANT_TYPE_VARDICT); g_autofree gchar *got = g_variant_type_dup_string (source_variant_type); g_message ("Wrong type of %s fetcher configuration, expected %s, got %s", name, expected, got); continue; } if (!fetcher (fetch_data, source_variant, &info, &local_error)) { g_message ("Failed to poll metadata from source %s: %s", name, local_error->message); continue; } if (info != NULL) { g_hash_table_insert (source_to_update, (gpointer) name, g_object_ref (info)); } } if (g_hash_table_size (source_to_update) > 0) { EosUpdateInfo *latest_update = NULL; g_autofree gchar *booted_ref = NULL; g_autoptr(GError) metrics_error = NULL; /* Send metrics about our ref: this is the ref we’re going to upgrade to, * but that’s always the same as the one we’re currently on. */ if (get_booted_refspec (NULL, NULL, &booted_ref, &metrics_error)) { g_autoptr(EosMetricsInfo) metrics = NULL; metrics = eos_metrics_info_new (booted_ref); maybe_send_metric (metrics); } else { g_message ("Failed to get metrics: %s", metrics_error->message); } latest_update = get_latest_update (sources, source_to_update); if (latest_update != NULL) return g_object_ref (latest_update); } return NULL; }