Exemplo n.º 1
0
static gboolean
meta_monitor_manager_handle_set_crtc_gamma  (MetaDBusDisplayConfig *skeleton,
                                             GDBusMethodInvocation *invocation,
                                             guint                  serial,
                                             guint                  crtc_id,
                                             GVariant              *red_v,
                                             GVariant              *green_v,
                                             GVariant              *blue_v)
{
  MetaMonitorManager *manager = META_MONITOR_MANAGER (skeleton);
  MetaMonitorManagerClass *klass;
  MetaCRTC *crtc;
  gsize size, dummy;
  unsigned short *red;
  unsigned short *green;
  unsigned short *blue;
  GBytes *red_bytes, *green_bytes, *blue_bytes;

  if (serial != manager->serial)
    {
      g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
                                             G_DBUS_ERROR_ACCESS_DENIED,
                                             "The requested configuration is based on stale information");
      return TRUE;
    }

  if (crtc_id >= manager->n_crtcs)
    {
      g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
                                             G_DBUS_ERROR_INVALID_ARGS,
                                             "Invalid crtc id");
      return TRUE;
    }
  crtc = &manager->crtcs[crtc_id];

  red_bytes = g_variant_get_data_as_bytes (red_v);
  green_bytes = g_variant_get_data_as_bytes (green_v);
  blue_bytes = g_variant_get_data_as_bytes (blue_v);

  size = g_bytes_get_size (red_bytes) / sizeof (unsigned short);
  red = (unsigned short*) g_bytes_get_data (red_bytes, &dummy);
  green = (unsigned short*) g_bytes_get_data (green_bytes, &dummy);
  blue = (unsigned short*) g_bytes_get_data (blue_bytes, &dummy);

  klass = META_MONITOR_MANAGER_GET_CLASS (manager);
  if (klass->set_crtc_gamma)
    klass->set_crtc_gamma (manager, crtc, size, red, green, blue);

  meta_dbus_display_config_complete_set_crtc_gamma (skeleton, invocation);

  g_bytes_unref (red_bytes);
  g_bytes_unref (green_bytes);
  g_bytes_unref (blue_bytes);

  return TRUE;
}
Exemplo n.º 2
0
static void test_type(const char *type) {
        CVariant *cv;
        GVariant *gv;
        GBytes *cb, *gb;
        const void *cd, *gd;

        test_generate(type, &cv, &gv);

        cb = test_cv_get_data_as_bytes(cv);
        gb = g_variant_get_data_as_bytes(gv);

        if (g_bytes_compare(cb, gb)) {
                fprintf(stderr, "FAILED: %s\n", type);

                cd = g_bytes_get_data(cb, NULL);
                gd = g_bytes_get_data(gb, NULL);

                fprintf(stderr, "Buffers: %p:%zu %p:%zu\n",
                        cd, g_bytes_get_size(cb),
                        gd, g_bytes_get_size(gb));

                test_print_cv(cv);
                assert(0);
        }

        test_compare(cv, gv);

        g_bytes_unref(gb);
        g_bytes_unref(cb);
        g_variant_unref(gv);
        c_variant_free(cv);
}
static gpointer read_characteristic_finish(
    GIO_ASYNCSEQ_HANDLE async_seq_handle,
    GAsyncResult* result,
    GError** error
)
{
    READ_CONTEXT* context = (READ_CONTEXT*)GIO_Async_Seq_GetContext(async_seq_handle);
    GBytes* result_value;
    GVariant* ret = g_dbus_proxy_call_finish(
        G_DBUS_PROXY(context->characteristic),
        result,
        error
    );
    if (ret != NULL && *error == NULL)
    {
        result_value = g_variant_get_data_as_bytes(ret);
        g_variant_unref(ret);
    }
    else
    {
        result_value = NULL;
    }
    
    return result_value;
}
Exemplo n.º 4
0
static gboolean
handle_install_bundle (FlatpakSystemHelper   *object,
                       GDBusMethodInvocation *invocation,
                       const gchar           *arg_bundle_path,
                       guint32                arg_flags,
                       GVariant              *arg_gpg_key)
{
  g_autoptr(FlatpakDir) system = dir_get_system ();
  g_autoptr(GFile) path = g_file_new_for_path (arg_bundle_path);
  g_autoptr(GError) error = NULL;
  g_autoptr(GBytes) gpg_data = NULL;
  g_autofree char *ref = NULL;

  g_debug ("InstallBundle %s %u %p", arg_bundle_path, arg_flags, arg_gpg_key);

  if (arg_flags != 0)
    {
      g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS,
                                             "Unsupported flags enabled: 0x%x", arg_flags);
      return TRUE;
    }

  if (!g_file_query_exists (path, NULL))
    {
      g_dbus_method_invocation_return_error (invocation, G_IO_ERROR, G_IO_ERROR_NOT_FOUND,
                                             "Bundle %s does not exist", arg_bundle_path);
      return TRUE;
    }

  if (g_variant_get_size (arg_gpg_key) > 0)
    gpg_data = g_variant_get_data_as_bytes (arg_gpg_key);

  if (!flatpak_dir_install_bundle (system, path, gpg_data, &ref, NULL, &error))
    {
      g_dbus_method_invocation_return_gerror  (invocation, error);
      return TRUE;
    }

  flatpak_system_helper_complete_install_bundle (object, invocation, ref);

  return TRUE;
}
/**
 * ostree_repo_static_delta_execute_offline:
 * @self: Repo
 * @dir_or_file: Path to a directory containing static delta data, or directly to the superblock
 * @skip_validation: If %TRUE, assume data integrity
 * @cancellable: Cancellable
 * @error: Error
 *
 * Given a directory representing an already-downloaded static delta
 * on disk, apply it, generating a new commit.  The directory must be
 * named with the form "FROM-TO", where both are checksums, and it
 * must contain a file named "superblock", along with at least one part.
 */
