Esempio n. 1
0
gboolean
ostree_create_temp_regular_file (GFile            *dir,
                                 const char       *prefix,
                                 const char       *suffix,
                                 GFile           **out_file,
                                 GOutputStream   **out_stream,
                                 GCancellable     *cancellable,
                                 GError          **error)
{
  gboolean ret = FALSE;
  ot_lobj GFile *ret_file = NULL;
  ot_lobj GOutputStream *ret_stream = NULL;

  if (!ostree_create_temp_file_from_input (dir, prefix, suffix, NULL, NULL, NULL,
                                           &ret_file, cancellable, error))
    goto out;
  
  ret_stream = (GOutputStream*)g_file_append_to (ret_file, 0, cancellable, error);
  if (ret_stream == NULL)
    goto out;
  
  ret = TRUE;
  ot_transfer_out_value(out_file, &ret_file);
  ot_transfer_out_value(out_stream, &ret_stream);
 out:
  return ret;
}
Esempio n. 2
0
/* Used by the remote builtins which are special in taking --sysroot or --repo */
gboolean
ostree_parse_sysroot_or_repo_option (GOptionContext *context,
                                     const char *sysroot_path,
                                     const char *repo_path,
                                     OstreeSysroot **out_sysroot,
                                     OstreeRepo **out_repo,
                                     GCancellable *cancellable,
                                     GError **error)
{
  g_autoptr(OstreeSysroot) sysroot = NULL;
  g_autoptr(OstreeRepo) repo = NULL;
  if (sysroot_path)
    {
      g_autoptr(GFile) sysroot_file = g_file_new_for_path (sysroot_path);
      sysroot = ostree_sysroot_new (sysroot_file);
      if (!ostree_sysroot_load (sysroot, cancellable, error))
        return FALSE;
      if (!ostree_sysroot_get_repo (sysroot, &repo, cancellable, error))
        return FALSE;
    }
  else
    {
      repo = parse_repo_option (context, repo_path, FALSE, cancellable, error);
      if (!repo)
        return FALSE;
    }

  ot_transfer_out_value (out_sysroot, &sysroot);
  ot_transfer_out_value (out_repo, &repo);
  return TRUE;
}
Esempio n. 3
0
gboolean
ostree_zlib_file_header_parse (GVariant         *metadata,
                               GFileInfo       **out_file_info,
                               GVariant        **out_xattrs,
                               GError          **error)
{
  gboolean ret = FALSE;
  guint64 size;
  guint32 uid, gid, mode, rdev;
  const char *symlink_target;
  ot_lobj GFileInfo *ret_file_info = NULL;
  ot_lvariant GVariant *ret_xattrs = NULL;

  g_variant_get (metadata, "(tuuuu&s@a(ayay))", &size,
                 &uid, &gid, &mode, &rdev,
                 &symlink_target, &ret_xattrs);

  size = GUINT64_FROM_BE (size);
  uid = GUINT32_FROM_BE (uid);
  gid = GUINT32_FROM_BE (gid);
  mode = GUINT32_FROM_BE (mode);
  rdev = GUINT32_FROM_BE (rdev);

  ret_file_info = g_file_info_new ();
  g_file_info_set_size (ret_file_info, size);
  g_file_info_set_attribute_uint32 (ret_file_info, "standard::type", ot_gfile_type_for_mode (mode));
  g_file_info_set_attribute_boolean (ret_file_info, "standard::is-symlink", S_ISLNK (mode));
  g_file_info_set_attribute_uint32 (ret_file_info, "unix::uid", uid);
  g_file_info_set_attribute_uint32 (ret_file_info, "unix::gid", gid);
  g_file_info_set_attribute_uint32 (ret_file_info, "unix::mode", mode);

  if (S_ISREG (mode))
    {
      ;
    }
  else if (S_ISLNK (mode))
    {
      g_file_info_set_attribute_byte_string (ret_file_info, "standard::symlink-target", symlink_target);
    }
  else if (S_ISCHR (mode) || S_ISBLK (mode))
    {
      g_file_info_set_attribute_uint32 (ret_file_info, "unix::rdev", rdev);
    }
  else if (S_ISFIFO (mode))
    {
      ;
    }
  else
    {
      g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
                   "Corrupted archive file; invalid mode %u", mode);
      goto out;
    }

  ret = TRUE;
  ot_transfer_out_value(out_file_info, &ret_file_info);
  ot_transfer_out_value(out_xattrs, &ret_xattrs);
 out:
  return ret;
}
Esempio n. 4
0
gboolean
ot_gfile_load_contents_utf8 (GFile         *file,
                             char         **out_contents,
                             char         **out_etag,
                             GCancellable  *cancellable,
                             GError       **error)
{
  gboolean ret = FALSE;
  gsize len;
  ot_lfree char *ret_contents = NULL;
  ot_lfree char *ret_etag = NULL;

  if (!g_file_load_contents (file, cancellable, &ret_contents, &len, &ret_etag, error))
    goto out;
  if (!g_utf8_validate (ret_contents, len, NULL))
    {
      g_set_error (error,
                   G_IO_ERROR,
                   G_IO_ERROR_INVALID_DATA,
                   "Invalid UTF-8");
      goto out;
    }

  ret = TRUE;
  ot_transfer_out_value (out_contents, &ret_contents);
  ot_transfer_out_value (out_etag, &ret_etag);
 out:
  return ret;
}
Esempio n. 5
0
gboolean
ot_gfile_load_contents_utf8_allow_noent (GFile          *path,
                                         char          **out_contents,
                                         GCancellable   *cancellable,
                                         GError        **error)
{
  gboolean ret = FALSE;
  GError *temp_error = NULL;
  g_autofree char *ret_contents = NULL;

  ret_contents = gs_file_load_contents_utf8 (path, cancellable, &temp_error);
  if (!ret_contents)
    {
      if (g_error_matches (temp_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))
        {
          g_clear_error (&temp_error);
        }
      else
        {
          g_propagate_error (error, temp_error);
          goto out;
        }
    }

  ret = TRUE;
  ot_transfer_out_value (out_contents, &ret_contents);
 out:
  return ret;
}
Esempio n. 6
0
gboolean
ot_gfile_query_symlink_target_allow_noent (GFile          *path,
                                           GFile         **out_target,
                                           GCancellable   *cancellable,
                                           GError        **error)
{
  gboolean ret = FALSE;
  g_autoptr(GFileInfo) file_info = NULL;
  g_autoptr(GFile) ret_target = NULL;

  if (!ot_gfile_query_info_allow_noent (path, OSTREE_GIO_FAST_QUERYINFO,
                                        G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
                                        &file_info,
                                        cancellable, error))
    goto out;

  if (file_info != NULL)
    {
      if (!ot_gfile_get_symlink_target_from_info (path, file_info, &ret_target,
                                                  cancellable, error))
        goto out;
    }
  
  ret = TRUE;
  ot_transfer_out_value (out_target, &ret_target);
 out:
  return ret;
}
Esempio n. 7
0
gboolean
ot_gfile_query_info_allow_noent (GFile                *path,
                                 const char           *queryopts,
                                 GFileQueryInfoFlags   flags,
                                 GFileInfo           **out_info,
                                 GCancellable         *cancellable,
                                 GError              **error)
{
  gboolean ret = FALSE;
  g_autoptr(GFileInfo) ret_file_info = NULL;
  GError *temp_error = NULL;

  ret_file_info = g_file_query_info (path, queryopts, flags,
                                     cancellable, &temp_error);
  if (!ret_file_info)
    {
      if (g_error_matches (temp_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))
        {
          g_clear_error (&temp_error);
        }
      else
        {
          g_propagate_error (error, temp_error);
          goto out;
        }
    }

  ret = TRUE;
  ot_transfer_out_value (out_info, &ret_file_info);
 out:
  return ret;
}
Esempio n. 8
0
static gboolean
diff_files (OstreeDiffFlags  flags,
            GFile           *a,
            GFileInfo       *a_info,
            GFile           *b,
            GFileInfo       *b_info,
            OstreeDiffItem **out_item,
            GCancellable    *cancellable,
            GError         **error)
{
  g_autofree char *checksum_a = NULL;
  g_autofree char *checksum_b = NULL;
  if (!get_file_checksum (flags, a, a_info, &checksum_a, cancellable, error))
    return FALSE;
  if (!get_file_checksum (flags, b, b_info, &checksum_b, cancellable, error))
    return FALSE;

  g_autoptr(OstreeDiffItem) ret_item = NULL;
  if (strcmp (checksum_a, checksum_b) != 0)
    {
      ret_item = diff_item_new (a, a_info, b, b_info,
                                checksum_a, checksum_b);
    }

  ot_transfer_out_value(out_item, &ret_item);
  return TRUE;
}
Esempio n. 9
0
static gboolean
parse_file_or_commit (OstreeRepo  *repo,
                      const char  *arg,
                      GFile      **out_file,
                      GCancellable *cancellable,
                      GError     **error)
{
  gboolean ret = FALSE;
  g_autoptr(GFile) ret_file = NULL;

  if (g_str_has_prefix (arg, "/")
      || g_str_has_prefix (arg, "./")
      )
    {
      ret_file = g_file_new_for_path (arg);
    }
  else
    {
      if (!ostree_repo_read_commit (repo, arg, &ret_file, NULL, cancellable, error))
        goto out;
    }

  ret = TRUE;
  ot_transfer_out_value (out_file, &ret_file);
 out:
  return ret;
}
Esempio n. 10
0
static gboolean
resolve_refspec_fallback (OstreeRepo     *self,
                          const char     *remote,
                          const char     *ref,
                          gboolean        allow_noent,
                          char          **out_rev,
                          GCancellable   *cancellable,
                          GError        **error)
{
    gboolean ret = FALSE;
    g_autofree char *ret_rev = NULL;

    if (self->parent_repo)
    {
        if (!resolve_refspec (self->parent_repo, remote, ref,
                              allow_noent, &ret_rev, error))
            goto out;
    }
    else if (!allow_noent)
    {
        g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND,
                     "Refspec '%s%s%s' not found",
                     remote ? remote : "",
                     remote ? ":" : "",
                     ref);
        goto out;
    }

    ret = TRUE;
    ot_transfer_out_value (out_rev, &ret_rev);
