Esempio n. 1
0
/**
 * glnx_dirfd_iterator_init_at:
 * @dfd: File descriptor, may be AT_FDCWD or -1
 * @path: Path, may be relative to @df
 * @follow: If %TRUE and the last component of @path is a symlink, follow it
 * @out_dfd_iter: (out caller-allocates): A directory iterator, will be initialized
 * @error: Error
 *
 * Initialize @out_dfd_iter from @dfd and @path.
 */
gboolean
glnx_dirfd_iterator_init_at (int                     dfd,
                             const char             *path,
                             gboolean                follow,
                             GLnxDirFdIterator      *out_dfd_iter,
                             GError                **error)
{
  gboolean ret = FALSE;
  glnx_fd_close int fd = -1;
  
  if (!glnx_opendirat (dfd, path, follow, &fd, error))
    goto out;

  if (!glnx_dirfd_iterator_init_take_fd (fd, out_dfd_iter, error))
    goto out;
  fd = -1; /* Transfer ownership */

  ret = TRUE;
 out:
  return ret;
}
Esempio n. 2
0
/**
 * 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 = NULL;
  glnx_fd_close int dfd = -1;

  ret_deltas = g_ptr_array_new_with_free_func (g_free);

  dfd = glnx_opendirat_with_errno (self->repo_dir_fd, "deltas", TRUE);
  if (dfd < 0)
    {
      if (errno != ENOENT)
        {
          glnx_set_error_from_errno (error);
          return FALSE;
        }
    }
  else
    {
      g_auto(GLnxDirFdIterator) dfd_iter = { 0, };

      if (!glnx_dirfd_iterator_init_take_fd (dfd, &dfd_iter, error))
        return FALSE;
      dfd = -1;

      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));
                }
            }
        }
    }

  if (out_deltas)
    *out_deltas = g_steal_pointer (&ret_deltas);
  return TRUE;
}
Esempio n. 3
0
gboolean
_ostree_sysroot_read_boot_loader_configs (OstreeSysroot *self,
                                          int            bootversion,
                                          GPtrArray    **out_loader_configs,
                                          GCancellable  *cancellable,
                                          GError       **error)
{
  gboolean ret = FALSE;
  int fd; /* Temporary owned by iterator */
  g_autofree char *entries_path = g_strdup_printf ("boot/loader.%d/entries", bootversion);
  g_autoptr(GPtrArray) ret_loader_configs = NULL;
  g_auto(GLnxDirFdIterator) dfd_iter = { 0, };

  if (!ensure_sysroot_fd (self, error))
    goto out;

  ret_loader_configs = g_ptr_array_new_with_free_func ((GDestroyNotify)g_object_unref);

  fd = glnx_opendirat_with_errno (self->sysroot_fd, entries_path, TRUE);
  if (fd == -1)
    {
      if (errno == ENOENT)
        goto done;
      else
        {
          glnx_set_error_from_errno (error);
          goto out;
        }
    }

  if (!glnx_dirfd_iterator_init_take_fd (fd, &dfd_iter, error))
    goto out;

  while (TRUE)
    {
      struct dirent *dent;
      struct stat stbuf;

      if (!glnx_dirfd_iterator_next_dent (&dfd_iter, &dent, cancellable, error))
        goto out;
          
      if (dent == NULL)
        break;

      if (fstatat (dfd_iter.fd, dent->d_name, &stbuf, 0) != 0)
        {
          glnx_set_error_from_errno (error);
          goto out;
        }

      if (g_str_has_prefix (dent->d_name, "ostree-") &&
          g_str_has_suffix (dent->d_name, ".conf") &&
          S_ISREG (stbuf.st_mode))
        {
          glnx_unref_object OstreeBootconfigParser *config = ostree_bootconfig_parser_new ();
  
          if (!ostree_bootconfig_parser_parse_at (config, dfd_iter.fd, dent->d_name, cancellable, error))
            {
              g_prefix_error (error, "Parsing %s: ", dent->d_name);
              goto out;
            }

          g_ptr_array_add (ret_loader_configs, g_object_ref (config));
        }
    }

 done:
  gs_transfer_out_value (out_loader_configs, &ret_loader_configs);
  ret = TRUE;
 out:
  return ret;
}