gboolean
ostree_repo_static_delta_execute_offline (OstreeRepo                    *self,
                                          GFile                         *dir_or_file,
                                          gboolean                       skip_validation,
                                          GCancellable                  *cancellable,
                                          GError                      **error)
{
  gboolean ret = FALSE;
  guint i, n;
  const char *dir_or_file_path = NULL;
  glnx_fd_close int meta_fd = -1;
  glnx_fd_close int dfd = -1;
  g_autoptr(GVariant) meta = NULL;
  g_autoptr(GVariant) headers = NULL;
  g_autoptr(GVariant) metadata = NULL;
  g_autoptr(GVariant) fallback = NULL;
  g_autofree char *to_checksum = NULL;
  g_autofree char *from_checksum = NULL;
  g_autofree char *basename = NULL;

  dir_or_file_path = gs_file_get_path_cached (dir_or_file);

  /* First, try opening it as a directory */
  dfd = glnx_opendirat_with_errno (AT_FDCWD, dir_or_file_path, TRUE);
  if (dfd < 0)
    {
      if (errno != ENOTDIR)
        {
          glnx_set_error_from_errno (error);
          goto out;
        }
      else
        {
          g_autofree char *dir = dirname (g_strdup (dir_or_file_path));
          basename = g_path_get_basename (dir_or_file_path);

          if (!glnx_opendirat (AT_FDCWD, dir, TRUE, &dfd, error))
            goto out;
        }
    }
  else
    basename = g_strdup ("superblock");

  meta_fd = openat (dfd, basename, O_RDONLY | O_CLOEXEC);
  if (meta_fd < 0)
    {
      glnx_set_error_from_errno (error);
      goto out;
    }
  
  if (!ot_util_variant_map_fd (meta_fd, 0, G_VARIANT_TYPE (OSTREE_STATIC_DELTA_SUPERBLOCK_FORMAT),
                               FALSE, &meta, error))
    goto out;

  /* Parsing OSTREE_STATIC_DELTA_SUPERBLOCK_FORMAT */

  metadata = g_variant_get_child_value (meta, 0);

  /* Write the to-commit object */
  {
    g_autoptr(GVariant) to_csum_v = NULL;
    g_autoptr(GVariant) from_csum_v = NULL;
    g_autoptr(GVariant) to_commit = NULL;
    gboolean have_to_commit;
    gboolean have_from_commit;

    to_csum_v = g_variant_get_child_value (meta, 3);
    if (!ostree_validate_structureof_csum_v (to_csum_v, error))
      goto out;
    to_checksum = ostree_checksum_from_bytes_v (to_csum_v);

    from_csum_v = g_variant_get_child_value (meta, 2);
    if (g_variant_n_children (from_csum_v) > 0)
      {
        if (!ostree_validate_structureof_csum_v (from_csum_v, error))
          goto out;
        from_checksum = ostree_checksum_from_bytes_v (from_csum_v);

        if (!ostree_repo_has_object (self, OSTREE_OBJECT_TYPE_COMMIT, from_checksum,
                                     &have_from_commit, cancellable, error))
          goto out;

        if (!have_from_commit)
          {
            g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
                         "Commit %s, which is the delta source, is not in repository", from_checksum);
            goto out;
          }
      }

    if (!ostree_repo_has_object (self, OSTREE_OBJECT_TYPE_COMMIT, to_checksum,
                                 &have_to_commit, cancellable, error))
      goto out;
    
    if (!have_to_commit)
      {
        g_autofree char *detached_path = _ostree_get_relative_static_delta_path (from_checksum, to_checksum, "commitmeta");
        g_autoptr(GVariant) detached_data = NULL;

        detached_data = g_variant_lookup_value (metadata, detached_path, G_VARIANT_TYPE("a{sv}"));
        if (detached_data && !ostree_repo_write_commit_detached_metadata (self,
                                                                          to_checksum,
                                                                          detached_data,
                                                                          cancellable,
                                                                          error))
          goto out;

        to_commit = g_variant_get_child_value (meta, 4);
        if (!ostree_repo_write_metadata (self, OSTREE_OBJECT_TYPE_COMMIT,
                                         to_checksum, to_commit, NULL,
                                         cancellable, error))
          goto out;
      }
  }

  fallback = g_variant_get_child_value (meta, 7);
  if (g_variant_n_children (fallback) > 0)
    {
      g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
                   "Cannot execute delta offline: contains nonempty http fallback entries");
      goto out;
    }

  headers = g_variant_get_child_value (meta, 6);
  n = g_variant_n_children (headers);
  for (i = 0; i < n; i++)
    {
      guint32 version;
      guint64 size;
      guint64 usize;
      const guchar *csum;
      char checksum[OSTREE_SHA256_STRING_LEN+1];
      gboolean have_all;
      g_autoptr(GInputStream) part_in = NULL;
      g_autoptr(GVariant) inline_part_data = NULL;
      g_autoptr(GVariant) header = NULL;
      g_autoptr(GVariant) csum_v = NULL;
      g_autoptr(GVariant) objects = NULL;
      g_autoptr(GVariant) part = NULL;
      g_autofree char *deltapart_path = NULL;
      OstreeStaticDeltaOpenFlags delta_open_flags = 
        skip_validation ? OSTREE_STATIC_DELTA_OPEN_FLAGS_SKIP_CHECKSUM : 0;

      header = g_variant_get_child_value (headers, i);
      g_variant_get (header, "(u@aytt@ay)", &version, &csum_v, &size, &usize, &objects);

      if (version > OSTREE_DELTAPART_VERSION)
        {
          g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
                       "Delta part has too new version %u", version);
          goto out;
        }

      if (!_ostree_repo_static_delta_part_have_all_objects (self, objects, &have_all,
                                                            cancellable, error))
        goto out;

      /* If we already have these objects, don't bother executing the
       * static delta.
       */
      if (have_all)
        continue;

      csum = ostree_checksum_bytes_peek_validate (csum_v, error);
      if (!csum)
        goto out;
      ostree_checksum_inplace_from_bytes (csum, checksum);

      deltapart_path =
        _ostree_get_relative_static_delta_part_path (from_checksum, to_checksum, i);

      inline_part_data = g_variant_lookup_value (metadata, deltapart_path, G_VARIANT_TYPE("(yay)"));
      if (inline_part_data)
        {
          g_autoptr(GBytes) inline_part_bytes = g_variant_get_data_as_bytes (inline_part_data);
          part_in = g_memory_input_stream_new_from_bytes (inline_part_bytes);

          /* For inline parts, we don't checksum, because it's
           * included with the metadata, so we're not trying to
           * protect against MITM or such.  Non-security related
           * checksums should be done at the underlying storage layer.
           */
          delta_open_flags |= OSTREE_STATIC_DELTA_OPEN_FLAGS_SKIP_CHECKSUM;

          if (!_ostree_static_delta_part_open (part_in, inline_part_bytes, 
                                               delta_open_flags,
                                               NULL,
                                               &part,
                                               cancellable, error))
            goto out;
        }
      else
        {
          g_autofree char *relpath = g_strdup_printf ("%u", i); /* TODO avoid malloc here */
          glnx_fd_close int part_fd = openat (dfd, relpath, O_RDONLY | O_CLOEXEC);
          if (part_fd < 0)
            {
              glnx_set_error_from_errno (error);
              g_prefix_error (error, "Opening deltapart '%s': ", deltapart_path);
              goto out;
            }

          part_in = g_unix_input_stream_new (part_fd, FALSE);

          if (!_ostree_static_delta_part_open (part_in, NULL, 
                                               delta_open_flags,
                                               checksum,
                                               &part,
                                               cancellable, error))
            goto out;
        }

      if (!_ostree_static_delta_part_execute (self, objects, part, skip_validation,
                                              NULL, cancellable, error))
        {
          g_prefix_error (error, "Executing delta part %i: ", i);
          goto out;
        }
    }

  ret = TRUE;
 out:
  return ret;
}
gboolean
rpmostree_compose_builtin_sign (int            argc,
                                char         **argv,
                                GCancellable  *cancellable,
                                GError       **error)
{
  gboolean ret = FALSE;
  GOptionContext *context = g_option_context_new ("- Use rpm-sign to sign an OSTree commit");
  gs_unref_object GFile *repopath = NULL;
  gs_unref_object OstreeRepo *repo = NULL;
  gs_unref_object GFile *tmp_commitdata_file = NULL;
  gs_unref_object GFileIOStream *tmp_sig_stream = NULL;
  gs_unref_object GFile *tmp_sig_file = NULL;
  gs_unref_object GFileIOStream *tmp_commitdata_stream = NULL;
  GOutputStream *tmp_commitdata_output = NULL;
  gs_unref_object GInputStream *commit_data = NULL;
  gs_free char *checksum = NULL;
  gs_unref_variant GVariant *commit_variant = NULL;
  gs_unref_bytes GBytes *commit_bytes = NULL;
  
  if (!rpmostree_option_context_parse (context, option_entries, &argc, &argv, error))
    goto out;

  if (!(opt_repo_path && opt_key_id && opt_rev))
    {
      g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
                   "Missing required argument");
      goto out;
    }

  repopath = g_file_new_for_path (opt_repo_path);
  repo = ostree_repo_new (repopath);
  if (!ostree_repo_open (repo, cancellable, error))
    goto out;

  if (!ostree_repo_resolve_rev (repo, opt_rev, FALSE, &checksum, error))
    goto out;

  if (!ostree_repo_load_variant (repo, OSTREE_OBJECT_TYPE_COMMIT,
                                 checksum, &commit_variant, error))
    goto out;

  commit_bytes = g_variant_get_data_as_bytes (commit_variant);
  commit_data = (GInputStream*)g_memory_input_stream_new_from_bytes (commit_bytes);
  
  tmp_commitdata_file = g_file_new_tmp ("tmpsigXXXXXX", &tmp_commitdata_stream,
                                       error);
  if (!tmp_commitdata_file)
    goto out;

  tmp_commitdata_output = (GOutputStream*)g_io_stream_get_output_stream ((GIOStream*)tmp_commitdata_stream);
  if (g_output_stream_splice ((GOutputStream*)tmp_commitdata_output,
                              commit_data,
                              G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE |
                              G_OUTPUT_STREAM_SPLICE_CLOSE_TARGET,
                              cancellable, error) < 0)
    goto out;

  tmp_sig_file = g_file_new_tmp ("tmpsigoutXXXXXX", &tmp_sig_stream, error);
  if (!tmp_sig_file)
    goto out;

  (void) g_io_stream_close ((GIOStream*)tmp_sig_stream, NULL, NULL);
                                  
  if (!gs_subprocess_simple_run_sync (NULL, GS_SUBPROCESS_STREAM_DISPOSITION_NULL,
                                      cancellable, error,
                                      "rpm-sign",
                                      "--key", opt_key_id,
                                      "--detachsign", gs_file_get_path_cached (tmp_commitdata_file),
                                      "--output", gs_file_get_path_cached (tmp_sig_file),
                                      NULL))
    goto out;

  {
    char *sigcontent = NULL;
    gsize len;
    gs_unref_bytes GBytes *sigbytes = NULL;

    if (!g_file_load_contents (tmp_sig_file, cancellable, &sigcontent, &len, NULL,
                               error))
      goto out;

    sigbytes = g_bytes_new_take (sigcontent, len);

    if (!ostree_repo_append_gpg_signature (repo, checksum, sigbytes,
                                           cancellable, error))
      goto out;
  }

  g_print ("Successfully signed OSTree commit=%s with key=%s\n",
           checksum, opt_key_id);
  
  ret = TRUE;
 out:
  if (tmp_commitdata_file)
    (void) gs_file_unlink (tmp_commitdata_file, NULL, NULL);
  if (tmp_sig_file)
    (void) gs_file_unlink (tmp_sig_file, NULL, NULL);
  return ret;
}
Exemplo n.º 7
0
static gboolean
handle_configure_remote (FlatpakSystemHelper *object,
                         GDBusMethodInvocation *invocation,
                         guint arg_flags,
                         const gchar *arg_remote,
                         const gchar *arg_config,
                         GVariant *arg_gpg_key)
{
  g_autoptr(FlatpakDir) system = dir_get_system ();
  g_autoptr(GError) error = NULL;
  g_autoptr(GKeyFile) config = g_key_file_new ();
  g_autofree char *group = g_strdup_printf ("remote \"%s\"", arg_remote);
  g_autoptr(GBytes) gpg_data = NULL;
  gboolean force_remove;

  g_debug ("ConfigureRemote %u %s", arg_flags, arg_remote);

  if (*arg_remote == 0 || strchr (arg_remote, '/') != NULL)
    {
      g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS,
                                             "Invalid remote name: %s", arg_remote);
      return TRUE;
    }

  if ((arg_flags & ~FLATPAK_HELPER_CONFIGURE_REMOTE_FLAGS_ALL) != 0)
    {
      g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS,
                                             "Unsupported flags enabled: 0x%x", (arg_flags & ~FLATPAK_HELPER_CONFIGURE_REMOTE_FLAGS_ALL));
      return TRUE;
    }

  if (!g_key_file_load_from_data (config, arg_config, strlen (arg_config),
                                  G_KEY_FILE_NONE, &error))
    {
      g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS,
                                             "Invalid config: %s\n", error->message);
      return TRUE;
    }

  if (!flatpak_dir_ensure_repo (system, NULL, &error))
    {
      g_dbus_method_invocation_return_gerror  (invocation, error);
      return TRUE;
    }

  if (g_variant_get_size (arg_gpg_key) > 0)
    gpg_data = g_variant_get_data_as_bytes (arg_gpg_key);

  force_remove = (arg_flags & FLATPAK_HELPER_CONFIGURE_REMOTE_FLAGS_FORCE_REMOVE) != 0;

  if (g_key_file_has_group (config, group))
    {
      /* Add/Modify */
      if (!flatpak_dir_modify_remote (system, arg_remote, config,
                                      gpg_data, NULL, &error))
        {
          g_dbus_method_invocation_return_gerror  (invocation, error);
          return TRUE;
        }
    }
  else
    {
      /* Remove */
      if (!flatpak_dir_remove_remote (system,
                                      force_remove,
                                      arg_remote,
                                      NULL, &error))
        {
          g_dbus_method_invocation_return_gerror  (invocation, error);
          return TRUE;
        }
    }

  flatpak_system_helper_complete_configure_remote (object, invocation);

  return TRUE;
}
Exemplo n.º 8
0
/*****************************************************************************
 * neardal_tag_prv_read_properties: Get Neard Tag Properties
 ****************************************************************************/