out:
    return ret;
}
Esempio n. 11
0
gboolean
ot_keyfile_get_value_with_default_group_optional (GKeyFile      *keyfile,
                                                  const char    *section,
                                                  const char    *value,
                                                  const char    *default_value,
                                                  char         **out_value,
                                                  GError       **error)
{
  gboolean ret = FALSE;
  GError *local_error = NULL;
  g_autofree char *ret_value = NULL;

  g_return_val_if_fail (keyfile != NULL, ret);
  g_return_val_if_fail (section != NULL, ret);
  g_return_val_if_fail (value != NULL, ret);

  if (!ot_keyfile_get_value_with_default (keyfile, section, value, default_value, &ret_value, &local_error))
    {
      if (g_error_matches (local_error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_GROUP_NOT_FOUND))
        {
          g_clear_error (&local_error);
          ret_value = g_strdup (default_value);
        }
      else
        {
          g_propagate_error (error, local_error);
          goto out;
        }
    }

  ret = TRUE;
  ot_transfer_out_value(out_value, &ret_value);
 out:
  return ret;
}
Esempio n. 12
0
static gboolean
load_remote_repo_config (OtPullData    *pull_data,
                         GKeyFile     **out_keyfile,
                         GCancellable  *cancellable,
                         GError       **error)
{
  gboolean ret = FALSE;
  gs_free char *contents = NULL;
  GKeyFile *ret_keyfile = NULL;
  SoupURI *target_uri = NULL;

  target_uri = suburi_new (pull_data->base_uri, "config", NULL);
  
  if (!fetch_uri_contents_utf8_sync (pull_data, target_uri, &contents,
                                     cancellable, error))
    goto out;

  ret_keyfile = g_key_file_new ();
  if (!g_key_file_load_from_data (ret_keyfile, contents, strlen (contents),
                                  0, error))
    goto out;

  ret = TRUE;
  ot_transfer_out_value (out_keyfile, &ret_keyfile);
 out:
  g_clear_pointer (&ret_keyfile, (GDestroyNotify) g_key_file_unref);
  g_clear_pointer (&target_uri, (GDestroyNotify) soup_uri_free);
  return ret;
}
Esempio n. 13
0
/**
 * Read all input from @src, allocating a new #GVariant from it into
 * output variable @out_variant.  @src will be closed as a result.
 *
 * Note the returned @out_variant is not floating.
 */
