static void meta_fetch_on_complete (GObject *object, GAsyncResult *result, gpointer user_data) { FetchObjectData *fetch_data = user_data; OtPullData *pull_data = fetch_data->pull_data; gs_unref_variant GVariant *metadata = NULL; const char *checksum; OstreeObjectType objtype; GError *local_error = NULL; GError **error = &local_error; ostree_object_name_deserialize (fetch_data->object, &checksum, &objtype); g_debug ("fetch of %s complete", ostree_object_to_string (checksum, objtype)); fetch_data->temp_path = ostree_fetcher_request_uri_with_partial_finish ((OstreeFetcher*)object, result, error); if (!fetch_data->temp_path) { if (!g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND)) goto out; else if (fetch_data->is_detached_meta) { /* There isn't any detached metadata, just fetch the commit */ g_clear_error (&local_error); enqueue_one_object_request (pull_data, fetch_data->object, FALSE); } goto out; } if (fetch_data->is_detached_meta) { if (!ot_util_variant_map (fetch_data->temp_path, G_VARIANT_TYPE ("a{sv}"), FALSE, &metadata, error)) goto out; if (!ostree_repo_write_commit_detached_metadata (pull_data->repo, checksum, metadata, pull_data->cancellable, error)) goto out; enqueue_one_object_request (pull_data, fetch_data->object, FALSE); } else { if (!ot_util_variant_map (fetch_data->temp_path, ostree_metadata_variant_type (objtype), FALSE, &metadata, error)) goto out; ostree_repo_write_metadata_async (pull_data->repo, objtype, checksum, metadata, pull_data->cancellable, on_metadata_writed, fetch_data); pull_data->n_outstanding_metadata_write_requests++; } out: pull_data->n_outstanding_metadata_fetches--; pull_data->n_fetched_metadata++; throw_async_error (pull_data, local_error); if (local_error) { g_variant_unref (fetch_data->object); g_free (fetch_data); } }
static gboolean dispatch_open_splice_and_close (OstreeRepo *repo, StaticDeltaExecutionState *state, GCancellable *cancellable, GError **error) { gboolean ret = FALSE; if (!open_output_target (state, cancellable, error)) goto out; if (OSTREE_OBJECT_TYPE_IS_META (state->output_objtype)) { g_autoptr(GVariant) metadata = NULL; guint64 offset; guint64 length; if (!read_varuint64 (state, &length, error)) goto out; if (!read_varuint64 (state, &offset, error)) goto out; if (!validate_ofs (state, offset, length, error)) goto out; if (state->stats_only) { ret = TRUE; goto out; } metadata = g_variant_new_from_data (ostree_metadata_variant_type (state->output_objtype), state->payload_data + offset, length, TRUE, NULL, NULL); { g_autofree guchar *actual_csum = NULL; if (!ostree_repo_write_metadata (state->repo, state->output_objtype, state->checksum, metadata, &actual_csum, cancellable, error)) goto out; } } else { guint64 content_offset; guint64 objlen; g_autoptr(GInputStream) object_input = NULL; g_autoptr(GInputStream) memin = NULL; if (!do_content_open_generic (repo, state, cancellable, error)) goto out; if (!read_varuint64 (state, &state->content_size, error)) goto out; if (!read_varuint64 (state, &content_offset, error)) goto out; if (!validate_ofs (state, content_offset, state->content_size, error)) goto out; if (state->stats_only) { ret = TRUE; goto out; } /* Fast path for regular files to bare repositories */ if (S_ISREG (state->mode) && (repo->mode == OSTREE_REPO_MODE_BARE || repo->mode == OSTREE_REPO_MODE_BARE_USER)) { if (!_ostree_repo_open_content_bare (repo, state->checksum, state->content_size, &state->barecommitstate, &state->content_out, &state->have_obj, cancellable, error)) goto out; if (!state->have_obj) { if (!handle_untrusted_content_checksum (repo, state, cancellable, error)) goto out; if (!content_out_write (repo, state, state->payload_data + content_offset, state->content_size, cancellable, error)) goto out; } } else { /* Slower path, for symlinks and unpacking deltas into archive-z2 */ g_autoptr(GFileInfo) finfo = NULL; finfo = _ostree_header_gfile_info_new (state->mode, state->uid, state->gid); if (S_ISLNK (state->mode)) { g_autofree char *nulterminated_target = g_strndup ((char*)state->payload_data + content_offset, state->content_size); g_file_info_set_symlink_target (finfo, nulterminated_target); } else { g_assert (S_ISREG (state->mode)); g_file_info_set_size (finfo, state->content_size); memin = g_memory_input_stream_new_from_data (state->payload_data + content_offset, state->content_size, NULL); } if (!ostree_raw_file_to_content_stream (memin, finfo, state->xattrs, &object_input, &objlen, cancellable, error)) goto out; { g_autofree guchar *actual_csum = NULL; if (!ostree_repo_write_content (state->repo, state->checksum, object_input, objlen, &actual_csum, cancellable, error)) goto out; } } } if (!dispatch_close (repo, state, cancellable, error)) goto out; ret = TRUE; out: if (state->stats_only) (void) dispatch_close (repo, state, cancellable, NULL); if (!ret) g_prefix_error (error, "opcode open-splice-and-close: "); return ret; }