static char * _ostree_get_relative_static_delta_path (const char *from, const char *to, const char *target) { guint8 csum_to[OSTREE_SHA256_DIGEST_LEN]; char to_b64[44]; guint8 csum_to_copy[OSTREE_SHA256_DIGEST_LEN]; GString *ret = g_string_new ("deltas/"); ostree_checksum_inplace_to_bytes (to, csum_to); ostree_checksum_b64_inplace_from_bytes (csum_to, to_b64); ostree_checksum_b64_inplace_to_bytes (to_b64, csum_to_copy); g_assert (memcmp (csum_to, csum_to_copy, OSTREE_SHA256_DIGEST_LEN) == 0); if (from != NULL) { guint8 csum_from[OSTREE_SHA256_DIGEST_LEN]; char from_b64[44]; ostree_checksum_inplace_to_bytes (from, csum_from); ostree_checksum_b64_inplace_from_bytes (csum_from, from_b64); g_string_append_c (ret, from_b64[0]); g_string_append_c (ret, from_b64[1]); g_string_append_c (ret, '/'); g_string_append (ret, from_b64 + 2); g_string_append_c (ret, '-'); } g_string_append_c (ret, to_b64[0]); g_string_append_c (ret, to_b64[1]); if (from == NULL) g_string_append_c (ret, '/'); g_string_append (ret, to_b64 + 2); if (target != NULL) { g_string_append_c (ret, '/'); g_string_append (ret, target); } return g_string_free (ret, FALSE); }
/** * ostree_repo_list_static_delta_names: * @self: Repo * @out_deltas: (out) (element-type utf8) (transfer container): String name of deltas (checksum-checksum.delta) * @cancellable: Cancellable * @error: Error * * This function synchronously enumerates all static deltas in the * repository, returning its result in @out_deltas. */ gboolean ostree_repo_list_static_delta_names (OstreeRepo *self, GPtrArray **out_deltas, GCancellable *cancellable, GError **error) { g_autoptr(GPtrArray) ret_deltas = g_ptr_array_new_with_free_func (g_free); g_auto(GLnxDirFdIterator) dfd_iter = { 0, }; gboolean exists; if (!ot_dfd_iter_init_allow_noent (self->repo_dir_fd, "deltas", &dfd_iter, &exists, error)) return FALSE; if (!exists) { /* Note early return */ ot_transfer_out_value (out_deltas, &ret_deltas); return TRUE; } while (TRUE) { g_auto(GLnxDirFdIterator) sub_dfd_iter = { 0, }; struct dirent *dent; if (!glnx_dirfd_iterator_next_dent_ensure_dtype (&dfd_iter, &dent, cancellable, error)) return FALSE; if (dent == NULL) break; if (dent->d_type != DT_DIR) continue; if (!glnx_dirfd_iterator_init_at (dfd_iter.fd, dent->d_name, FALSE, &sub_dfd_iter, error)) return FALSE; while (TRUE) { struct dirent *sub_dent; const char *name1; const char *name2; g_autofree char *superblock_subpath = NULL; struct stat stbuf; if (!glnx_dirfd_iterator_next_dent_ensure_dtype (&sub_dfd_iter, &sub_dent, cancellable, error)) return FALSE; if (sub_dent == NULL) break; if (dent->d_type != DT_DIR) continue; name1 = dent->d_name; name2 = sub_dent->d_name; superblock_subpath = g_strconcat (name2, "/superblock", NULL); if (fstatat (sub_dfd_iter.fd, superblock_subpath, &stbuf, 0) < 0) { if (errno != ENOENT) { glnx_set_error_from_errno (error); return FALSE; } } else { g_autofree char *buf = g_strconcat (name1, name2, NULL); GString *out = g_string_new (""); char checksum[OSTREE_SHA256_STRING_LEN+1]; guchar csum[OSTREE_SHA256_DIGEST_LEN]; const char *dash = strchr (buf, '-'); ostree_checksum_b64_inplace_to_bytes (buf, csum); ostree_checksum_inplace_from_bytes (csum, checksum); g_string_append (out, checksum); if (dash) { g_string_append_c (out, '-'); ostree_checksum_b64_inplace_to_bytes (dash+1, csum); ostree_checksum_inplace_from_bytes (csum, checksum); g_string_append (out, checksum); } g_ptr_array_add (ret_deltas, g_string_free (out, FALSE)); } } } ot_transfer_out_value (out_deltas, &ret_deltas); return TRUE; }
/** * ostree_repo_list_static_delta_names: * @self: Repo * @out_deltas: (out) (element-type utf8) (transfer container): String name of deltas (checksum-checksum.delta) * @cancellable: Cancellable * @error: Error * * This function synchronously enumerates all static deltas in the * repository, returning its result in @out_deltas. */ gboolean ostree_repo_list_static_delta_names (OstreeRepo *self, GPtrArray **out_deltas, GCancellable *cancellable, GError **error) { gboolean ret = FALSE; g_autoptr(GPtrArray) ret_deltas = NULL; g_autoptr(GFileEnumerator) dir_enum = NULL; ret_deltas = g_ptr_array_new_with_free_func (g_free); if (g_file_query_exists (self->deltas_dir, NULL)) { dir_enum = g_file_enumerate_children (self->deltas_dir, OSTREE_GIO_FAST_QUERYINFO, G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, NULL, error); if (!dir_enum) goto out; while (TRUE) { g_autoptr(GFileEnumerator) dir_enum2 = NULL; GFileInfo *file_info; GFile *child; if (!g_file_enumerator_iterate (dir_enum, &file_info, &child, NULL, error)) goto out; if (file_info == NULL) break; if (g_file_info_get_file_type (file_info) != G_FILE_TYPE_DIRECTORY) continue; dir_enum2 = g_file_enumerate_children (child, OSTREE_GIO_FAST_QUERYINFO, G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, NULL, error); if (!dir_enum2) goto out; while (TRUE) { GFileInfo *file_info2; GFile *child2; const char *name1; const char *name2; if (!g_file_enumerator_iterate (dir_enum2, &file_info2, &child2, NULL, error)) goto out; if (file_info2 == NULL) break; if (g_file_info_get_file_type (file_info2) != G_FILE_TYPE_DIRECTORY) continue; name1 = g_file_info_get_name (file_info); name2 = g_file_info_get_name (file_info2); { g_autoptr(GFile) meta_path = g_file_get_child (child2, "superblock"); if (g_file_query_exists (meta_path, NULL)) { g_autofree char *buf = g_strconcat (name1, name2, NULL); GString *out = g_string_new (""); char checksum[OSTREE_SHA256_STRING_LEN+1]; guchar csum[OSTREE_SHA256_DIGEST_LEN]; const char *dash = strchr (buf, '-'); ostree_checksum_b64_inplace_to_bytes (buf, csum); ostree_checksum_inplace_from_bytes (csum, checksum); g_string_append (out, checksum); if (dash) { g_string_append_c (out, '-'); ostree_checksum_b64_inplace_to_bytes (dash+1, csum); ostree_checksum_inplace_from_bytes (csum, checksum); g_string_append (out, checksum); } g_ptr_array_add (ret_deltas, g_string_free (out, FALSE)); } } } } } ret = TRUE; if (out_deltas) *out_deltas = g_steal_pointer (&ret_deltas); out: return ret; }