gboolean
ot_util_variant_from_stream (GInputStream         *src,
                             const GVariantType   *type,
                             gboolean              trusted,
                             GVariant            **out_variant,
                             GCancellable         *cancellable,
                             GError              **error)
{
  gboolean ret = FALSE;
  gs_unref_object GMemoryOutputStream *data_stream = NULL;
  gs_unref_variant GVariant *ret_variant = NULL;

  data_stream = (GMemoryOutputStream*)g_memory_output_stream_new (NULL, 0, g_realloc, g_free);

  if (g_output_stream_splice ((GOutputStream*)data_stream, src,
                              G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE | G_OUTPUT_STREAM_SPLICE_CLOSE_TARGET,
                              cancellable, error) < 0)
    goto out;

  ret_variant = g_variant_new_from_data (type, g_memory_output_stream_get_data (data_stream),
                                         g_memory_output_stream_get_data_size (data_stream),
                                         trusted, (GDestroyNotify) g_object_unref, data_stream);
  data_stream = NULL; /* Transfer ownership */
  g_variant_ref_sink (ret_variant);

  ret = TRUE;
  ot_transfer_out_value (out_variant, &ret_variant);
 out:
  return ret;
}
Esempio n. 14
0
gboolean
ot_gfile_get_symlink_target_from_info (GFile             *path,
                                       GFileInfo         *file_info,
                                       GFile            **out_target,
                                       GCancellable      *cancellable,
                                       GError           **error)
{
  gboolean ret = FALSE;
  const char *target;
  g_autoptr(GFile) path_parent = NULL;
  g_autoptr(GFile) ret_target = NULL;

  if (g_file_info_get_file_type (file_info) != G_FILE_TYPE_SYMBOLIC_LINK)
    {
      g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
                   "Not a symbolic link");
      goto out;
    }

  path_parent = g_file_get_parent (path);
  target = g_file_info_get_symlink_target (file_info);
  g_assert (target);
  ret_target = g_file_resolve_relative_path (path_parent, target);

  ret = TRUE;
 out:
  ot_transfer_out_value (out_target, &ret_target);
  return ret;
}
Esempio n. 15
0
/**
 * ot_util_variant_map:
 * @src: a #GFile
 * @type: Use this for variant
 * @trusted: See documentation of g_variant_new_from_data()
 * @out_variant: (out): Return location for new variant
 * @error:
 *
 * Memory-map @src, and store a new #GVariant referring to this memory
 * in @out_variant.  Note the returned @out_variant is not floating.
 */