static errorCode_t neardal_tag_prv_read_properties(TagProp *tagProp)
{
	errorCode_t	err		= NEARDAL_SUCCESS;
	GVariant	*tmp		= NULL;
	GVariant	*tmpOut		= NULL;
	gsize		len;

	NEARDAL_TRACEIN();
	NEARDAL_ASSERT_RET(tagProp != NULL, NEARDAL_ERROR_INVALID_PARAMETER);
	NEARDAL_ASSERT_RET(tagProp->proxy != NULL
			  , NEARDAL_ERROR_GENERAL_ERROR);

	tmp = g_datalist_get_data(&(neardalMgr.dbus_data), tagProp->name);
	if (tmp == NULL) {
		err = NEARDAL_ERROR_NO_TAG;
		NEARDAL_TRACE_ERR("Unable to read tag's properties\n");
		goto exit;
	}
	NEARDAL_TRACEF("Reading:\n%s\n", g_variant_print(tmp, TRUE));

	tmpOut = g_variant_lookup_value(tmp, "TagType", G_VARIANT_TYPE_ARRAY);
	if (tmpOut != NULL) {
		tagProp->tagType = g_variant_dup_strv(tmpOut, &len);
		tagProp->tagTypeLen = len;
		if (len == 0) {
			g_strfreev(tagProp->tagType);
			tagProp->tagType = NULL;
		}
	}

	tmpOut = g_variant_lookup_value(tmp, "Type", G_VARIANT_TYPE_STRING);
	if (tmpOut != NULL)
		tagProp->type = g_variant_dup_string(tmpOut, NULL);

	tmpOut = g_variant_lookup_value(tmp, "ReadOnly",
					G_VARIANT_TYPE_BOOLEAN);
	if (tmpOut != NULL)
		tagProp->readOnly = g_variant_get_boolean(tmpOut);

	/* ISO14443A-specific fields (optional) */
	tmpOut = g_variant_lookup_value(tmp, "Iso14443aAtqa",
			G_VARIANT_TYPE_BYTESTRING);
	if ( (tmpOut != NULL) && (g_variant_n_children(tmpOut) > 0) )
		tagProp->iso14443aAtqa = g_variant_get_data_as_bytes(tmpOut);

	tmpOut = g_variant_lookup_value(tmp, "Iso14443aSak",
			G_VARIANT_TYPE_BYTESTRING);
	if ( (tmpOut != NULL) && (g_variant_n_children(tmpOut) > 0) )
		tagProp->iso14443aSak = g_variant_get_data_as_bytes(tmpOut);

	tmpOut = g_variant_lookup_value(tmp, "Iso14443aUid",
			G_VARIANT_TYPE_BYTESTRING);
	if ( (tmpOut != NULL) && (g_variant_n_children(tmpOut) > 0) )
		tagProp->iso14443aUid = g_variant_get_data_as_bytes(tmpOut);

	/* Felica-specific fields (optional) */
	tmpOut = g_variant_lookup_value(tmp, "FelicaManufacturer",
			G_VARIANT_TYPE_BYTESTRING);
	if ( (tmpOut != NULL) && (g_variant_n_children(tmpOut) > 0) )
		tagProp->felicaManufacturer = g_variant_get_data_as_bytes(tmpOut);

	tmpOut = g_variant_lookup_value(tmp, "FelicaCid",
			G_VARIANT_TYPE_BYTESTRING);
	if ( (tmpOut != NULL) && (g_variant_n_children(tmpOut) > 0) )
		tagProp->felicaCid = g_variant_get_data_as_bytes(tmpOut);

	tmpOut = g_variant_lookup_value(tmp, "FelicaIc",
			G_VARIANT_TYPE_BYTESTRING);
	if ( (tmpOut != NULL) && (g_variant_n_children(tmpOut) > 0) )
		tagProp->felicaIc = g_variant_get_data_as_bytes(tmpOut);

	tmpOut = g_variant_lookup_value(tmp, "FelicaMaxRespTimes",
			G_VARIANT_TYPE_BYTESTRING);
	if ( (tmpOut != NULL) && (g_variant_n_children(tmpOut) > 0) )
		tagProp->felicaMaxRespTimes = g_variant_get_data_as_bytes(tmpOut);

exit:
	return err;
}
int
rpmostree_compose_builtin_sign (int            argc,
                                char         **argv,
                                GCancellable  *cancellable,
                                GError       **error)
{
  int exit_status = EXIT_FAILURE;
  GOptionContext *context = g_option_context_new ("- Use rpm-sign to sign an OSTree commit");
  g_autoptr(GFile) repopath = NULL;
  glnx_unref_object OstreeRepo *repo = NULL;
  g_autoptr(GFile) tmp_commitdata_file = NULL;
  g_autoptr(GFileIOStream) tmp_sig_stream = NULL;
  g_autoptr(GFile) tmp_sig_file = NULL;
  g_autoptr(GFileIOStream) tmp_commitdata_stream = NULL;
  GOutputStream *tmp_commitdata_output = NULL;
  g_autoptr(GInputStream) commit_data = NULL;
  g_autofree char *checksum = NULL;
  g_autoptr(GVariant) commit_variant = NULL;
  g_autoptr(GBytes) commit_bytes = NULL;
  
  if (!rpmostree_option_context_parse (context,
                                       option_entries,
                                       &argc, &argv,
                                       RPM_OSTREE_BUILTIN_FLAG_LOCAL_CMD,
                                       cancellable,
                                       NULL,
                                       error))
    goto out;

  if (!(opt_repo_path && opt_key_id && opt_rev))
    {
      rpmostree_usage_error (context, "Missing required argument", error);
      goto out;
    }

  repopath = g_file_new_for_path (opt_repo_path);
  repo = ostree_repo_new (repopath);
  if (!ostree_repo_open (repo, cancellable, error))
    goto out;

  if (!ostree_repo_resolve_rev (repo, opt_rev, FALSE, &checksum, error))
    goto out;

  if (!ostree_repo_load_variant (repo, OSTREE_OBJECT_TYPE_COMMIT,
                                 checksum, &commit_variant, error))
    goto out;

  commit_bytes = g_variant_get_data_as_bytes (commit_variant);
  commit_data = (GInputStream*)g_memory_input_stream_new_from_bytes (commit_bytes);
  
  tmp_commitdata_file = g_file_new_tmp ("tmpsigXXXXXX", &tmp_commitdata_stream,
                                       error);
  if (!tmp_commitdata_file)
    goto out;

  tmp_commitdata_output = (GOutputStream*)g_io_stream_get_output_stream ((GIOStream*)tmp_commitdata_stream);
  if (g_output_stream_splice ((GOutputStream*)tmp_commitdata_output,
                              commit_data,
                              G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE |
                              G_OUTPUT_STREAM_SPLICE_CLOSE_TARGET,
                              cancellable, error) < 0)
    goto out;

  tmp_sig_file = g_file_new_tmp ("tmpsigoutXXXXXX", &tmp_sig_stream, error);
  if (!tmp_sig_file)
    goto out;

  (void) g_io_stream_close ((GIOStream*)tmp_sig_stream, NULL, NULL);
                                  

  { const char *child_argv[] = { "rpm-sign",
                                 "--key", opt_key_id,
                                 "--detachsign", gs_file_get_path_cached (tmp_commitdata_file),
                                 "--output", gs_file_get_path_cached (tmp_sig_file),
                                 NULL };
    int estatus;
    
    if (!g_spawn_sync (NULL, (char**)child_argv, NULL, G_SPAWN_SEARCH_PATH, NULL, NULL,
                       NULL, NULL, &estatus, error))
      goto out;
    if (!g_spawn_check_exit_status (estatus, error))
      goto out;
  }

  {
    char *sigcontent = NULL;
    gsize len;
    g_autoptr(GBytes) sigbytes = NULL;

    if (!g_file_load_contents (tmp_sig_file, cancellable, &sigcontent, &len, NULL,
                               error))
      goto out;

    sigbytes = g_bytes_new_take (sigcontent, len);

    if (!ostree_repo_append_gpg_signature (repo, checksum, sigbytes,
                                           cancellable, error))
      goto out;
  }

  g_print ("Successfully signed OSTree commit=%s with key=%s\n",
           checksum, opt_key_id);
  
  exit_status = EXIT_SUCCESS;

 out:
  if (tmp_commitdata_file)
    (void) unlink (gs_file_get_path_cached (tmp_commitdata_file));
  if (tmp_sig_file)
    (void) unlink (gs_file_get_path_cached (tmp_sig_file));

  return exit_status;
}