static gboolean _ostree_repo_prune_tmp (OstreeRepo *self, GCancellable *cancellable, GError **error) { if (self->cache_dir_fd == -1) return TRUE; g_auto(GLnxDirFdIterator) dfd_iter = { 0, }; gboolean exists; if (!ot_dfd_iter_init_allow_noent (self->cache_dir_fd, _OSTREE_SUMMARY_CACHE_DIR, &dfd_iter, &exists, error)) return FALSE; /* Note early return */ if (!exists) return TRUE; while (TRUE) { size_t len; gboolean has_sig_suffix = FALSE; struct dirent *dent; g_autofree gchar *d_name = NULL; if (!glnx_dirfd_iterator_next_dent (&dfd_iter, &dent, cancellable, error)) return FALSE; if (dent == NULL) break; /* dirent->d_name can't be modified directly; see `man 3 readdir` */ d_name = g_strdup (dent->d_name); len = strlen (d_name); if (len > 4 && g_strcmp0 (d_name + len - 4, ".sig") == 0) { has_sig_suffix = TRUE; d_name[len - 4] = '\0'; } if (!g_hash_table_contains (self->remotes, d_name)) { /* Restore the previous value to get the file name. */ if (has_sig_suffix) d_name[len - 4] = '.'; if (!glnx_unlinkat (dfd_iter.fd, d_name, 0, error)) return FALSE; } } 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) { 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; }