gboolean
ot_util_variant_map (GFile              *src,
                     const GVariantType *type,
                     gboolean            trusted,
                     GVariant          **out_variant,
                     GError            **error)
{
  gboolean ret = FALSE;
  gs_unref_variant GVariant *ret_variant = NULL;
  GMappedFile *mfile = NULL;

  mfile = gs_file_map_noatime (src, NULL, error);
  if (!mfile)
    goto out;

  ret_variant = g_variant_new_from_data (type,
                                         g_mapped_file_get_contents (mfile),
                                         g_mapped_file_get_length (mfile),
                                         trusted,
                                         (GDestroyNotify) g_mapped_file_unref,
                                         mfile);
  mfile = NULL;
  g_variant_ref_sink (ret_variant);
  
  ret = TRUE;
  ot_transfer_out_value(out_variant, &ret_variant);
 out:
  if (mfile)
    g_mapped_file_unref (mfile);
  return ret;
}
Esempio n. 16
0
static gboolean
fetch_ref_contents (OtPullData    *pull_data,
                    const char    *ref,
                    char         **out_contents,
                    GCancellable  *cancellable,
                    GError       **error)
{
  gboolean ret = FALSE;
  gs_free char *ret_contents = NULL;
  SoupURI *target_uri = NULL;

  target_uri = suburi_new (pull_data->base_uri, "refs", "heads", ref, NULL);
  
  if (!fetch_uri_contents_utf8_sync (pull_data, target_uri, &ret_contents, cancellable, error))
    goto out;

  g_strchomp (ret_contents);

  if (!ostree_validate_checksum_string (ret_contents, error))
    goto out;

  ret = TRUE;
  ot_transfer_out_value (out_contents, &ret_contents);
 out:
  if (target_uri)
    soup_uri_free (target_uri);
  return ret;
}
Esempio n. 17
0
static gboolean
parse_rev_file (OstreeRepo     *self,
                GFile          *f,
                char          **sha256,
                GError        **error)
{
  gboolean ret = FALSE;
  GError *temp_error = NULL;
  gs_free char *rev = NULL;

  if ((rev = gs_file_load_contents_utf8 (f, NULL, &temp_error)) == NULL)
    goto out;

  if (rev == NULL)
    {
      if (g_error_matches (temp_error, G_FILE_ERROR, G_FILE_ERROR_NOENT))
        {
          g_clear_error (&temp_error);
        }
      else
        {
          g_propagate_error (error, temp_error);
          goto out;
        }
    }
  else
    {
      g_strchomp (rev);
    }

  if (g_str_has_prefix (rev, "ref: "))
    {
      gs_unref_object GFile *ref = NULL;
      char *ref_sha256;
      gboolean subret;

      ref = g_file_resolve_relative_path (self->local_heads_dir, rev + 5);
      subret = parse_rev_file (self, ref, &ref_sha256, error);
        
      if (!subret)
        {
          g_free (ref_sha256);
          goto out;
        }
      
      g_free (rev);
      rev = ref_sha256;
    }
  else 
    {
      if (!ostree_validate_checksum_string (rev, error))
        goto out;
    }

  ot_transfer_out_value(sha256, &rev);
  ret = TRUE;
 out:
  return ret;
}
Esempio n. 18
0
static gboolean
list_all_deployment_directories (OstreeSysroot       *self,
                                 GPtrArray          **out_deployments,
                                 GCancellable        *cancellable,
                                 GError             **error)
{
    gboolean ret = FALSE;
    gs_unref_object GFileEnumerator *dir_enum = NULL;
    gs_unref_object GFile *deploydir = NULL;
    gs_unref_ptrarray GPtrArray *ret_deployments = NULL;
    GError *temp_error = NULL;

    deploydir = g_file_resolve_relative_path (self->path, "ostree/deploy");

    ret_deployments = g_ptr_array_new_with_free_func (g_object_unref);

    dir_enum = g_file_enumerate_children (deploydir, OSTREE_GIO_FAST_QUERYINFO,
                                          G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
                                          cancellable, &temp_error);
    if (!dir_enum)
    {
        if (g_error_matches (temp_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))
        {
            g_clear_error (&temp_error);
            goto done;
        }
        else
        {
            g_propagate_error (error, temp_error);
            goto out;
        }
    }

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

        if (!gs_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;

        if (!_ostree_sysroot_list_deployment_dirs_for_os (child, ret_deployments,
                cancellable, error))
            goto out;
    }

done:
    ret = TRUE;
    ot_transfer_out_value (out_deployments, &ret_deployments);
out:
    return ret;
}
Esempio n. 19
0
gboolean
ostree_content_file_parse (gboolean                compressed,
                           GFile                  *content_path,
                           gboolean                trusted,
                           GInputStream          **out_input,
                           GFileInfo             **out_file_info,
                           GVariant              **out_xattrs,
                           GCancellable           *cancellable,
                           GError                **error)
{
  gboolean ret = FALSE;
  guint64 length;
  struct stat stbuf;
  ot_lobj GInputStream *file_input = NULL;
  ot_lobj GInputStream *ret_input = NULL;
  ot_lobj GFileInfo *content_file_info = NULL;
  ot_lobj GFileInfo *ret_file_info = NULL;
  ot_lvariant GVariant *ret_xattrs = NULL;

  file_input = (GInputStream*)gs_file_read_noatime (content_path, cancellable, error);
  if (!file_input)
    goto out;

  if (fstat (g_file_descriptor_based_get_fd ((GFileDescriptorBased*)file_input), &stbuf) < 0)
    {
      ot_util_set_error_from_errno (error, errno);
      goto out;
    }

  length = stbuf.st_size;

  if (!ostree_content_stream_parse (compressed, file_input, length, trusted,
                                    out_input ? &ret_input : NULL,
                                    &ret_file_info, &ret_xattrs,
                                    cancellable, error))
    goto out;

  ret = TRUE;
  ot_transfer_out_value (out_input, &ret_input);
  ot_transfer_out_value (out_file_info, &ret_file_info);
  ot_transfer_out_value (out_xattrs, &ret_xattrs);
 out:
  return ret;
}
Esempio n. 20
0
gboolean
ostree_get_xattrs_for_file (GFile         *f,
                            GVariant     **out_xattrs,
                            GCancellable  *cancellable,
                            GError       **error)
{
  gboolean ret = FALSE;
  const char *path;
  ssize_t bytes_read;
  ot_lvariant GVariant *ret_xattrs = NULL;
  ot_lfree char *xattr_names = NULL;
  ot_lfree char *xattr_names_canonical = NULL;
  GVariantBuilder builder;
  gboolean builder_initialized = FALSE;

  path = ot_gfile_get_path_cached (f);

  g_variant_builder_init (&builder, G_VARIANT_TYPE ("a(ayay)"));
  builder_initialized = TRUE;

  bytes_read = llistxattr (path, NULL, 0);

  if (bytes_read < 0)
    {
      if (errno != ENOTSUP)
        {
          ot_util_set_error_from_errno (error, errno);
          goto out;
        }
    }
  else if (bytes_read > 0)
    {
      xattr_names = g_malloc (bytes_read);
      if (llistxattr (path, xattr_names, bytes_read) < 0)
        {
          ot_util_set_error_from_errno (error, errno);
          goto out;
        }
      xattr_names_canonical = canonicalize_xattrs (xattr_names, bytes_read);
      
      if (!read_xattr_name_array (path, xattr_names_canonical, bytes_read, &builder, error))
        goto out;
    }

  ret_xattrs = g_variant_builder_end (&builder);
  g_variant_ref_sink (ret_xattrs);
  
  ret = TRUE;
  ot_transfer_out_value (out_xattrs, &ret_xattrs);
 out:
  if (!builder_initialized)
    g_variant_builder_clear (&builder);
  return ret;
}
Esempio n. 21
0
static gboolean
fetch_uri_contents_utf8_sync (OtPullData  *pull_data,
                              SoupURI     *uri,
                              char       **out_contents,
                              GCancellable  *cancellable,
                              GError     **error)
{
  gboolean ret = FALSE;
  const guint8 nulchar = 0;
  gs_free char *ret_contents = NULL;
  gs_unref_object GMemoryOutputStream *buf = NULL;
  OstreeFetchUriSyncData fetch_data = { 0, };

  if (g_cancellable_set_error_if_cancelled (cancellable, error))
    return FALSE;

  fetch_data.pull_data = pull_data;

  pull_data->fetching_sync_uri = uri;
  ostree_fetcher_stream_uri_async (pull_data->fetcher, uri, cancellable,
                                   fetch_uri_sync_on_complete, &fetch_data);

  run_mainloop_monitor_fetcher (pull_data);
  if (!fetch_data.result_stream)
    goto out;

  buf = (GMemoryOutputStream*)g_memory_output_stream_new (NULL, 0, g_realloc, g_free);
  if (g_output_stream_splice ((GOutputStream*)buf, fetch_data.result_stream,
                              G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE,
                              cancellable, error) < 0)
    goto out;

  /* Add trailing NUL */
  if (!g_output_stream_write ((GOutputStream*)buf, &nulchar, 1, cancellable, error))
    goto out;

  if (!g_output_stream_close ((GOutputStream*)buf, cancellable, error))
    goto out;

  ret_contents = g_memory_output_stream_steal_data (buf);

  if (!g_utf8_validate (ret_contents, -1, NULL))
    {
      g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
                   "Invalid UTF-8");
      goto out;
    }

  ret = TRUE;
  ot_transfer_out_value (out_contents, &ret_contents);
 out:
  g_clear_object (&(fetch_data.result_stream));
  return ret;
}
Esempio n. 22
0
static gboolean
parse_ref_summary (const char    *contents,
                   GHashTable   **out_refs,
                   GError       **error)
{
  gboolean ret = FALSE;
  gs_unref_hashtable GHashTable *ret_refs = NULL;
  char **lines = NULL;
  char **iter = NULL;
  char *ref = NULL;
  char *sha256 = NULL;

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

  lines = g_strsplit_set (contents, "\n", -1);
  for (iter = lines; *iter; iter++)
    {
      const char *line = *iter;
      const char *spc;

      if (!*line)
        continue;

      spc = strchr (line, ' ');
      if (!spc)
        {
          g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
                       "Invalid ref summary file; missing ' ' in line");
          goto out;
        }

      g_free (ref);
      ref = g_strdup (spc + 1);
      if (!ostree_validate_rev (ref, error))
        goto out;
      
      g_free (sha256);
      sha256 = g_strndup (line, spc - line);
      if (!ostree_validate_checksum_string (sha256, error))
        goto out;

      g_hash_table_replace (ret_refs, ref, sha256);
      /* Transfer ownership */
      ref = NULL;
      sha256 = NULL;
    }

  ret = TRUE;
  ot_transfer_out_value (out_refs, &ret_refs);
 out:
  g_strfreev (lines);
  return ret;
}
Esempio n. 23
0
gboolean
ostree_checksum_file_from_input (GFileInfo        *file_info,
                                 GVariant         *xattrs,
                                 GInputStream     *in,
                                 OstreeObjectType  objtype,
                                 guchar          **out_csum,
                                 GCancellable     *cancellable,
                                 GError          **error)
{
  gboolean ret = FALSE;
  ot_lfree guchar *ret_csum = NULL;
  GChecksum *checksum = NULL;

  checksum = g_checksum_new (G_CHECKSUM_SHA256);

  if (OSTREE_OBJECT_TYPE_IS_META (objtype))
    {
      if (!ot_gio_splice_update_checksum (NULL, in, checksum, cancellable, error))
        goto out;
    }
  else if (g_file_info_get_file_type (file_info) == G_FILE_TYPE_DIRECTORY)
    {
      ot_lvariant GVariant *dirmeta = ostree_create_directory_metadata (file_info, xattrs);
      g_checksum_update (checksum, g_variant_get_data (dirmeta),
                         g_variant_get_size (dirmeta));
      
    }
  else
    {
      ot_lvariant GVariant *file_header = NULL;

      file_header = ostree_file_header_new (file_info, xattrs);

      if (!ostree_write_file_header_update_checksum (NULL, file_header, checksum,
                                                     cancellable, error))
        goto out;

      if (g_file_info_get_file_type (file_info) == G_FILE_TYPE_REGULAR)
        {
          if (!ot_gio_splice_update_checksum (NULL, in, checksum, cancellable, error))
            goto out;
        }
    }

  ret_csum = ot_csum_from_gchecksum (checksum);

  ret = TRUE;
  ot_transfer_out_value (out_csum, &ret_csum);
 out:
  g_clear_pointer (&checksum, (GDestroyNotify)g_checksum_free);
  return ret;
}
Esempio n. 24
0
static gboolean
parse_statoverride_file (GHashTable   **out_mode_add,
                         GCancellable  *cancellable,
                         GError        **error)
{
  gboolean ret = FALSE;
  gsize len;
  char **iter = NULL; /* nofree */
  g_autoptr(GHashTable) ret_hash = NULL;
  g_autoptr(GFile) path = NULL;
  g_autofree char *contents = NULL;
  char **lines = NULL;

  path = g_file_new_for_path (opt_statoverride_file);

  if (!g_file_load_contents (path, cancellable, &contents, &len, NULL,
                             error))
    goto out;
  
  ret_hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
  lines = g_strsplit (contents, "\n", -1);

  for (iter = lines; iter && *iter; iter++)
    {
      const char *line = *iter;

      if (*line == '+')
        {
          const char *spc;
          guint mode_add;

          spc = strchr (line + 1, ' ');
          if (!spc)
            {
              g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
                           "Malformed statoverride file");
              goto out;
            }
          
          mode_add = (guint32)(gint32)g_ascii_strtod (line + 1, NULL);
          g_hash_table_insert (ret_hash,
                               g_strdup (spc + 1),
                               GUINT_TO_POINTER((gint32)mode_add));
        }
    }

  ret = TRUE;
  ot_transfer_out_value (out_mode_add, &ret_hash);
 out:
  g_strfreev (lines);
  return ret;
}
Esempio n. 25
0
/**
 * ostree_repo_resolve_partial_checksum:
 * @self: Repo
 * @refspec: A refspec
 * @full_checksum (out) (transfer full): A full checksum corresponding to the truncated ref given
 * @error: Error
 *
 * Look up the existing refspec checksums.  If the given ref is a unique truncated beginning
 * of a valid checksum it will return that checksum in the parameter @full_checksum
 */
