Ejemplo n.º 1
0
static gboolean
enumerate_refs_recurse (OstreeRepo    *repo,
                        const char    *remote,
                        int            base_dfd,
                        GString       *base_path,
                        int            child_dfd,
                        const char    *path,
                        GHashTable    *refs,
                        GCancellable  *cancellable,
                        GError       **error)
{
  g_auto(GLnxDirFdIterator) dfd_iter = { 0, };

  if (!glnx_dirfd_iterator_init_at (child_dfd, path, FALSE, &dfd_iter, error))
    return FALSE;

  while (TRUE)
    {
      guint len = base_path->len;
      struct dirent *dent = NULL;

      if (!glnx_dirfd_iterator_next_dent_ensure_dtype (&dfd_iter, &dent, cancellable, error))
        return FALSE;
      if (dent == NULL)
        break;

      g_string_append (base_path, dent->d_name);

      if (dent->d_type == DT_DIR)
        {
          g_string_append_c (base_path, '/');

          if (!enumerate_refs_recurse (repo, remote, base_dfd, base_path,
                                       dfd_iter.fd, dent->d_name,
                                       refs, cancellable, error))
            return FALSE;
        }
      else if (dent->d_type == DT_REG)
        {
          if (!add_ref_to_set (remote, base_dfd, base_path->str, refs,
                               cancellable, error))
            return FALSE;
        }

      g_string_truncate (base_path, len);
    }

  return TRUE;
}
Ejemplo n.º 2
0
static gboolean
enumerate_refs_recurse (OstreeRepo    *repo,
                        const char    *remote,
                        GFile         *base,
                        GFile         *dir,
                        GHashTable    *refs,
                        GCancellable  *cancellable,
                        GError       **error)
{
    gboolean ret = FALSE;
    g_autoptr(GFileEnumerator) enumerator = NULL;

    enumerator = g_file_enumerate_children (dir, OSTREE_GIO_FAST_QUERYINFO,
                                            G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
                                            cancellable, error);
    if (!enumerator)
        goto out;

    while (TRUE)
    {
        GFileInfo *file_info = NULL;
        GFile *child = NULL;

        if (!gs_file_enumerator_iterate (enumerator, &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)
        {
            if (!enumerate_refs_recurse (repo, remote, base, child, refs, cancellable, error))
                goto out;
        }
        else if (g_file_info_get_file_type (file_info) == G_FILE_TYPE_REGULAR)
        {
            if (!add_ref_to_set (remote, base, child, refs,
                                 cancellable, error))
                goto out;
        }
    }

    ret = TRUE;
out:
    return ret;
}
Ejemplo n.º 3
0
/**
 * ostree_repo_list_refs:
 * @self: Repo
 * @refspec_prefix: (allow-none): Only list refs which match this prefix
 * @out_all_refs: (out) (element-type utf8 utf8): Mapping from ref to checksum
 * @cancellable: Cancellable
 * @error: Error
 *
 * If @refspec_prefix is %NULL, list all local and remote refspecs,
 * with their current values in @out_all_refs.  Otherwise, only list
 * refspecs which have @refspec_prefix as a prefix.
 */
gboolean
ostree_repo_list_refs (OstreeRepo       *self,
                       const char       *refspec_prefix,
                       GHashTable      **out_all_refs,
                       GCancellable     *cancellable,
                       GError          **error)
{
    gboolean ret = FALSE;
    g_autoptr(GHashTable) ret_all_refs = NULL;
    g_autofree char *remote = NULL;
    g_autofree char *ref_prefix = NULL;

    ret_all_refs = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);

    if (refspec_prefix)
    {
        g_autoptr(GFile) dir = NULL;
        g_autoptr(GFile) child = NULL;
        g_autoptr(GFileInfo) info = NULL;

        if (!ostree_parse_refspec (refspec_prefix, &remote, &ref_prefix, error))
            goto out;

        if (remote)
            dir = g_file_get_child (self->remote_heads_dir, remote);
        else
            dir = g_object_ref (self->local_heads_dir);

        child = g_file_resolve_relative_path (dir, ref_prefix);
        if (!ot_gfile_query_info_allow_noent (child, OSTREE_GIO_FAST_QUERYINFO, 0,
                                              &info, cancellable, error))
            goto out;

        if (info)
        {
            if (g_file_info_get_file_type (info) == G_FILE_TYPE_DIRECTORY)
            {
                if (!enumerate_refs_recurse (self, remote, child, child,
                                             ret_all_refs,
                                             cancellable, error))
                    goto out;
            }
            else
            {
                if (!add_ref_to_set (remote, dir, child, ret_all_refs,
                                     cancellable, error))
                    goto out;
            }
        }
    }
    else
    {
        g_autoptr(GFileEnumerator) remote_enumerator = NULL;

        if (!enumerate_refs_recurse (self, NULL, self->local_heads_dir, self->local_heads_dir,
                                     ret_all_refs,
                                     cancellable, error))
            goto out;

        remote_enumerator = g_file_enumerate_children (self->remote_heads_dir, OSTREE_GIO_FAST_QUERYINFO,
                            0,
                            cancellable, error);

        while (TRUE)
        {
            GFileInfo *info;
            GFile *child;
            const char *name;

            if (!gs_file_enumerator_iterate (remote_enumerator, &info, &child,
                                             cancellable, error))
                goto out;
            if (!info)
                break;

            name = g_file_info_get_name (info);
            if (!enumerate_refs_recurse (self, name, child, child,
                                         ret_all_refs,
                                         cancellable, error))
                goto out;
        }
    }

    ret = TRUE;
    ot_transfer_out_value (out_all_refs, &ret_all_refs);
out:
    return ret;
}
Ejemplo n.º 4
0
static gboolean
_ostree_repo_list_refs_internal (OstreeRepo       *self,
                                 gboolean         cut_prefix,
                                 const char       *refspec_prefix,
                                 GHashTable      **out_all_refs,
                                 GCancellable     *cancellable,
                                 GError          **error)
{
  g_autoptr(GHashTable) ret_all_refs = NULL;
  g_autofree char *remote = NULL;
  g_autofree char *ref_prefix = NULL;

  ret_all_refs = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);

  if (refspec_prefix)
    {
      struct stat stbuf;
      const char *prefix_path;
      const char *path;

      if (!ostree_parse_refspec (refspec_prefix, &remote, &ref_prefix, error))
        return FALSE;

      if (remote)
        {
          prefix_path = glnx_strjoina ("refs/remotes/", remote, "/");
          path = glnx_strjoina (prefix_path, ref_prefix);
        }
      else
        {
          prefix_path = "refs/heads/";
          path = glnx_strjoina (prefix_path, ref_prefix);
        }

      if (fstatat (self->repo_dir_fd, path, &stbuf, 0) < 0)
        {
          if (errno != ENOENT)
            return glnx_throw_errno (error);
        }
      else
        {
          if (S_ISDIR (stbuf.st_mode))
            {
              glnx_fd_close int base_fd = -1;
              g_autoptr(GString) base_path = g_string_new ("");
              if (!cut_prefix)
                g_string_printf (base_path, "%s/", ref_prefix);

              if (!glnx_opendirat (self->repo_dir_fd, cut_prefix ? path : prefix_path, TRUE, &base_fd, error))
                return FALSE;

              if (!enumerate_refs_recurse (self, remote, base_fd, base_path,
                                           base_fd, cut_prefix ? "." : ref_prefix,
                                           ret_all_refs, cancellable, error))
                return FALSE;
            }
          else
            {
              glnx_fd_close int prefix_dfd = -1;

              if (!glnx_opendirat (self->repo_dir_fd, prefix_path, TRUE, &prefix_dfd, error))
                return FALSE;

              if (!add_ref_to_set (remote, prefix_dfd, ref_prefix, ret_all_refs,
                                   cancellable, error))
                return FALSE;
            }
        }
    }
  else
    {
      g_auto(GLnxDirFdIterator) dfd_iter = { 0, };
      g_autoptr(GString) base_path = g_string_new ("");
      glnx_fd_close int refs_heads_dfd = -1;

      if (!glnx_opendirat (self->repo_dir_fd, "refs/heads", TRUE, &refs_heads_dfd, error))
        return FALSE;

      if (!enumerate_refs_recurse (self, NULL, refs_heads_dfd, base_path,
                                   refs_heads_dfd, ".",
                                   ret_all_refs, cancellable, error))
        return FALSE;

      g_string_truncate (base_path, 0);

      if (!glnx_dirfd_iterator_init_at (self->repo_dir_fd, "refs/remotes", TRUE, &dfd_iter, error))
        return FALSE;

      while (TRUE)
        {
          struct dirent *dent;
          glnx_fd_close int remote_dfd = -1;

          if (!glnx_dirfd_iterator_next_dent_ensure_dtype (&dfd_iter, &dent, cancellable, error))
            return FALSE;
          if (!dent)
            break;

          if (dent->d_type != DT_DIR)
            continue;

          if (!glnx_opendirat (dfd_iter.fd, dent->d_name, TRUE, &remote_dfd, error))
            return FALSE;

          if (!enumerate_refs_recurse (self, dent->d_name, remote_dfd, base_path,
                                       remote_dfd, ".",
                                       ret_all_refs,
                                       cancellable, error))
            return FALSE;
        }
    }

  ot_transfer_out_value (out_all_refs, &ret_all_refs);
  return TRUE;
}