static gboolean do_read_run (GLnxDirFdIterator *dfd_iter, guint *out_n_read, GError **error) { guint nattrs = 0; while (TRUE) { struct dirent *dent; if (!glnx_dirfd_iterator_next_dent (dfd_iter, &dent, NULL, error)) return FALSE; if (!dent) break; glnx_autofd int fd = -1; if (!glnx_openat_rdonly (dfd_iter->fd, dent->d_name, FALSE, &fd, error)) return FALSE; g_autoptr(GVariant) current_xattrs = NULL; if (!glnx_fd_get_all_xattrs (fd, ¤t_xattrs, NULL, error)) return FALSE; /* We don't actually care about the values, just use the variable * to avoid compiler warnings. */ nattrs += g_variant_n_children (current_xattrs); } *out_n_read = nattrs; return TRUE; }
/* swiss-army knife: takes an strv of pkgspecs destined for * install, and splits it into repo pkgs, and for local * pkgs, an fd list & idx variant. */ gboolean rpmostree_sort_pkgs_strv (const char *const* pkgs, GUnixFDList *fd_list, GPtrArray **out_repo_pkgs, GVariant **out_fd_idxs, GError **error) { g_autoptr(GPtrArray) repo_pkgs = g_ptr_array_new_with_free_func (g_free); g_auto(GVariantBuilder) builder; g_variant_builder_init (&builder, G_VARIANT_TYPE ("ah")); for (const char *const* pkg = pkgs; pkg && *pkg; pkg++) { if (!g_str_has_suffix (*pkg, ".rpm")) g_ptr_array_add (repo_pkgs, g_strdup (*pkg)); else { glnx_fd_close int fd = -1; if (!glnx_openat_rdonly (AT_FDCWD, *pkg, TRUE, &fd, error)) return FALSE; int idx = g_unix_fd_list_append (fd_list, fd, error); if (idx < 0) return FALSE; g_variant_builder_add (&builder, "h", idx); } } *out_fd_idxs = g_variant_ref_sink (g_variant_new ("ah", &builder)); *out_repo_pkgs = g_steal_pointer (&repo_pkgs); return TRUE; }
static gboolean do_write_run (GLnxDirFdIterator *dfd_iter, GError **error) { WriteType wtype = g_random_int () % 2; if (wtype == WRITE_RUN_CREATE) { guint32 randname_v = g_random_int (); g_autofree char *randname = g_strdup_printf ("file%u", randname_v); glnx_autofd int fd = -1; again: fd = openat (dfd_iter->fd, randname, O_CREAT | O_EXCL, 0644); if (fd < 0) { if (errno == EEXIST) { g_printerr ("Congratulations! I suggest purchasing a lottery ticket today!\n"); goto again; } else { glnx_set_error_from_errno (error); return FALSE; } } if (!add_random_xattrs (fd, error)) return FALSE; } else if (wtype == WRITE_RUN_MUTATE) { while (TRUE) { struct dirent *dent; if (!glnx_dirfd_iterator_next_dent (dfd_iter, &dent, NULL, error)) return FALSE; if (!dent) break; glnx_autofd int fd = -1; if (!glnx_openat_rdonly (dfd_iter->fd, dent->d_name, FALSE, &fd, error)) return FALSE; g_autoptr(GVariant) current_xattrs = NULL; if (!glnx_fd_get_all_xattrs (fd, ¤t_xattrs, NULL, error)) return FALSE; for (int i = 0; i < g_variant_n_children (current_xattrs); i++) { const char *name, *value; g_variant_get_child (current_xattrs, i, "(^&ay^&ay)", &name, &value); /* We don't want to potentially test/change xattrs like security.selinux * that were injected by the system. */ if (!g_str_has_prefix (name, "user.test")) continue; if (!set_random_xattr_value (fd, name, error)) return FALSE; } } } else g_assert_not_reached (); return TRUE; }