static gboolean
ostree_repo_resolve_partial_checksum (OstreeRepo   *self,
                                      const char   *refspec,
                                      char        **full_checksum,
                                      GError      **error)
{
  static const char hexchars[] = "0123456789abcdef";
  g_autofree char *ret_rev = NULL;

  g_return_val_if_fail (error == NULL || *error == NULL, FALSE);

  /* If the input is longer than OSTREE_SHA256_STRING_LEN chars or contains non-hex chars,
     don't bother looking for it as an object */
  const gsize off = strspn (refspec, hexchars);
  if (off > OSTREE_SHA256_STRING_LEN || refspec[off] != '\0')
    return TRUE;

  /* this looks through all objects and adds them to the ref_list if:
     a) they are a commit object AND
     b) the obj checksum starts with the partual checksum defined by "refspec" */
  g_autoptr(GHashTable) ref_list = NULL;
  if (!ostree_repo_list_commit_objects_starting_with (self, refspec, &ref_list, NULL, error))
    return FALSE;

  guint length = g_hash_table_size (ref_list);

  GHashTableIter hashiter;
  gpointer key, value;
  GVariant *first_commit = NULL;
  g_hash_table_iter_init (&hashiter, ref_list);
  if (g_hash_table_iter_next (&hashiter, &key, &value))
    first_commit = (GVariant*) key;

  OstreeObjectType objtype;
  const char *checksum = NULL;
  if (first_commit)
    ostree_object_name_deserialize (first_commit, &checksum, &objtype);

  /* length more than one - multiple commits match partial refspec: is not unique */
  if (length > 1)
    return glnx_throw (error, "Refspec %s not unique", refspec);
  /* length is 1 - a single matching commit gives us our revision */
  else if (length == 1)
    ret_rev = g_strdup (checksum);

  /* Note: if length is 0, then code will return TRUE
     because there is no error, but it will return full_checksum = NULL
     to signal to continue parsing */

  ot_transfer_out_value (full_checksum, &ret_rev);
  return TRUE;
}
Esempio n. 26
0
gboolean
ostree_raw_file_to_content_stream (GInputStream       *input,
                                   GFileInfo          *file_info,
                                   GVariant           *xattrs,
                                   GInputStream      **out_input,
                                   guint64            *out_length,
                                   GCancellable       *cancellable,
                                   GError            **error)
{
  gboolean ret = FALSE;
  gpointer header_data;
  gsize header_size;
  ot_lobj GInputStream *ret_input = NULL;
  ot_lvariant GVariant *file_header = NULL;
  ot_lptrarray GPtrArray *streams = NULL;
  ot_lobj GOutputStream *header_out_stream = NULL;
  ot_lobj GInputStream *header_in_stream = NULL;

  file_header = ostree_file_header_new (file_info, xattrs);

  header_out_stream = g_memory_output_stream_new (NULL, 0, g_realloc, g_free);

  if (!ostree_write_variant_with_size (header_out_stream, file_header, 0, NULL, NULL,
                                       cancellable, error))
    goto out;

  if (!g_output_stream_close (header_out_stream, cancellable, error))
    goto out;

  header_size = g_memory_output_stream_get_data_size ((GMemoryOutputStream*) header_out_stream);
  header_data = g_memory_output_stream_steal_data ((GMemoryOutputStream*) header_out_stream);
  header_in_stream = g_memory_input_stream_new_from_data (header_data, header_size, g_free);

  streams = g_ptr_array_new_with_free_func ((GDestroyNotify)g_object_unref);

  g_ptr_array_add (streams, g_object_ref (header_in_stream));
  if (input)
    g_ptr_array_add (streams, g_object_ref (input));
  
  ret_input = (GInputStream*)ostree_chain_input_stream_new (streams);

  ret = TRUE;
  ot_transfer_out_value (out_input, &ret_input);
  if (out_length)
    *out_length = header_size + g_file_info_get_size (file_info);
 out:
  return ret;
}
Esempio n. 27
0
gboolean
ostree_checksum_file (GFile            *f,
                      OstreeObjectType  objtype,
                      guchar          **out_csum,
                      GCancellable     *cancellable,
                      GError          **error)
{
  gboolean ret = FALSE;
  ot_lobj GFileInfo *file_info = NULL;
  ot_lobj GInputStream *in = NULL;
  ot_lvariant GVariant *xattrs = NULL;
  ot_lfree guchar *ret_csum = NULL;

  if (g_cancellable_set_error_if_cancelled (cancellable, error))
    return FALSE;

  file_info = g_file_query_info (f, OSTREE_GIO_FAST_QUERYINFO,
                                 G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
                                 cancellable, error);
  if (!file_info)
    goto out;

  if (g_file_info_get_file_type (file_info) == G_FILE_TYPE_REGULAR)
    {
      in = (GInputStream*)g_file_read (f, cancellable, error);
      if (!in)
        goto out;
    }

  if (objtype == OSTREE_OBJECT_TYPE_FILE)
    {
      if (!ostree_get_xattrs_for_file (f, &xattrs, cancellable, error))
        goto out;
    }

  if (!ostree_checksum_file_from_input (file_info, xattrs, in, objtype,
                                        &ret_csum, cancellable, error))
    goto out;

  ret = TRUE;
  ot_transfer_out_value(out_csum, &ret_csum);
 out:
  return ret;
}
Esempio n. 28
0
static gboolean
get_file_checksum (OstreeDiffFlags  flags,
                   GFile *f,
                   GFileInfo *f_info,
                   char  **out_checksum,
                   GCancellable *cancellable,
                   GError   **error)
{
  g_autofree char *ret_checksum = NULL;

  if (OSTREE_IS_REPO_FILE (f))
    {
      ret_checksum = g_strdup (ostree_repo_file_get_checksum ((OstreeRepoFile*)f));
    }
  else
    {
      g_autoptr(GVariant) xattrs = NULL;
      g_autoptr(GInputStream) in = NULL;

      if (!(flags & OSTREE_DIFF_FLAGS_IGNORE_XATTRS))
        {
          if (!glnx_dfd_name_get_all_xattrs (AT_FDCWD, gs_file_get_path_cached (f),
                                             &xattrs, cancellable, error))
            return FALSE;
        }

      if (g_file_info_get_file_type (f_info) == G_FILE_TYPE_REGULAR)
        {
          in = (GInputStream*)g_file_read (f, cancellable, error);
          if (!in)
            return FALSE;
        }

      g_autofree guchar *csum = NULL;
      if (!ostree_checksum_file_from_input (f_info, xattrs, in,
                                            OSTREE_OBJECT_TYPE_FILE,
                                            &csum, cancellable, error))
        return FALSE;
      ret_checksum = ostree_checksum_from_bytes (csum);
    }

  ot_transfer_out_value(out_checksum, &ret_checksum);
  return TRUE;
}
Esempio n. 29
0
static gboolean
find_ref_in_remotes (OstreeRepo         *self,
                     const char         *rev,
                     GFile             **out_file,
                     GError            **error)
{
    gboolean ret = FALSE;
    g_autoptr(GFileEnumerator) dir_enum = NULL;
    g_autoptr(GFile) ret_file = NULL;

    dir_enum = g_file_enumerate_children (self->remote_heads_dir, OSTREE_GIO_FAST_QUERYINFO,
                                          G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
                                          NULL, error);
    if (!dir_enum)
        goto out;

    while (TRUE)
    {
        GFileInfo *file_info;
        GFile *child;
        if (!gs_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;

        g_clear_object (&ret_file);
        ret_file = g_file_resolve_relative_path (child, rev);
        if (!g_file_query_exists (ret_file, NULL))
            g_clear_object (&ret_file);
        else
            break;
    }

    ret = TRUE;
    ot_transfer_out_value (out_file, &ret_file);
out:
    return ret;
}
static gboolean
get_kernel_path_from_release (const char         *release,
                              GFile             **out_path,
                              GCancellable       *cancellable,
                              GError            **error)
{
  gboolean ret = FALSE;
  ot_lfree char *name = NULL;
  ot_lobj GFile *possible_path = NULL;

  /* TODO - replace this with grubby code */

  name = g_strconcat ("vmlinuz-", release, NULL);
  possible_path = ot_gfile_from_build_path ("/boot", name, NULL);
  if (!g_file_query_exists (possible_path, cancellable))
    g_clear_object (&possible_path);

  ret = TRUE;
  ot_transfer_out_value (out_path, &possible_path);
  /*  out: */
  return ret;
}