static int _icd_state_value_from_gvariant(OCRepPayload *repr, GVariantIter *iter) { int ret; char *key; GVariant *var; const char *str_value; OCRepPayload *repr_value; struct icd_state_list_s value_list = {0}; while (g_variant_iter_loop(iter, "{sv}", &key, &var)) { if (g_variant_is_of_type(var, G_VARIANT_TYPE_BOOLEAN)) { OCRepPayloadSetPropBool(repr, key, g_variant_get_boolean(var)); } else if (g_variant_is_of_type(var, G_VARIANT_TYPE_INT32)) { OCRepPayloadSetPropInt(repr, key, g_variant_get_int32(var)); } else if (g_variant_is_of_type(var, G_VARIANT_TYPE_DOUBLE)) { OCRepPayloadSetPropDouble(repr, key, g_variant_get_double(var)); } else if (g_variant_is_of_type(var, G_VARIANT_TYPE_STRING)) { str_value = g_variant_get_string(var, NULL); if (NULL == str_value) { ERR("g_variant_get_string() Fail"); _icd_payload_state_list_destroy(&value_list); return IOTCON_ERROR_OUT_OF_MEMORY; } if (IC_STR_EQUAL == strcmp(IC_STR_NULL, str_value)) OCRepPayloadSetNull(repr, key); else OCRepPayloadSetPropString(repr, key, str_value); } else if (g_variant_is_of_type(var, G_VARIANT_TYPE("ay"))) { OCByteString byte_value; byte_value.bytes = (uint8_t*)g_variant_get_data(var); byte_value.len = g_variant_get_size(var); OCRepPayloadSetPropByteString(repr, key, byte_value); } else if (g_variant_is_of_type(var, G_VARIANT_TYPE("a{sv}"))) { GVariantIter state_iter; repr_value = OCRepPayloadCreate(); g_variant_iter_init(&state_iter, var); ret = _icd_state_value_from_gvariant(repr_value, &state_iter); if (IOTCON_ERROR_NONE != ret) { ERR("_icd_state_value_from_gvariant() Fail(%d)", ret); _icd_payload_state_list_destroy(&value_list); OCRepPayloadDestroy(repr_value); return ret; } OCRepPayloadSetPropObjectAsOwner(repr, key, repr_value); } else if (g_variant_is_of_type(var, G_VARIANT_TYPE_ARRAY)) { memset(&value_list, 0, sizeof(struct icd_state_list_s)); ret = _icd_state_list_from_gvariant(var, &value_list, 0); if (IOTCON_ERROR_NONE != ret) { ERR("_icd_state_list_from_gvariant() Fail(%d)", ret); _icd_payload_state_list_destroy(&value_list); return ret; } ret = _icd_state_array_from_list(repr, &value_list, key); if (IOTCON_ERROR_NONE != ret) { ERR("_icd_state_array_from_list() Fail(%d)", ret); _icd_payload_state_list_destroy(&value_list); return ret; } } else { ERR("Invalid type(%s)", g_variant_get_type_string(var)); return IOTCON_ERROR_INVALID_TYPE; } } return IOTCON_ERROR_NONE; }
gboolean _ostree_static_delta_part_open (GInputStream *part_in, GBytes *inline_part_bytes, OstreeStaticDeltaOpenFlags flags, const char *expected_checksum, GVariant **out_part, GCancellable *cancellable, GError **error) { const gboolean trusted = (flags & OSTREE_STATIC_DELTA_OPEN_FLAGS_VARIANT_TRUSTED) > 0; const gboolean skip_checksum = (flags & OSTREE_STATIC_DELTA_OPEN_FLAGS_SKIP_CHECKSUM) > 0; gsize bytes_read; guint8 comptype; g_autoptr(GChecksum) checksum = NULL; g_autoptr(GInputStream) checksum_in = NULL; GInputStream *source_in; /* We either take a fd or a GBytes reference */ g_return_val_if_fail (G_IS_FILE_DESCRIPTOR_BASED (part_in) || inline_part_bytes != NULL, FALSE); g_return_val_if_fail (skip_checksum || expected_checksum != NULL, FALSE); if (!skip_checksum) { checksum = g_checksum_new (G_CHECKSUM_SHA256); checksum_in = (GInputStream*)ostree_checksum_input_stream_new (part_in, checksum); source_in = checksum_in; } else { source_in = part_in; } { guint8 buf[1]; /* First byte is compression type */ if (!g_input_stream_read_all (source_in, buf, sizeof(buf), &bytes_read, cancellable, error)) return glnx_prefix_error (error, "Reading initial compression flag byte"); comptype = buf[0]; } g_autoptr(GVariant) ret_part = NULL; switch (comptype) { case 0: if (!inline_part_bytes) { int part_fd = g_file_descriptor_based_get_fd ((GFileDescriptorBased*)part_in); /* No compression, no checksums - a fast path */ if (!ot_util_variant_map_fd (part_fd, 1, G_VARIANT_TYPE (OSTREE_STATIC_DELTA_PART_PAYLOAD_FORMAT_V0), trusted, &ret_part, error)) return FALSE; } else { g_autoptr(GBytes) content_bytes = g_bytes_new_from_bytes (inline_part_bytes, 1, g_bytes_get_size (inline_part_bytes) - 1); ret_part = g_variant_new_from_bytes (G_VARIANT_TYPE (OSTREE_STATIC_DELTA_PART_PAYLOAD_FORMAT_V0), content_bytes, trusted); g_variant_ref_sink (ret_part); } if (!skip_checksum) g_checksum_update (checksum, g_variant_get_data (ret_part), g_variant_get_size (ret_part)); break; case 'x': { g_autoptr(GConverter) decomp = (GConverter*) _ostree_lzma_decompressor_new (); g_autoptr(GInputStream) convin = g_converter_input_stream_new (source_in, decomp); g_autoptr(GBytes) buf = ot_map_anonymous_tmpfile_from_content (convin, cancellable, error); if (!buf) return FALSE; ret_part = g_variant_new_from_bytes (G_VARIANT_TYPE (OSTREE_STATIC_DELTA_PART_PAYLOAD_FORMAT_V0), buf, FALSE); } break; default: return glnx_throw (error, "Invalid compression type '%u'", comptype); } if (checksum) { const char *actual_checksum = g_checksum_get_string (checksum); g_assert (expected_checksum != NULL); if (strcmp (actual_checksum, expected_checksum) != 0) return glnx_throw (error, "Checksum mismatch in static delta part; expected=%s actual=%s", expected_checksum, actual_checksum); } *out_part = g_steal_pointer (&ret_part); return TRUE; }
static int _icd_state_list_from_gvariant(GVariant *var, struct icd_state_list_s *value_list, int depth) { int ret; GVariantIter iter; const GVariantType *type; union icd_state_value_u *value; type = g_variant_get_type(var); g_variant_iter_init(&iter, var); value_list->dimensions[depth] = g_variant_iter_n_children(&iter); DBG("[%d]list dim : %d", depth, value_list->dimensions[depth]); if (g_variant_type_equal(G_VARIANT_TYPE("ab"), type)) { bool b; value_list->type = OCREP_PROP_BOOL; while (g_variant_iter_loop(&iter, "b", &b)) { value = calloc(1, sizeof(union icd_state_value_u)); if (NULL == value) { ERR("calloc() Fail(%d)", errno); return IOTCON_ERROR_OUT_OF_MEMORY; } value->b = b; value_list->list = g_list_append(value_list->list, value); } } else if (g_variant_type_equal(G_VARIANT_TYPE("ai"), type)) { int i; value_list->type = OCREP_PROP_INT; while (g_variant_iter_loop(&iter, "i", &i)) { value = calloc(1, sizeof(union icd_state_value_u)); if (NULL == value) { ERR("calloc() Fail(%d)", errno); return IOTCON_ERROR_OUT_OF_MEMORY; } value->i = i; value_list->list = g_list_append(value_list->list, value); } } else if (g_variant_type_equal(G_VARIANT_TYPE("ad"), type)) { double d; value_list->type = OCREP_PROP_DOUBLE; while (g_variant_iter_loop(&iter, "d", &d)) { value = calloc(1, sizeof(union icd_state_value_u)); if (NULL == value) { ERR("calloc() Fail(%d)", errno); return IOTCON_ERROR_OUT_OF_MEMORY; } value->d = d; value_list->list = g_list_append(value_list->list, value); } } else if (g_variant_type_equal(G_VARIANT_TYPE("as"), type)) { char *s; value_list->type = OCREP_PROP_STRING; while (g_variant_iter_next(&iter, "s", &s)) value_list->list = g_list_append(value_list->list, s); } else if (g_variant_type_equal(G_VARIANT_TYPE("av"), type)) { GVariant *value; if (g_variant_iter_loop(&iter, "v", &value)) { if (g_variant_is_of_type(value, G_VARIANT_TYPE("a{sv}"))) { OCRepPayload *repr; GVariantIter state_iter; value_list->type = OCREP_PROP_OBJECT; do { repr = OCRepPayloadCreate(); g_variant_iter_init(&state_iter, value); ret = _icd_state_value_from_gvariant(repr, &state_iter); if (IOTCON_ERROR_NONE != ret) { ERR("_icd_state_value_from_gvariant() Fail(%d)", ret); OCRepPayloadDestroy(repr); return ret; } value_list->list = g_list_append(value_list->list, repr); } while (g_variant_iter_loop(&iter, "v", &value)); } else if (g_variant_is_of_type(value, G_VARIANT_TYPE("ay"))) { OCByteString *byte_str; value_list->type = OCREP_PROP_BYTE_STRING; do { byte_str = calloc(1, sizeof(OCByteString)); if (NULL == byte_str) { ERR("calloc() Fail(%d)", errno); return IOTCON_ERROR_OUT_OF_MEMORY; } byte_str->len = g_variant_get_size(value); byte_str->bytes = calloc(byte_str->len, sizeof(uint8_t)); if (NULL == byte_str->bytes) { ERR("calloc() Fail(%d)", errno); free(byte_str); return IOTCON_ERROR_OUT_OF_MEMORY; } memcpy(byte_str->bytes, g_variant_get_data(value), byte_str->len); value_list->list = g_list_append(value_list->list, byte_str); } while (g_variant_iter_loop(&iter, "v", &value)); } else if (g_variant_is_of_type(value, G_VARIANT_TYPE_ARRAY)) { do { ret = _icd_state_list_from_gvariant(value, value_list, depth + 1); if (IOTCON_ERROR_NONE != ret) { ERR("_icd_state_list_from_gvariant() Fail(%d)", ret); return ret; } } while (g_variant_iter_loop(&iter, "v", &value)); } } } return IOTCON_ERROR_NONE; }
static gboolean do_lookup (GResource *resource, const gchar *path, GResourceLookupFlags lookup_flags, gsize *size, guint32 *flags, const void **data, gsize *data_size, GError **error) { char *free_path = NULL; gsize path_len; gboolean res = FALSE; GVariant *value; path_len = strlen (path); if (path[path_len-1] == '/') { path = free_path = g_strdup (path); free_path[path_len-1] = 0; } value = gvdb_table_get_raw_value (resource->table, path); if (value == NULL) { g_set_error (error, G_RESOURCE_ERROR, G_RESOURCE_ERROR_NOT_FOUND, _("The resource at '%s' does not exist"), path); } else { guint32 _size, _flags; GVariant *array; g_variant_get (value, "(uu@ay)", &_size, &_flags, &array); _size = GUINT32_FROM_LE (_size); _flags = GUINT32_FROM_LE (_flags); if (size) *size = _size; if (flags) *flags = _flags; if (data) *data = g_variant_get_data (array); if (data_size) { /* Don't report trailing newline that non-compressed files has */ if (_flags & G_RESOURCE_FLAGS_COMPRESSED) *data_size = g_variant_get_size (array); else *data_size = g_variant_get_size (array) - 1; } g_variant_unref (array); g_variant_unref (value); res = TRUE; } g_free (free_path); return res; }
gboolean _ostree_static_delta_part_open (GInputStream *part_in, GBytes *inline_part_bytes, OstreeStaticDeltaOpenFlags flags, const char *expected_checksum, GVariant **out_part, GCancellable *cancellable, GError **error) { gboolean ret = FALSE; const gboolean trusted = (flags & OSTREE_STATIC_DELTA_OPEN_FLAGS_VARIANT_TRUSTED) > 0; const gboolean skip_checksum = (flags & OSTREE_STATIC_DELTA_OPEN_FLAGS_SKIP_CHECKSUM) > 0; gsize bytes_read; guint8 comptype; g_autoptr(GChecksum) checksum = NULL; g_autoptr(GInputStream) checksum_in = NULL; g_autoptr(GVariant) ret_part = NULL; GInputStream *source_in; /* We either take a fd or a GBytes reference */ g_return_val_if_fail (G_IS_FILE_DESCRIPTOR_BASED (part_in) || inline_part_bytes != NULL, FALSE); g_return_val_if_fail (skip_checksum || expected_checksum != NULL, FALSE); if (!skip_checksum) { checksum = g_checksum_new (G_CHECKSUM_SHA256); checksum_in = (GInputStream*)ostree_checksum_input_stream_new (part_in, checksum); source_in = checksum_in; } else { source_in = part_in; } { guint8 buf[1]; /* First byte is compression type */ if (!g_input_stream_read_all (source_in, buf, sizeof(buf), &bytes_read, cancellable, error)) { g_prefix_error (error, "Reading initial compression flag byte: "); goto out; } comptype = buf[0]; } switch (comptype) { case 0: if (!inline_part_bytes) { int part_fd = g_file_descriptor_based_get_fd ((GFileDescriptorBased*)part_in); /* No compression, no checksums - a fast path */ if (!ot_util_variant_map_fd (part_fd, 1, G_VARIANT_TYPE (OSTREE_STATIC_DELTA_PART_PAYLOAD_FORMAT_V0), trusted, &ret_part, error)) goto out; } else { g_autoptr(GBytes) content_bytes = g_bytes_new_from_bytes (inline_part_bytes, 1, g_bytes_get_size (inline_part_bytes) - 1); ret_part = g_variant_new_from_bytes (G_VARIANT_TYPE (OSTREE_STATIC_DELTA_PART_PAYLOAD_FORMAT_V0), content_bytes, trusted); g_variant_ref_sink (ret_part); } if (!skip_checksum) g_checksum_update (checksum, g_variant_get_data (ret_part), g_variant_get_size (ret_part)); break; case 'x': { g_autofree char *tmppath = g_strdup ("/var/tmp/ostree-delta-XXXXXX"); g_autoptr(GConverter) decomp = (GConverter*) _ostree_lzma_decompressor_new (); g_autoptr(GInputStream) convin = g_converter_input_stream_new (source_in, decomp); g_autoptr(GOutputStream) unpacked_out = NULL; glnx_fd_close int unpacked_fd = -1; gssize n_bytes_written; unpacked_fd = g_mkstemp_full (tmppath, O_RDWR | O_CLOEXEC, 0640); if (unpacked_fd < 0) { glnx_set_error_from_errno (error); goto out; } /* Now make it autocleanup on process exit - in the future, we * should consider caching unpacked deltas as well. */ if (unlink (tmppath) < 0) { glnx_set_error_from_errno (error); goto out; } unpacked_out = g_unix_output_stream_new (unpacked_fd, FALSE); n_bytes_written = g_output_stream_splice (unpacked_out, convin, G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE | G_OUTPUT_STREAM_SPLICE_CLOSE_TARGET, cancellable, error); if (n_bytes_written < 0) goto out; if (!ot_util_variant_map_fd (unpacked_fd, 0, G_VARIANT_TYPE (OSTREE_STATIC_DELTA_PART_PAYLOAD_FORMAT_V0), trusted, &ret_part, error)) goto out; } break; default: g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Invalid compression type '%u'", comptype); goto out; } if (checksum) { const char *actual_checksum = g_checksum_get_string (checksum); g_assert (expected_checksum != NULL); if (strcmp (actual_checksum, expected_checksum) != 0) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Checksum mismatch in static delta part; expected=%s actual=%s", expected_checksum, actual_checksum); goto out; } } ret = TRUE; *out_part = g_steal_pointer (&ret_part); out: return ret; }
// Get the (key,value) pairs back from KWallet. GHashTable* dt_pwstorage_kwallet_get(const backend_kwallet_context_t *context, const gchar* slot) { GHashTable *table = g_hash_table_new(g_str_hash, g_str_equal); GError* error = NULL; // Is there an entry in the wallet? gboolean has_entry = FALSE; int wallet_handle = get_wallet_handle(context); /* signature: * * in i handle, * in s folder, * in s key, * in s appid, * * out b arg_0 */ GVariant *ret = g_dbus_proxy_call_sync(context->proxy, "hasEntry", g_variant_new("(isss)", wallet_handle, kwallet_folder, slot, app_id), G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error); if(check_error(error)) { g_variant_unref(ret); return table; } GVariant *child = g_variant_get_child_value(ret, 0); has_entry = g_variant_get_boolean(child); g_variant_unref(child); g_variant_unref(ret); if(!has_entry) return table; /* signature: * * in i handle, * in s folder, * in s key, * in s appid, * * out a{sv} arg_0) */ ret = g_dbus_proxy_call_sync(context->proxy, "readMapList", g_variant_new("(isss)", wallet_handle, kwallet_folder, slot, app_id), G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error); if(check_error(error)) { g_variant_unref(ret); return table; } child = g_variant_get_child_value(ret, 0); // we are only interested in the first child. i am not even sure that there can legally be more than one if(g_variant_n_children(child)<1) { g_variant_unref(child); g_variant_unref(ret); return table; } GVariant *element = g_variant_get_child_value(child, 0); GVariant *v = NULL; g_variant_get(element, "{sv}", NULL, &v); const gchar *byte_array = g_variant_get_data(v); if(!byte_array) { g_variant_unref(v); g_variant_unref(element); g_variant_unref(child); g_variant_unref(ret); return table; } int entries = GINT_FROM_BE(*((int*)byte_array)); byte_array += sizeof(gint); for(int i=0; i<entries; i++) { guint length; gchar* key = array2string(byte_array, &length); byte_array += length; gchar* value = array2string(byte_array, &length); byte_array += length; dt_print(DT_DEBUG_PWSTORAGE,"[pwstorage_kwallet_get] reading (%s, %s)\n",(gchar*)key, (gchar*)value); g_hash_table_insert(table, key, value); } g_variant_unref(v); g_variant_unref(element); g_variant_unref(child); g_variant_unref(ret); return table; }
gboolean _ostree_static_delta_part_execute_raw (OstreeRepo *repo, GVariant *objects, GVariant *part, GCancellable *cancellable, GError **error) { gboolean ret = FALSE; guint8 *checksums_data; g_autoptr(GVariant) checksums = NULL; g_autoptr(GVariant) mode_dict = NULL; g_autoptr(GVariant) xattr_dict = NULL; g_autoptr(GVariant) payload = NULL; g_autoptr(GVariant) ops = NULL; StaticDeltaExecutionState statedata = { 0, }; StaticDeltaExecutionState *state = &statedata; guint n_executed = 0; state->repo = repo; state->async_error = error; if (!_ostree_static_delta_parse_checksum_array (objects, &checksums_data, &state->n_checksums, error)) goto out; state->checksums = checksums_data; g_assert (state->n_checksums > 0); g_variant_get (part, "(@a(uuu)@aa(ayay)@ay@ay)", &mode_dict, &xattr_dict, &payload, &ops); state->mode_dict = mode_dict; state->xattr_dict = xattr_dict; state->payload_data = g_variant_get_data (payload); state->payload_size = g_variant_get_size (payload); state->oplen = g_variant_n_children (ops); state->opdata = g_variant_get_data (ops); while (state->oplen > 0) { guint8 opcode; opcode = state->opdata[0]; state->oplen--; state->opdata++; switch (opcode) { case OSTREE_STATIC_DELTA_OP_OPEN_SPLICE_AND_CLOSE: if (!dispatch_open_splice_and_close (repo, state, cancellable, error)) goto out; break; case OSTREE_STATIC_DELTA_OP_OPEN: if (!dispatch_open (repo, state, cancellable, error)) goto out; break; case OSTREE_STATIC_DELTA_OP_WRITE: if (!dispatch_write (repo, state, cancellable, error)) goto out; break; case OSTREE_STATIC_DELTA_OP_SET_READ_SOURCE: if (!dispatch_set_read_source (repo, state, cancellable, error)) goto out; break; case OSTREE_STATIC_DELTA_OP_UNSET_READ_SOURCE: if (!dispatch_unset_read_source (repo, state, cancellable, error)) goto out; break; case OSTREE_STATIC_DELTA_OP_CLOSE: if (!dispatch_close (repo, state, cancellable, error)) goto out; break; case OSTREE_STATIC_DELTA_OP_BSPATCH: if (!dispatch_bspatch (repo, state, cancellable, error)) goto out; break; default: g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT, "Unknown opcode %u at offset %u", opcode, n_executed); goto out; } n_executed++; } if (state->caught_error) goto out; ret = TRUE; out: return ret; }
static void write_translations_dictionary (GList * licenses, const gchar * dict_filename) { /* maps C string => (dictionary of: locale => translation) */ GVariantBuilder array; /* maps C string => boolean (if it's in the dictionary already */ GHashTable *translations; GVariant *var; GList *l; FILE *f; /* sort langs for prettiness / to make variant dumps easier to read */ langs = g_list_sort (langs, (GCompareFunc) strcmp); g_variant_builder_init (&array, G_VARIANT_TYPE_ARRAY); translations = g_hash_table_new (g_str_hash, g_str_equal); for (l = licenses; l != NULL; l = l->next) { const gchar *en; License *license; license = l->data; if (license->packed_into_source) continue; /* add title + translations */ en = g_hash_table_lookup (license->titles, "en"); g_assert (en != NULL); /* check if we already have added translations for this string */ if (!g_hash_table_lookup (translations, (gpointer) en)) { GVariant *trans; trans = create_translation_dict (license->titles, en); if (trans != NULL) { g_variant_builder_add_value (&array, g_variant_new_dict_entry (g_variant_new_string (en), trans)); g_hash_table_insert (translations, (gpointer) en, GINT_TO_POINTER (TRUE)); } } /* add description + translations */ if (license->descriptions == NULL) continue; en = g_hash_table_lookup (license->descriptions, "en"); g_assert (en != NULL); /* check if we already have added translations for this string */ if (!g_hash_table_lookup (translations, (gpointer) en)) { GVariant *trans; trans = create_translation_dict (license->descriptions, en); if (trans != NULL) { g_variant_builder_add_value (&array, g_variant_new_dict_entry (g_variant_new_string (en), trans)); g_hash_table_insert (translations, (gpointer) en, GINT_TO_POINTER (TRUE)); } } } var = g_variant_builder_end (&array); f = fopen (dict_filename, "wb"); if (fwrite (g_variant_get_data (var), g_variant_get_size (var), 1, f) != 1) { g_error ("failed to write dict to file: %s", g_strerror (errno)); } fclose (f); g_printerr ("Wrote dictionary to %s, size: %u, type: %s\n", dict_filename, (guint) g_variant_get_size (var), (gchar *) g_variant_get_type (var)); g_variant_unref (var); g_hash_table_destroy (translations); }