Example #1
0
static void
builder_source_file_checksum (BuilderSource  *source,
                              BuilderCache   *cache,
                              BuilderContext *context)
{
  BuilderSourceFile *self = BUILDER_SOURCE_FILE (source);
  g_autoptr(GFile) src = NULL;
  g_autofree char *data = NULL;
  gsize len;
  gboolean is_local, is_inline;

  src = get_source_file (self, context, &is_local, &is_inline, NULL);
  if (src == NULL)
    return;

  if (is_local &&
      g_file_load_contents (src, NULL, &data, &len, NULL, NULL))
    builder_cache_checksum_data (cache, (guchar *)data, len);

  builder_cache_checksum_str (cache, self->path);
  builder_cache_checksum_str (cache, self->url);
  builder_cache_checksum_str (cache, self->sha256);
  builder_cache_checksum_str (cache, self->dest_filename);
}
Example #2
0
static void
on_systemd_shutdown_scheduled_changed (GFileMonitor *monitor,
                                       GFile *file,
                                       GFile *other_file,
                                       GFileMonitorEvent event_type,
                                       gpointer user_data)
{
  Manager *manager = user_data;
  GError *error = NULL;
  gs_free char *scheduled_contents = NULL;

  if (!g_file_load_contents (file, NULL,
                             &scheduled_contents, NULL,
                             NULL, &error))
    {
      if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))
        cockpit_manager_set_shutdown_schedule (COCKPIT_MANAGER(manager), NULL);
      else
        g_warning ("%s", error->message);
      g_error_free (error);
    }
  else
    parse_scheduled_contents (manager, scheduled_contents);
}
static GdkPixbuf *
impl_load_pixbuf_file (const char     *uri,
                       int             available_width,
                       int             available_height,
                       GError        **error)
{
  GdkPixbuf *pixbuf = NULL;
  GFile *file;
  char *contents = NULL;
  gsize size;

  file = g_file_new_for_uri (uri);
  if (g_file_load_contents (file, NULL, &contents, &size, NULL, error))
    {
      pixbuf = impl_load_pixbuf_data ((const guchar *) contents, size,
                                      available_width, available_height,
                                      error);
    }

  g_object_unref (file);
  g_free (contents);

  return pixbuf;
}
Example #4
0
/**
 * cd_util_create_colprof:
 **/
static gboolean
cd_util_create_colprof (CdUtilPrivate *priv,
			CdDom *dom,
			const GNode *root,
			GError **error)
{
	const gchar *basename = "profile";
	const gchar *data_ti3;
	const gchar *viewcond;
	const GNode *node_enle;
	const GNode *node_enpo;
	const GNode *node_shape;
	const GNode *node_stle;
	const GNode *node_stpo;
	const GNode *tmp;
	gboolean ret = FALSE;
	gdouble enle;
	gdouble enpo;
	gdouble klimit;
	gdouble shape;
	gdouble stle;
	gdouble stpo;
	gdouble tlimit;
	gint exit_status = 0;
	gsize len = 0;
	g_autofree gchar *cmdline = NULL;
	g_autofree gchar *data = NULL;
	g_autofree gchar *debug_stderr = NULL;
	g_autofree gchar *debug_stdout = NULL;
	g_autofree gchar *output_fn = NULL;
	g_autofree gchar *ti3_fn = NULL;
	g_autoptr(GFile) output_file = NULL;
	g_autoptr(GFile) ti3_file = NULL;
	g_autoptr(GPtrArray) argv = NULL;

#ifndef TOOL_COLPROF
	/* no support */
	g_set_error_literal (error, 1, 0,
			     "not compiled with --enable-print-profiles");
	return FALSE;
#endif

	/* create common options */
	argv = g_ptr_array_new_with_free_func (g_free);
#ifdef TOOL_COLPROF
	g_ptr_array_add (argv, g_strdup (TOOL_COLPROF));
#endif
	g_ptr_array_add (argv, g_strdup ("-nc"));	/* no embedded ti3 */
	g_ptr_array_add (argv, g_strdup ("-qm"));	/* medium quality */
	g_ptr_array_add (argv, g_strdup ("-bm"));	/* medium quality B2A */

	/* get values */
	node_stle = cd_dom_get_node (dom, root, "stle");
	node_stpo = cd_dom_get_node (dom, root, "stpo");
	node_enpo = cd_dom_get_node (dom, root, "enpo");
	node_enle = cd_dom_get_node (dom, root, "enle");
	node_shape = cd_dom_get_node (dom, root, "shape");
	if (node_stle != NULL && node_stpo != NULL && node_enpo != NULL &&
	    node_enle != NULL && node_shape != NULL) {
		stle = cd_dom_get_node_data_as_double (node_stle);
		stpo = cd_dom_get_node_data_as_double (node_stpo);
		enpo = cd_dom_get_node_data_as_double (node_enpo);
		enle = cd_dom_get_node_data_as_double (node_enle);
		shape = cd_dom_get_node_data_as_double (node_shape);
		if (stle == G_MAXDOUBLE || stpo == G_MAXDOUBLE || enpo == G_MAXDOUBLE ||
		    enle == G_MAXDOUBLE || shape == G_MAXDOUBLE) {
			g_set_error_literal (error, 1, 0,
					     "XML error: invalid stle, stpo, enpo, enle, shape");
			return FALSE;
		}
		g_ptr_array_add (argv, g_strdup ("-kp"));
		g_ptr_array_add (argv, g_strdup_printf ("%f", stle));
		g_ptr_array_add (argv, g_strdup_printf ("%f", stpo));
		g_ptr_array_add (argv, g_strdup_printf ("%f", enpo));
		g_ptr_array_add (argv, g_strdup_printf ("%f", enle));
		g_ptr_array_add (argv, g_strdup_printf ("%f", shape));
	}

	/* total ink limit */
	tmp = cd_dom_get_node (dom, root, "tlimit");
	if (tmp != NULL) {
		tlimit = cd_dom_get_node_data_as_double (tmp);
		if (tlimit == G_MAXDOUBLE) {
			g_set_error_literal (error, 1, 0,
					     "XML error: invalid tlimit");
			return FALSE;
		}
		g_ptr_array_add (argv, g_strdup_printf ("-l%.0f", tlimit));
	}

	/* black ink limit */
	tmp = cd_dom_get_node (dom, root, "klimit");
	if (tmp != NULL) {
		klimit = cd_dom_get_node_data_as_double (tmp);
		if (klimit == G_MAXDOUBLE) {
			g_set_error_literal (error, 1, 0,
					     "XML error: invalid klimit");
			return FALSE;
		}
		g_ptr_array_add (argv, g_strdup_printf ("-L%.0f", klimit));
	}

	/* input viewing conditions */
	tmp = cd_dom_get_node (dom, root, "input_viewing_conditions");
	if (tmp != NULL) {
		viewcond = cd_dom_get_node_data (tmp);
		g_ptr_array_add (argv, g_strdup_printf ("-c%s", viewcond));
	}

	/* output viewing conditions */
	tmp = cd_dom_get_node (dom, root, "output_viewing_conditions");
	if (tmp != NULL) {
		viewcond = cd_dom_get_node_data (tmp);
		g_ptr_array_add (argv, g_strdup_printf ("-d%s", viewcond));
	}

	/* get source filename and copy into working directory */
	tmp = cd_dom_get_node (dom, root, "data_ti3");
	if (tmp == NULL) {
		g_set_error_literal (error, 1, 0,
				     "XML error: no data_ti3");
		return FALSE;
	}
	data_ti3 = cd_dom_get_node_data (tmp);
	ti3_fn = g_strdup_printf ("/tmp/%s.ti3", basename);
	ti3_file = g_file_new_for_path (ti3_fn);
	ret = g_file_replace_contents (ti3_file,
				       data_ti3,
				       strlen (data_ti3),
				       NULL,
				       FALSE,
				       G_FILE_CREATE_NONE,
				       NULL,
				       NULL,
				       error);
	if (!ret)
		return FALSE;

	/* ensure temporary icc profile does not already exist */
	output_fn = g_strdup_printf ("/tmp/%s.icc", basename);
	output_file = g_file_new_for_path (output_fn);
	if (g_file_query_exists (output_file, NULL)) {
		if (!g_file_delete (output_file, NULL, error))
			return FALSE;
	}

	/* run colprof in working directory */
	g_ptr_array_add (argv, g_strdup_printf ("-O%s.icc", basename));
	g_ptr_array_add (argv, g_strdup (basename));
	g_ptr_array_add (argv, NULL);
	ret = g_spawn_sync ("/tmp",
			    (gchar **) argv->pdata,
			    NULL,
			    0,
			    NULL, NULL,
			    &debug_stdout,
			    &debug_stderr,
			    &exit_status,
			    error);
	if (!ret)
		return FALSE;

	/* failed */
	if (exit_status != 0) {
		cmdline = g_strjoinv (" ", (gchar **) argv->pdata);
		g_set_error (error, 1, 0,
			     "Failed to generate %s using '%s'\nOutput: %s\nError:\t%s",
			     output_fn, cmdline, debug_stdout, debug_stderr);
		return FALSE;
	}

	/* load resulting .icc file */
	if (!g_file_load_contents (output_file, NULL, &data, &len, NULL, error))
		return FALSE;

	/* open /tmp/$basename.icc as hProfile */
	priv->lcms_profile = cmsOpenProfileFromMemTHR (cd_icc_get_context (priv->icc),
						       data, len);
	if (priv->lcms_profile == NULL) {
		g_set_error (error, 1, 0,
			     "Failed to open generated %s",
			     output_fn);
		return FALSE;
	}

	/* delete temp files */
	if (!g_file_delete (output_file, NULL, error))
		return FALSE;
	if (!g_file_delete (ti3_file, NULL, error))
		return FALSE;
	return TRUE;
}
static GList *
get_bookmarks (void)
{
  GFile *file;
  gchar *contents;
  gchar *path;
  gchar **lines;
  GList *bookmarks;
  GError *error = NULL;

  path = g_build_filename (g_get_user_config_dir (), "gtk-3.0",
                           "bookmarks", NULL);
  file = g_file_new_for_path (path);
  g_free (path);

  contents = NULL;
  g_file_load_contents (file, NULL, &contents, NULL, NULL, &error);
  g_object_unref (file);

  bookmarks = NULL;
  lines = NULL;

  if (error != NULL)
    {
      g_error_free (error);
    }
  else
    {
      gint idx;

      lines = g_strsplit (contents, "\n", -1);
      for (idx = 0; lines[idx]; idx++)
        {
          /* Ignore empty or invalid lines that cannot be parsed properly */
          if (lines[idx][0] != '\0' && lines[idx][0] != ' ')
            {
              /* gtk 2.7/2.8 might have labels appended to bookmarks which are separated by a space */
              /* we must seperate the bookmark uri and the potential label */
              char *space, *label;
              Place *bookmark;

              label = NULL;
              space = strchr (lines[idx], ' ');
              if (space)
                {
                  *space = '\0';
                  label = g_strdup (space + 1);
                }

              bookmark = g_slice_new0 (Place);
              bookmark->location = g_file_new_for_uri (lines[idx]);

              if (label != NULL)
                bookmark->display_name = label;
              else
                bookmark->display_name = g_file_get_basename (bookmark->location);

              bookmark->place_type = PLACE_BOOKMARKS;

              bookmarks = g_list_prepend (bookmarks, bookmark);
            }
	}
    }

  g_strfreev (lines);
  g_free (contents);

  return g_list_reverse (bookmarks);
}
Example #6
0
static gpointer _dentry_ui_init(GtkBuilder *ui, gpointer uidata, FmFileInfoList *files)
{
    GObject *widget;
    GtkWidget *new_widget;
    FmFilePropertiesDEntryData *data;
    GtkTable *table;
    GtkLabel *label;
    GError *err = NULL;
    FmFileInfo *fi;
    GFile *gf;
    gchar *txt;
    gsize length;
    const gchar * const *langs;
    gboolean tmp_bool;

    /* disable permissions tab and open_with in any case */
#define HIDE_WIDGET(x) widget = gtk_builder_get_object(ui, x); \
        gtk_widget_hide(GTK_WIDGET(widget))
    /* HIDE_WIDGET("permissions_tab");
       TODO: made visibility of permissions_tab configurable */
    table = GTK_TABLE(gtk_builder_get_object(ui, "general_table"));
    HIDE_WIDGET("open_with");
    HIDE_WIDGET("open_with_label");
    gtk_table_set_row_spacing(table, 5, 0);
    /* we will do the thing only for single file! */
    if (fm_file_info_list_get_length(files) != 1)
        return NULL;
    fi = fm_file_info_list_peek_head(files);
    gf = fm_path_to_gfile(fm_file_info_get_path(fi));
    if (!g_file_load_contents(gf, NULL, &txt, &length, NULL, NULL))
    {
        g_warning("file properties dialog: cannot access desktop entry file");
        g_object_unref(gf);
        return NULL;
    }
    data = g_slice_new(FmFilePropertiesDEntryData);
    data->changed = FALSE;
    data->file = gf;
    data->kf = g_key_file_new();
    g_key_file_load_from_data(data->kf, txt, length,
                              G_KEY_FILE_KEEP_COMMENTS | G_KEY_FILE_KEEP_TRANSLATIONS,
                              NULL);
    g_free(txt);
    /* FIXME: handle errors, also do g_key_file_has_group() */
    /* get locale name */
    data->lang = NULL;
    langs = g_get_language_names();
    if (strcmp(langs[0], "C") != 0)
    {
        /* remove encoding from locale name */
        char *sep = strchr(langs[0], '.');
        if (sep)
            data->lang = g_strndup(langs[0], sep - langs[0]);
        else
            data->lang = g_strdup(langs[0]);
    }
    /* enable events for icon */
    widget = gtk_builder_get_object(ui, "icon_eventbox");
    data->icon = gtk_builder_get_object(ui, "icon");
    gtk_widget_set_can_focus(GTK_WIDGET(widget), TRUE);
    /* disable Name event handler in the widget */
    widget = gtk_builder_get_object(ui, "name");
    g_signal_handlers_block_matched(widget, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, uidata);
    g_signal_connect(widget, "changed", G_CALLBACK(_dentry_name_changed), data);
    data->name = GTK_ENTRY(widget);
    data->saved_name = g_strdup(gtk_entry_get_text(data->name));
    /* FIXME: two lines below is temporary workaround on FIXME in widget */
    gtk_widget_set_can_focus(GTK_WIDGET(widget), TRUE);
    gtk_editable_set_editable(GTK_EDITABLE(widget), TRUE);
    /* Name is set from "Name" by libfm already so don't touch it */
    /* support 'hidden' option */
    data->hidden = NULL;
    widget = gtk_builder_get_object(ui, "hidden");
    if (widget && GTK_IS_TOGGLE_BUTTON(widget) && fm_file_info_is_native(fi))
    {
        data->hidden = (GtkToggleButton*)widget;
        data->was_hidden = fm_file_info_is_hidden(fi);
        g_signal_connect(widget, "toggled", G_CALLBACK(_dentry_hidden_toggled), data);
        gtk_widget_set_can_focus(GTK_WIDGET(data->hidden), TRUE);
        /* set sensitive since it can be toggled for desktop entry */
        gtk_widget_set_sensitive(GTK_WIDGET(widget), TRUE);
        gtk_widget_show(GTK_WIDGET(data->hidden));
    }
#undef HIDE_WIDGET
    /* FIXME: migrate to GtkGrid */
    table = GTK_TABLE(gtk_table_new(8, 2, FALSE));
    gtk_table_set_row_spacings(table, 4);
    gtk_table_set_col_spacings(table, 12);
    gtk_container_set_border_width(GTK_CONTAINER(table), 4);
    /* row 0: "Exec" GtkHBox: GtkEntry+GtkButton */
    new_widget = gtk_label_new(NULL);
    label = GTK_LABEL(new_widget);
    gtk_misc_set_alignment(GTK_MISC(new_widget), 0.0, 0.0);
    gtk_label_set_markup_with_mnemonic(label, _("<b>Co_mmand:</b>"));
    gtk_table_attach(table, new_widget, 0, 1, 0, 1, GTK_FILL, 0, 0, 0);
#if GTK_CHECK_VERSION(3, 2, 0)
    /* FIXME: migrate to GtkGrid */
    widget = G_OBJECT(gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 6));
#else
    widget = G_OBJECT(gtk_hbox_new(FALSE, 6));
#endif
    new_widget = gtk_button_new_with_mnemonic(_("_Browse..."));
    gtk_box_pack_end(GTK_BOX(widget), new_widget, FALSE, FALSE, 0);
    g_signal_connect(new_widget, "clicked",
                     G_CALLBACK(_dentry_browse_exec_event), data);
    new_widget = gtk_entry_new();
    data->exec = GTK_ENTRY(new_widget);
    txt = g_key_file_get_locale_string(data->kf, GRP_NAME, "Exec", NULL, NULL);
    if (txt)
    {
        gtk_entry_set_text(data->exec, txt);
        g_free(txt);
    }
    gtk_widget_set_tooltip_text(new_widget,
                                _("Command to execute when the application icon is activated"));
    gtk_box_pack_start(GTK_BOX(widget), new_widget, TRUE, TRUE, 0);
    g_signal_connect(new_widget, "changed", G_CALLBACK(_dentry_exec_changed), data);
    gtk_table_attach(table, GTK_WIDGET(widget), 1, 2, 0, 1, GTK_FILL|GTK_EXPAND, 0, 0, 0);
    gtk_label_set_mnemonic_widget(label, new_widget);
    /* row 1: "Terminal" GtkCheckButton */
    new_widget = gtk_check_button_new_with_mnemonic(_("_Execute in terminal emulator"));
    data->terminal = GTK_TOGGLE_BUTTON(new_widget);
    tmp_bool = g_key_file_get_boolean(data->kf, GRP_NAME, "Terminal", &err);
    if (err) /* no such key present */
    {
        tmp_bool = FALSE;
        g_clear_error(&err);
    }
    gtk_toggle_button_set_active(data->terminal, tmp_bool);
    g_signal_connect(new_widget, "toggled", G_CALLBACK(_dentry_terminal_toggled), data);
    gtk_table_attach(table, new_widget, 0, 2, 1, 2, GTK_FILL, 0, 18, 0);
    /* row 2: "X-KeepTerminal" GtkCheckButton */
    new_widget = gtk_check_button_new_with_mnemonic(_("_Keep terminal window open after command execution"));
    data->keep_open = GTK_TOGGLE_BUTTON(new_widget);
    gtk_widget_set_sensitive(new_widget, tmp_bool); /* disable if not in terminal */
    tmp_bool = g_key_file_get_boolean(data->kf, GRP_NAME, "X-KeepTerminal", &err);
    if (err) /* no such key present */
    {
        tmp_bool = FALSE;
        g_clear_error(&err);
    }
    gtk_toggle_button_set_active(data->keep_open, tmp_bool);
    g_signal_connect(new_widget, "toggled", G_CALLBACK(_dentry_keepterm_toggled), data);
    gtk_table_attach(table, new_widget, 0, 2, 2, 3, GTK_FILL, 0, 27, 0);
    /* row 4: "GenericName" GtkEntry */
    new_widget = gtk_label_new(NULL);
    label = GTK_LABEL(new_widget);
    gtk_misc_set_alignment(GTK_MISC(new_widget), 0.0, 0.0);
    gtk_label_set_markup_with_mnemonic(label, _("<b>D_escription:</b>"));
    gtk_table_attach(table, new_widget, 0, 1, 4, 5, GTK_FILL, 0, 0, 0);
    new_widget = gtk_entry_new();
    data->generic_name = GTK_ENTRY(new_widget);
    txt = g_key_file_get_locale_string(data->kf, GRP_NAME, "GenericName", NULL, NULL);
    if (txt)
    {
        gtk_entry_set_text(data->generic_name, txt);
        g_free(txt);
    }
    gtk_widget_set_tooltip_text(new_widget, _("Generic name of the application"));
    g_signal_connect(new_widget, "changed", G_CALLBACK(_dentry_genname_changed), data);
    gtk_table_attach(table, new_widget, 1, 2, 4, 5, GTK_FILL|GTK_EXPAND, 0, 0, 0);
    gtk_label_set_mnemonic_widget(label, new_widget);
    /* row 3: "Path" GtkEntry */
    new_widget = gtk_label_new(NULL);
    label = GTK_LABEL(new_widget);
    gtk_misc_set_alignment(GTK_MISC(new_widget), 0.0, 0.0);
    gtk_label_set_markup_with_mnemonic(label, _("<b>_Working directory:</b>"));
    gtk_table_attach(table, new_widget, 0, 1, 3, 4, GTK_FILL, 0, 0, 0);
    new_widget = gtk_entry_new();
    data->path = GTK_ENTRY(new_widget);
    txt = g_key_file_get_locale_string(data->kf, GRP_NAME, "Path", NULL, NULL);
    if (txt)
    {
        gtk_entry_set_text(data->path, txt);
        g_free(txt);
    }
    gtk_widget_set_tooltip_text(new_widget,
                                _("The working directory to run the program in"));
    g_signal_connect(new_widget, "changed", G_CALLBACK(_dentry_path_changed), data);
    gtk_table_attach(table, new_widget, 1, 2, 3, 4, GTK_FILL|GTK_EXPAND, 0, 0, 0);
    gtk_label_set_mnemonic_widget(label, new_widget);
    /* row 5: "Comment" GtkEntry */
    new_widget = gtk_label_new(NULL);
    label = GTK_LABEL(new_widget);
    gtk_misc_set_alignment(GTK_MISC(new_widget), 0.0, 0.0);
    gtk_label_set_markup_with_mnemonic(label, _("<b>_Tooltip:</b>"));
    gtk_table_attach(table, new_widget, 0, 1, 5, 6, GTK_FILL, 0, 0, 0);
    new_widget = gtk_entry_new();
    data->comment = GTK_ENTRY(new_widget);
    txt = g_key_file_get_locale_string(data->kf, GRP_NAME, "Comment", NULL, NULL);
    if (txt)
    {
        gtk_entry_set_text(data->comment, txt);
        g_free(txt);
    }
    gtk_widget_set_tooltip_text(new_widget, _("Tooltip to show on application"));
    g_signal_connect(new_widget, "changed", G_CALLBACK(_dentry_tooltip_changed), data);
    gtk_table_attach(table, new_widget, 1, 2, 5, 6, GTK_FILL|GTK_EXPAND, 0, 0, 0);
    gtk_label_set_mnemonic_widget(label, new_widget);
    /* TODO: handle "TryExec" field ? */
    /* row 7: "StartupNotify" GtkCheckButton */
    new_widget = gtk_check_button_new_with_mnemonic(_("_Use startup notification"));
    data->notification = GTK_TOGGLE_BUTTON(new_widget);
    tmp_bool = g_key_file_get_boolean(data->kf, GRP_NAME, "StartupNotify", &err);
    if (err) /* no such key present */
    {
        tmp_bool = FALSE;
        g_clear_error(&err);
    }
    gtk_toggle_button_set_active(data->notification, tmp_bool);
    g_signal_connect(new_widget, "toggled", G_CALLBACK(_dentry_notification_toggled), data);
    gtk_table_attach(table, new_widget, 0, 2, 7, 8, GTK_FILL, 0, 0, 0);
    /* put the table into third tab and enable it */
    widget = gtk_builder_get_object(ui, "extra_tab_label");
    gtk_label_set_markup_with_mnemonic(GTK_LABEL(widget), _("_Desktop Entry"));
    widget = gtk_builder_get_object(ui, "extra_tab");
    gtk_container_add(GTK_CONTAINER(widget), GTK_WIDGET(table));
    gtk_widget_show_all(GTK_WIDGET(widget));
    return data;
}
Example #7
0
static gboolean
builder_source_file_extract (BuilderSource *source,
                             GFile *dest,
                             BuilderContext *context,
                             GError **error)
{
  BuilderSourceFile *self = BUILDER_SOURCE_FILE (source);
  g_autoptr(GFile) src = NULL;
  g_autoptr(GFile) dest_file = NULL;
  g_autofree char *dest_filename = NULL;
  gboolean is_local, is_inline;

  src = get_source_file (self, context, &is_local, &is_inline, error);
  if (src == NULL)
    return FALSE;

  if (self->dest_filename)
    dest_filename = g_strdup (self->dest_filename);
  else
    {
      if (is_inline)
        {
          g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
                       "No dest-filename set for inline file data");
          return FALSE;
        }
      dest_filename = g_file_get_basename (src);
    }

  dest_file = g_file_get_child (dest, dest_filename);

  if (is_inline)
    {
      g_autoptr(GBytes) content = NULL;

      content = download_uri (self->url,
                              context,
                              error);
      if (content == NULL)
        return FALSE;

      if (!g_file_replace_contents (dest_file,
                                    g_bytes_get_data (content, NULL),
                                    g_bytes_get_size (content),
                                    NULL, FALSE, G_FILE_CREATE_NONE, NULL,
                                    NULL, error))
        return FALSE;
    }
  else
    {
      if (is_local)
        {
          g_autofree char *data = NULL;
          g_autofree char *base64 = NULL;
          gsize len;

          if (!g_file_load_contents (src, NULL, &data, &len, NULL, error))
            return FALSE;

          base64 = g_base64_encode ((const guchar *)data, len);
          g_free (self->url);
          self->url = g_strdup_printf ("data:text/plain;charset=utf8;base64,%s", base64);
          if (self->dest_filename == NULL || *self->dest_filename == 0)
            {
              g_free (self->dest_filename);
              self->dest_filename = g_file_get_basename (src);
            }
        }

      if (!g_file_copy (src, dest_file,
                        G_FILE_COPY_OVERWRITE,
                        NULL,
                        NULL, NULL,
                        error))
        return FALSE;
    }

  return TRUE;
}
Example #8
0
static void
jpeg_thumbnailer_create (TumblerAbstractThumbnailer *thumbnailer,
                         GCancellable               *cancellable,
                         TumblerFileInfo            *info)
{
  TumblerThumbnailFlavor *flavor;
  TumblerImageData        data;
  TumblerThumbnail       *thumbnail;
  struct stat             statb;
  const gchar            *uri;
  GdkPixbuf              *pixbuf = NULL;
  gboolean                streaming_needed = TRUE;
  JOCTET                 *content;
  GError                 *error = NULL;
  GFile                  *file;
  gchar                  *path;
  gsize                   length;
  gint                    fd;
  gint                    height;
  gint                    width;
  gint                    size;

  g_return_if_fail (IS_JPEG_THUMBNAILER (thumbnailer));
  g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
  g_return_if_fail (TUMBLER_IS_FILE_INFO (info));

  /* do nothing if cancelled */
  if (g_cancellable_is_cancelled (cancellable)) 
    return;

  uri = tumbler_file_info_get_uri (info);

  /* try to open the source file for reading */
  file = g_file_new_for_uri (uri);

  thumbnail = tumbler_file_info_get_thumbnail (info);
  g_assert (thumbnail != NULL);

  flavor = tumbler_thumbnail_get_flavor (thumbnail);
  g_assert (flavor != NULL);

  tumbler_thumbnail_flavor_get_size (flavor, &width, &height);
  size = MIN (width, height);

#ifdef HAVE_MMAP
  if (g_file_is_native (file))
    {
      path = g_file_get_path (file);

      /* try to open the file at the given path */
      fd = open (path, O_RDONLY);
      if (G_LIKELY (fd >= 0))
        {
          /* determine the status of the file */
          if (G_LIKELY (fstat (fd, &statb) == 0 && statb.st_size > 0))
            {
              /* try to mmap the file */
              content = (JOCTET *) mmap (NULL, statb.st_size, PROT_READ, 
                                         MAP_SHARED, fd, 0);

              /* verify whether the mmap was successful */
              if (G_LIKELY (content != (JOCTET *) MAP_FAILED))
                {
                  /* try to load the embedded thumbnail first */
                  pixbuf = tvtj_jpeg_load_thumbnail (content, statb.st_size, size);
                  if (pixbuf == NULL)
                    {
                      /* fall back to loading and scaling the image itself */
                      pixbuf = tvtj_jpeg_load (content, statb.st_size, size);

                      if (pixbuf == NULL)
                        {
                          g_set_error (&error, TUMBLER_ERROR, 
                                       TUMBLER_ERROR_INVALID_FORMAT,
                                       _("Thumbnail could not be inferred from file contents"));
                        }
                    }

                  /* we have successfully mmapped the file. we may not have
                   * a thumbnail but trying to read the image from a stream
                   * won't help us here, so we don't need to attempt streaming
                   * as a fallback */
                  streaming_needed = FALSE;
                }

              /* unmap the file content */
              munmap ((void *) content, statb.st_size);
            }

          /* close the file */
          close (fd);
        }

      g_free (path);
    }
#endif

  if (streaming_needed)
    {
      g_file_load_contents (file, cancellable, (gchar **)&content, &length, 
                            NULL, &error);

      if (error == NULL)
        {
          pixbuf = tvtj_jpeg_load_thumbnail (content, length, size);

          if (pixbuf == NULL)
            {
              pixbuf = tvtj_jpeg_load (content, length, size);
              if (pixbuf == NULL)
                {
                  g_set_error (&error, TUMBLER_ERROR, TUMBLER_ERROR_INVALID_FORMAT,
                               _("Thumbnail could not be inferred from file contents"));
                }
            }
        }
    }

  /* either we have an error now or we have a valid thumbnail pixbuf */
  g_assert (error != NULL || pixbuf != NULL);

  if (pixbuf != NULL)
    {
      data.data = gdk_pixbuf_get_pixels (pixbuf);
      data.has_alpha = gdk_pixbuf_get_has_alpha (pixbuf);
      data.bits_per_sample = gdk_pixbuf_get_bits_per_sample (pixbuf);
      data.width = gdk_pixbuf_get_width (pixbuf);
      data.height = gdk_pixbuf_get_height (pixbuf);
      data.rowstride = gdk_pixbuf_get_rowstride (pixbuf);
      data.colorspace = (TumblerColorspace) gdk_pixbuf_get_colorspace (pixbuf);

      tumbler_thumbnail_save_image_data (thumbnail, &data, 
                                         tumbler_file_info_get_mtime (info), 
                                         NULL, &error);

      g_object_unref (pixbuf);
    }

  if (error != NULL)
    {
      g_signal_emit_by_name (thumbnailer, "error", uri, error->code, error->message);
      g_error_free (error);
    }
  else
    {
      g_signal_emit_by_name (thumbnailer, "ready", uri);
    }

  g_object_unref (flavor);
  g_object_unref (thumbnail);
  g_object_unref (file);
}
Example #9
0
static void
xviewer_print_draw_page (GtkPrintOperation *operation,
                         GtkPrintContext   *context,
                         gint               page_nr,
                         gpointer           user_data)
{
    cairo_t *cr;
    gdouble dpi_x, dpi_y;
    gdouble x0, y0;
    gdouble scale_factor;
    gdouble p_width, p_height;
    gint width, height;
    XviewerPrintData *data;
    GtkPageSetup *page_setup;

    xviewer_debug (DEBUG_PRINTING);

    data = (XviewerPrintData *) user_data;

    scale_factor = data->scale_factor/100;

    dpi_x = gtk_print_context_get_dpi_x (context);
    dpi_y = gtk_print_context_get_dpi_y (context);

    switch (data->unit) {
    case GTK_UNIT_INCH:
        x0 = data->left_margin * dpi_x;
        y0 = data->top_margin  * dpi_y;
        break;
    case GTK_UNIT_MM:
        x0 = data->left_margin * dpi_x/25.4;
        y0 = data->top_margin  * dpi_y/25.4;
        break;
    default:
        g_assert_not_reached ();
    }

    cr = gtk_print_context_get_cairo_context (context);

    cairo_translate (cr, x0, y0);

    page_setup = gtk_print_context_get_page_setup (context);
    p_width =  gtk_page_setup_get_page_width (page_setup, GTK_UNIT_POINTS);
    p_height = gtk_page_setup_get_page_height (page_setup, GTK_UNIT_POINTS);

    xviewer_image_get_size (data->image, &width, &height);

    /* this is both a workaround for a bug in cairo's PDF backend, and
       a way to ensure we are not printing outside the page margins */
    cairo_rectangle (cr, 0, 0, MIN (width*scale_factor, p_width), MIN (height*scale_factor, p_height));
    cairo_clip (cr);

    cairo_scale (cr, scale_factor, scale_factor);

#ifdef HAVE_RSVG
    if (xviewer_image_is_svg (data->image))
    {
        RsvgHandle *svg = xviewer_image_get_svg (data->image);

        rsvg_handle_render_cairo (svg, cr);
        return;
    } else
#endif
        /* JPEGs can be attached to the cairo surface which simply embeds the JPEG file into the
         * destination PDF skipping (PNG-)recompression. This should reduce PDF sizes enormously. */
        if (xviewer_image_is_jpeg (data->image) && _cairo_ctx_supports_jpg_metadata (cr))
        {
            GFile *file;
            char *img_data;
            gsize data_len;
            cairo_surface_t *surface = NULL;

            xviewer_debug_message (DEBUG_PRINTING, "Attaching image to cairo surface");

            file = xviewer_image_get_file (data->image);
            if (g_file_load_contents (file, NULL, &img_data, &data_len, NULL, NULL))
            {
                XviewerTransform *tf = xviewer_image_get_transform (data->image);
                XviewerTransform *auto_tf = xviewer_image_get_autorotate_transform (data->image);
                cairo_matrix_t mx, mx2;

                if (!tf && auto_tf) {
                    /* If only autorotation data present,
                     * make it the normal rotation. */
                    tf = auto_tf;
                    auto_tf = NULL;
                }

                /* Care must be taken with height and width values. They are not the original
                 * values but were affected by the transformation. As the surface needs to be
                 * generated using the original dimensions they might need to be flipped. */
                if (tf) {
                    if (auto_tf) {
                        /* If we have an autorotation apply
                         * it before the others */
                        tf = xviewer_transform_compose (auto_tf, tf);
                    }

                    switch (xviewer_transform_get_transform_type (tf)) {
                    case XVIEWER_TRANSFORM_ROT_90:
                        surface = cairo_image_surface_create (
                                      CAIRO_FORMAT_RGB24, height, width);
                        cairo_rotate (cr, 90.0 * (G_PI/180.0));
                        cairo_translate (cr, 0.0, -width);
                        break;
                    case XVIEWER_TRANSFORM_ROT_180:
                        surface = cairo_image_surface_create (
                                      CAIRO_FORMAT_RGB24, width, height);
                        cairo_rotate (cr, 180.0 * (G_PI/180.0));
                        cairo_translate (cr, -width, -height);
                        break;
                    case XVIEWER_TRANSFORM_ROT_270:
                        surface = cairo_image_surface_create (
                                      CAIRO_FORMAT_RGB24, height, width);
                        cairo_rotate (cr, 270.0 * (G_PI/180.0));
                        cairo_translate (cr, -height, 0.0);
                        break;
                    case XVIEWER_TRANSFORM_FLIP_HORIZONTAL:
                        surface = cairo_image_surface_create (
                                      CAIRO_FORMAT_RGB24, width, height);
                        cairo_matrix_init_identity (&mx);
                        _xviewer_cairo_matrix_flip (&mx2, &mx, TRUE, FALSE);
                        cairo_transform (cr, &mx2);
                        cairo_translate (cr, -width, 0.0);
                        break;
                    case XVIEWER_TRANSFORM_FLIP_VERTICAL:
                        surface = cairo_image_surface_create (
                                      CAIRO_FORMAT_RGB24, width, height);
                        cairo_matrix_init_identity (&mx);
                        _xviewer_cairo_matrix_flip (&mx2, &mx, FALSE, TRUE);
                        cairo_transform (cr, &mx2);
                        cairo_translate (cr, 0.0, -height);
                        break;
                    case XVIEWER_TRANSFORM_TRANSPOSE:
                        surface = cairo_image_surface_create (
                                      CAIRO_FORMAT_RGB24, height, width);
                        cairo_matrix_init_rotate (&mx, 90.0 * (G_PI/180.0));
                        cairo_matrix_init_identity (&mx2);
                        _xviewer_cairo_matrix_flip (&mx2, &mx2, TRUE, FALSE);
                        cairo_matrix_multiply (&mx2, &mx, &mx2);
                        cairo_transform (cr, &mx2);
                        break;
                    case XVIEWER_TRANSFORM_TRANSVERSE:
                        surface = cairo_image_surface_create (
                                      CAIRO_FORMAT_RGB24, height, width);
                        cairo_matrix_init_rotate (&mx, 90.0 * (G_PI/180.0));
                        cairo_matrix_init_identity (&mx2);
                        _xviewer_cairo_matrix_flip (&mx2, &mx2, FALSE, TRUE);
                        cairo_matrix_multiply (&mx2, &mx, &mx2);
                        cairo_transform (cr, &mx2);
                        cairo_translate (cr, -height , -width);
                        break;
                    case XVIEWER_TRANSFORM_NONE:
                    default:
                        surface = cairo_image_surface_create (
                                      CAIRO_FORMAT_RGB24, width, height);
                        break;
                    }
                }

                if (!surface)
                    surface = cairo_image_surface_create (CAIRO_FORMAT_RGB24,
                                                          width, height);
                cairo_surface_set_mime_data (surface,
                                             CAIRO_MIME_TYPE_JPEG,
                                             (unsigned char*)img_data, data_len,
                                             g_free, img_data);
                cairo_set_source_surface (cr, surface, 0, 0);
                cairo_paint (cr);
                cairo_surface_destroy (surface);
                g_object_unref (file);
                return;
            }
            g_object_unref (file);

        }

    {
        GdkPixbuf *pixbuf;

        pixbuf = xviewer_image_get_pixbuf (data->image);
        gdk_cairo_set_source_pixbuf (cr, pixbuf, 0, 0);
        cairo_paint (cr);
        g_object_unref (pixbuf);
    }
}
Example #10
0
/* initialise the gtodo lib */
gboolean gtodo_client_check_file(GTodoClient *cl, GError **error)
{
	GError *tmp_error = NULL;
	GFile *base_path = NULL;
	GFileInfo *file_info = NULL;
	GError *file_error = NULL;

	/* check if the error is good or wrong. */
	g_return_val_if_fail(error == NULL || *error == NULL,FALSE);

	base_path = g_file_get_parent (cl->xml_file);

	/* this is dirty.. needs a fix hard *
	 * The client should do this.. so this code should be considert
	 * deprecated. I left it here thinking it wouldnt hurt anybody.
	 */
	
	if(base_path != NULL)
	{
		g_file_make_directory (base_path, NULL, NULL);
		g_object_unref (G_OBJECT(base_path));
	}

	/* Get permission of the file */
	/* This also tell's us if it does exists */
	file_info = g_file_query_info (cl->xml_file, 
			"access::can-read,access::can-write",
			G_FILE_QUERY_INFO_NONE,
			NULL, &file_error);

	/* If I got the info to check it out */
	if(file_error == NULL)
	{
		gchar *read_buf = NULL;
		gboolean read;
		gboolean write;
		gsize size;

		read = g_file_info_get_attribute_boolean (file_info, "access::can-read");
		write = g_file_info_get_attribute_boolean (file_info, "access::can-write");

		/* If I am not allowed to read the file */
		if(!read)
		{
			/* save some more info here.. check for some logicol errors and print it. */
			g_set_error(&tmp_error,LIBGTODO_ERROR,LIBGTODO_ERROR_NO_PERMISSION,
					_("No permission to read the file."));		
			g_propagate_error(error, tmp_error);                                                         
			return FALSE;
		}
		cl->read_only = !write;
		DEBUG_PRINT("trying to read file: %s", g_file_get_parse_name (cl->xml_file));

		if (!g_file_load_contents (cl->xml_file, NULL, (char **)&read_buf, &size, NULL, &file_error))
		{
			if (file_error)
			{
				g_propagate_error(error, file_error);
			}
			else
			{
				g_set_error(&tmp_error, LIBGTODO_ERROR, LIBGTODO_ERROR_FAILED, _("Failed to read file"));
				g_propagate_error(error, tmp_error);
			}
			return FALSE;
		}
		cl->gtodo_doc = xmlParseMemory(read_buf, size);
		if(cl->gtodo_doc == NULL)
		{
			g_set_error(&tmp_error,LIBGTODO_ERROR,LIBGTODO_ERROR_XML,_("Failed to parse XML structure"));
			g_propagate_error(error, tmp_error);
			DEBUG_PRINT("%s", "failed to read the file");
			g_free (read_buf);
			return FALSE;
		}

		/* get root element.. this "root" is used in the while program */    
		cl->root = xmlDocGetRootElement(cl->gtodo_doc);
		if(cl->root == NULL)
		{
			g_set_error(&tmp_error,LIBGTODO_ERROR,LIBGTODO_ERROR_XML,_("Failed to parse XML structure"));
			g_propagate_error(error, tmp_error);
			DEBUG_PRINT("%s", "failed to get root node.");
			g_free (read_buf);
			return FALSE;
		}
		/* check if the name of the root file is ok.. just to make sure :) */
		if(!xmlStrEqual(cl->root->name, (const xmlChar *)"gtodo"))
		{
			g_set_error(&tmp_error,LIBGTODO_ERROR,LIBGTODO_ERROR_XML,_("File is not a valid gtodo file"));
			g_propagate_error(error, tmp_error);
			g_free (read_buf);
			return FALSE;
		}

		g_free (read_buf);
	}
	else if ((file_error->domain == G_IO_ERROR) && (file_error->code == G_IO_ERROR_NOT_FOUND))
	{
		xmlNodePtr newn;
		DEBUG_PRINT ("Trying to create new file\n");
		cl->gtodo_doc = xmlNewDoc((xmlChar *)"1.0");
		cl->root = xmlNewDocNode(cl->gtodo_doc, NULL, (xmlChar *)"gtodo", NULL);	 
		xmlDocSetRootElement(cl->gtodo_doc, cl->root);
		newn = xmlNewTextChild(cl->root, NULL, (xmlChar *)"category", NULL);	
		xmlNewProp(newn, (xmlChar *)"title", (xmlChar *)_("Personal"));
		newn = xmlNewTextChild(cl->root, NULL, (xmlChar *)"category", NULL);	
		xmlNewProp(newn, (xmlChar *)"title", (xmlChar *)_("Business"));
		newn = xmlNewTextChild(cl->root, NULL, (xmlChar *)"category", NULL);	
		xmlNewProp(newn, (xmlChar *)"title", (xmlChar *)_("Unfiled"));
		if(gtodo_client_save_xml(cl, &tmp_error))
		{
			g_propagate_error(error, tmp_error);
			return FALSE;
		}
		cl->read_only = FALSE;
		g_error_free (file_error);
	}
	else{
		/* save some more info here.. check for some logicol errors and print it. */
		g_propagate_error(error, file_error);
		return FALSE;
	}
	return TRUE;
}
Example #11
0
static gpointer files_replace_run(gpointer data) {
	Treplaceinthread *rit = data;
	GError *gerror=NULL;
	gchar *inbuf=NULL, *encoding=NULL, *outbuf, *utf8buf;
	gsize inbuflen=0, outbuflen=0;
	Tasyncqueue *tmpqueue;

	if (!data) {
		g_warning("problem detected in files_replace_run, data is NULL, please report a bug\n");
		return NULL;
	}

	DEBUG_MSG("thread %p: files_replace_run, started rit %p\n", g_thread_self(), rit);

	g_file_load_contents(rit->uri,NULL,&inbuf,&inbuflen,NULL,&gerror);
	if (g_atomic_int_get(&rit->s3run->cancelled)!=0) {
		g_free(inbuf);
		return NULL;
	}
	if (gerror) {
		g_print("failed to load file: %s\n",gerror->message);
		g_error_free(gerror);
		tmpqueue = &rit->s3run->threadqueue;
		g_idle_add(replace_files_in_thread_finished, rit);
		queue_worker_ready_inthread(tmpqueue);
		return NULL;
	} else {
		DEBUG_MSG("thread %p: calling buffer_find_encoding for %ld bytes\n", g_thread_self(),(glong)strlen(inbuf));
		/* is the following function thread safe ?? */
		utf8buf = buffer_find_encoding(inbuf, inbuflen, &encoding, rit->s3run->bfwin->session->encoding);
		g_free(inbuf);

		if (utf8buf) {
			gchar *replacedbuf=NULL;
			DEBUG_MSG("starting threaded search/replace\n");
			switch (rit->s3run->type) {
				case snr3type_string:
					if (rit->s3run->replaceall) {
						rit->results = snr3_replace_string(rit->s3run, utf8buf, &replacedbuf);
					} else {
						rit->results = snr3_find_string(rit->s3run, utf8buf);
					}
				break;
				case snr3type_pcre:
				if (rit->s3run->replaceall) {
						rit->results = snr3_replace_pcre(rit->s3run, utf8buf, &replacedbuf);
					} else {
						rit->results = snr3_find_pcre(rit->s3run, utf8buf);
					}
				break;
			}
			DEBUG_MSG("finished threaded search/replace\n");
			g_free(utf8buf);
			if ((g_atomic_int_get(&rit->s3run->cancelled)==0) && rit->results && replacedbuf) {
				DEBUG_MSG("replaced %d entries\n",g_list_length(rit->results));
				outbuf = g_convert(replacedbuf, -1, encoding, "UTF-8", NULL, &outbuflen, NULL);

				g_file_replace_contents(rit->uri,outbuf,outbuflen,NULL,TRUE,G_FILE_CREATE_NONE,NULL,NULL,&gerror);
				if (gerror) {
					g_print("failed to save file: %s\n",gerror->message);
					g_error_free(gerror);
				}
				g_free(outbuf);
			}
			g_free(replacedbuf);

		}
	}
	rit->results = g_list_reverse(rit->results);
	tmpqueue = &rit->s3run->threadqueue;
	if (g_atomic_int_get(&rit->s3run->cancelled)==0) {
		g_idle_add(replace_files_in_thread_finished, rit);
	}

	DEBUG_MSG("thread %p: calling queue_worker_ready_inthread\n",g_thread_self());
	queue_worker_ready_inthread(tmpqueue);
	/* we don't need to start a new thread by calling _inthread() inside the thread */
	return NULL;
}
Example #12
0
static gboolean
callback_button_box_click (GtkWidget * widget, GdkEvent * event,
    gpointer user_data)
{
  GList *list, *header_list;
  GList *hlist = NULL, *slist = NULL;
  GtkWidget *notebook = NULL;
  GtkWidget *textview = NULL;
  GFile *hexfile;
  GtkWidget *sc_window, *tree_view;
  gboolean is_header, is_slice, is_hexval;

  CodecComponents component = (CodecComponents) user_data;

  char *xml_name = ui->current_xml;
  char *hex_name = ui->current_hex;

  switch (component) {
    case COMPONENTS_HEADERS_GENERAL:
      is_header = TRUE;
      is_slice = FALSE;
      is_hexval = FALSE;
      break;
    case COMPONENTS_HEADERS_SLICE:
      is_slice = TRUE;
      is_header = FALSE;
      is_hexval = FALSE;
      break;
    case COMPONENTS_HEXVAL:
      is_hexval = TRUE;
      is_header = FALSE;
      is_slice = FALSE;
      break;
    default:
      break;
  }

  if (ui->prev_page)
    gtk_widget_destroy (GTK_WIDGET (ui->prev_page));
  if (ui->notebook_hash)
    g_hash_table_destroy (ui->notebook_hash);
  ui->notebook_hash = g_hash_table_new (g_str_hash, g_str_equal);

  if (!is_hexval) {
    header_list = analyzer_get_list_header_strings (xml_name);

    while (header_list) {
      if (strcmp (header_list->data, "comment")) {
        if (is_header && !g_str_has_prefix (header_list->data, "slice"))
          hlist = g_list_append (hlist, header_list->data);
        else if (is_slice && g_str_has_prefix (header_list->data, "slice"))
          hlist = g_list_append (hlist, header_list->data);
      }
      header_list = header_list->next;
    }

    notebook = gtk_notebook_new ();
    g_object_set (G_OBJECT (notebook), "expand", TRUE, NULL);
    gtk_notebook_set_scrollable (GTK_NOTEBOOK (notebook), TRUE);
    gtk_notebook_popup_enable (GTK_NOTEBOOK (notebook));
    gtk_notebook_set_show_border (GTK_NOTEBOOK (notebook), TRUE);

    g_list_foreach (hlist, (GFunc) populate_notebook, (gpointer) notebook);

    while (hlist) {
      sc_window = g_hash_table_lookup (ui->notebook_hash, hlist->data);
      if (sc_window && GTK_IS_BIN (sc_window))
        tree_view = gtk_bin_get_child (GTK_BIN (sc_window));

      if (tree_view) {
        list = analyzer_get_list_analyzer_node_from_xml (xml_name, hlist->data);
        if (list) {
          GtkTreeStore *treestore;
          GtkTreeModel *model;

          treestore = gtk_tree_store_new (NUM_COLS,
              G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING);

          g_list_foreach (list, (GFunc) fill_tree_store, treestore);
          analyzer_node_list_free (list);
          list = NULL;

          model = GTK_TREE_MODEL (treestore);
          gtk_tree_view_set_model (GTK_TREE_VIEW (tree_view), model);
          g_object_unref (model);
        }
      }
      hlist = hlist->next;
    }
    ui->prev_page = notebook;
    gtk_container_add (GTK_CONTAINER (ui->parsed_info_vbox), notebook);
  } else {
    /*Display the hex dump of the frame */
    GtkWidget *scrolled_window;
    GtkTextBuffer *buffer;
    gchar *contents;
    gsize length;

    textview = gtk_text_view_new ();
    gtk_text_view_set_left_margin (GTK_TEXT_VIEW (textview), 20);
    g_object_set (G_OBJECT (textview), "expand", TRUE, "editable", FALSE, NULL);

    scrolled_window = gtk_scrolled_window_new (NULL, NULL);
    gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window),
        GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);
    gtk_container_add (GTK_CONTAINER (scrolled_window), textview);

    hexfile = g_file_new_for_path (hex_name);
    if (hexfile) {
      if (g_file_load_contents (hexfile, NULL, &contents, &length, NULL, NULL)) {
        buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (textview));
        gtk_text_buffer_set_text (buffer, contents, length);
        g_free (contents);
        g_object_unref (G_OBJECT (hexfile));
      }
    }
    ui->prev_page = scrolled_window;
    gtk_container_add (GTK_CONTAINER (ui->parsed_info_vbox), scrolled_window);
  }

  gtk_widget_show_all (ui->main_window);

  return TRUE;
}
Example #13
0
static GSList *
parole_pl_parser_parse_xspf (const gchar *filename)
{
    ParoleParserData data;
    GFile *file;
    gchar *contents;
    GError *error = NULL;
    gsize size;
    GMarkupParseContext *pctx;
    GMarkupParser parser = {
        parole_xspf_xml_start,
        parole_xspf_xml_end,
        parole_xspf_xml_text,
        NULL,
        NULL
    };
    
    data.list = NULL;
    data.title = data.uri = NULL;
    
    file = g_file_new_for_path (filename);
    
    if ( !g_file_load_contents (file, NULL, &contents, &size, NULL, NULL) )
	goto out;
    
    if ( g_utf8_validate (contents, -1, NULL) == FALSE) 
    {
	gchar *fixed;
	fixed = g_convert (contents, -1, "UTF-8", "ISO8859-1", NULL, NULL, NULL);
	if (fixed != NULL) 
	{
	    g_free (contents);
	    contents = fixed;
	}
    }
    
    pctx = g_markup_parse_context_new (&parser, 0, &data, NULL);
    
    if ( !g_markup_parse_context_parse (pctx, contents, size, &error) )
    {
	if ( error )
	{
	    g_critical ("Unable to parse xspf file : %s : %s\n", filename, error->message);
	    g_error_free (error);
	}
    }
    else
    {
	if ( !g_markup_parse_context_end_parse (pctx, &error) )
	{
            g_critical ("Unable to finish parsing xspf playlist file %s", error->message);
            g_error_free (error);
        }
    }
    
    g_markup_parse_context_free (pctx);
    
out:
    g_object_unref (file);
    return data.list;
}
Example #14
0
VinagreConnection *
vinagre_connection_new_from_file (const gchar *uri, gchar **error_msg, gboolean use_bookmarks)
{
  GKeyFile          *file;
  GError            *error;
  gboolean           loaded;
  VinagreConnection *conn;
  gchar             *host, *actual_host, *data;
  gint               port;
  int                file_size;
  GFile             *file_a;

  *error_msg = NULL;
  host = NULL;
  data = NULL;
  conn = NULL;
  error = NULL;
  file = NULL;
  conn = NULL;

  file_a = g_file_new_for_commandline_arg (uri);
  loaded = g_file_load_contents (file_a,
				 NULL,
				 &data,
				 &file_size,
				 NULL,
				 &error);
  if (!loaded)
    {
      if (error)
	{
	  *error_msg = g_strdup (error->message);
	  g_error_free (error);
	}
      else
	*error_msg = g_strdup (_("Could not open the file."));

      goto the_end;
    }

  file = g_key_file_new ();
  loaded = g_key_file_load_from_data (file,
				      data,
				      file_size,
				      0,
				      &error);
  if (!loaded)
    {
      if (error)
	{
	  *error_msg = g_strdup (error->message);
	  g_error_free (error);
	}
      else
	*error_msg = g_strdup (_("Could not parse the file."));

      goto the_end;
    }

  host = g_key_file_get_string (file, "connection", "host", NULL);
  port = g_key_file_get_integer (file, "connection", "port", NULL);
  if (host)
    {
      if (!port)
	{
	  if (!vinagre_connection_split_string (host, &actual_host, &port, error_msg))
	    goto the_end;

	  g_free (host);
	  host = actual_host;
	}

      if (use_bookmarks)
        conn = vinagre_bookmarks_exists (vinagre_bookmarks_get_default (), host, port);
      if (!conn)
	{
	  gchar *username, *password;
	  gint shared;
	  GError *e = NULL;

	  conn = vinagre_connection_new ();
	  vinagre_connection_set_host (conn, host);
	  vinagre_connection_set_port (conn, port);

	  username = g_key_file_get_string  (file, "connection", "username", NULL);
	  vinagre_connection_set_username (conn, username);
	  g_free (username);

	  password = g_key_file_get_string  (file, "connection", "password", NULL);
	  vinagre_connection_set_password (conn, password);
	  g_free (password);

	  shared = g_key_file_get_integer (file, "options", "shared", &e);
	  if (e)
	    g_error_free (e);
	  else
	    if (shared == 0 || shared == 1)
	      vinagre_connection_set_shared (conn, shared);
	    else
	      g_message (_("Bad value for 'shared' flag: %d. It is supposed to be 0 or 1. Ignoring it."), shared);
	}

      g_free (host);
    }
  else
    *error_msg = g_strdup (_("Could not find the host address in the file."));

the_end:
  g_free (data);
  g_object_unref (file_a);
  if (file)
    g_key_file_free (file);

  return conn;
}
Example #15
0
/* Display any errors from the NI compiler and continue on. This function is
 called from a child process watch, so the GDK lock is not held and must be
 acquired for any GUI calls. */
static void
finish_ni_compiler(GPid pid, gint status, CompilerData *data)
{
    I7_STORY_USE_PRIVATE(data->story, priv);
    I7App *theapp = i7_app_get();
    GSettings *prefs = i7_app_get_prefs(theapp);

    /* Clear the progress indicator */
    gdk_threads_enter();
    i7_document_remove_status_message(I7_DOCUMENT(data->story), COMPILE_OPERATIONS);
    i7_document_clear_progress(I7_DOCUMENT(data->story));
    gdk_threads_leave();

    /* Get the ni.exe exit code */
    int exit_code = WIFEXITED(status)? WEXITSTATUS(status) : -1;

    /* Display the appropriate HTML error or success page */
    GFile *problems_file = NULL;
    if(exit_code <= 1) {
        /* In the case of success or a "normal" failure, or a negative error
         code should one occur, display the compiler's generated Problems.html*/
        problems_file = g_file_get_child(data->builddir_file, "Problems.html");
    } else {
        gchar *file = g_strdup_printf("Error%i.html", exit_code);
        problems_file = i7_app_check_data_file_va(theapp, "Resources", "en", file, NULL);
        g_free(file);
        if(!problems_file)
            problems_file = i7_app_get_data_file_va(theapp, "Resources", "en", "Error0.html", NULL);
    }

    g_clear_object(&data->results_file);
    data->results_file = problems_file; /* assumes reference */

    if(g_settings_get_boolean(prefs, PREFS_SHOW_DEBUG_LOG)) {
        /* Update */
        gdk_threads_enter();
        while(gtk_events_pending())
            gtk_main_iteration();
        gdk_threads_leave();

        /* Refresh the debug log */
        gchar *text;
        GFile *debug_file = g_file_get_child(data->builddir_file, "Debug log.txt");
        /* Ignore errors, just don't show it if it's not there */
        if(g_file_load_contents(debug_file, NULL, &text, NULL, NULL, NULL)) {
            gdk_threads_enter();
            gtk_text_buffer_set_text(priv->debug_log, text, -1);
            gdk_threads_leave();
            g_free(text);
        }
        g_object_unref(debug_file);

        /* Refresh the I6 code */
        GFile *i6_file = g_file_get_child(data->builddir_file, "auto.inf");
        if(g_file_load_contents(i6_file, NULL, &text, NULL, NULL, NULL)) {
            gdk_threads_enter();
            gtk_text_buffer_set_text(GTK_TEXT_BUFFER(priv->i6_source), text, -1);
            gdk_threads_leave();
            g_free(text);
        }
        g_object_unref(i6_file);
    }

    /* Stop here and show the Results/Report tab if there was an error */
    if(exit_code != 0) {
        finish_compiling(FALSE, data);
        return;
    }

    /* Reload the Index in the background */
    i7_story_reload_index_tabs(data->story, FALSE);

    /* Read in the Blorb manifest */
    GFile *file = i7_document_get_file(I7_DOCUMENT(data->story));
    GFile *manifest_file = g_file_get_child(file, "manifest.plist");
    g_object_unref(file);
    PlistObject *manifest = plist_read_file(manifest_file, NULL, NULL);
    g_object_unref(manifest_file);
    /* If that failed, then silently keep the old manifest */
    if(manifest) {
        plist_object_free(priv->manifest);
        priv->manifest = manifest;
    }

    /* Decide what to do next */
    if(data->refresh_only) {
        I7Story *story = data->story;
        finish_compiling(TRUE, data);
        /* Hold the GDK lock for the callback */
        gdk_threads_enter();
        (priv->compile_finished_callback)(story, priv->compile_finished_callback_data);
        gdk_threads_leave();
        return;
    }

    prepare_i6_compiler(data);
    start_i6_compiler(data);
}
static IdolPlParserResult
idol_pl_parser_add_quicktime_metalink (IdolPlParser *parser,
					GFile *file,
					GFile *base_file,
					IdolPlParseData *parse_data,
					gpointer data)
{
	xml_node_t *doc, *node;
	gsize size;
	char *contents;
	const char *item_uri, *autoplay;
	gboolean found;

	if (g_str_has_prefix (data, "RTSPtext") != FALSE
			|| g_str_has_prefix (data, "rtsptext") != FALSE) {
		return idol_pl_parser_add_quicktime_rtsptext (parser, file, base_file, parse_data, data);
	}
	if (g_str_has_prefix (data, "SMILtext") != FALSE) {
		char *contents;
		gsize size;
		IdolPlParserResult retval;

		if (g_file_load_contents (file, NULL, &contents, &size, NULL, NULL) == FALSE)
			return IDOL_PL_PARSER_RESULT_ERROR;

		retval = idol_pl_parser_add_smil_with_data (parser,
							     file, base_file,
							     contents + strlen ("SMILtext"),
							     size - strlen ("SMILtext"));
		g_free (contents);
		return retval;
	}

	if (g_file_load_contents (file, NULL, &contents, &size, NULL, NULL) == FALSE)
		return IDOL_PL_PARSER_RESULT_ERROR;

	doc = idol_pl_parser_parse_xml_relaxed (contents, size);
	if (doc == NULL) {
		g_free (contents);
		return IDOL_PL_PARSER_RESULT_ERROR;
	}
	g_free (contents);

	/* Check for quicktime type */
	for (node = doc, found = FALSE; node != NULL; node = node->next) {
		const char *type;

		if (node->name == NULL)
			continue;
		if (g_ascii_strcasecmp (node->name , "?quicktime") != 0)
			continue;
		type = xml_parser_get_property (node, "type");
		if (g_ascii_strcasecmp ("application/x-quicktime-media-link", type) != 0)
			continue;
		found = TRUE;
	}

	if (found == FALSE) {
		xml_parser_free_tree (doc);
		return IDOL_PL_PARSER_RESULT_ERROR;
	}

	if (!doc || !doc->name
	    || g_ascii_strcasecmp (doc->name, "embed") != 0) {
		xml_parser_free_tree (doc);
		return IDOL_PL_PARSER_RESULT_ERROR;
	}

	item_uri = xml_parser_get_property (doc, "src");
	if (!item_uri) {
		xml_parser_free_tree (doc);
		return IDOL_PL_PARSER_RESULT_ERROR;
	}

	autoplay = xml_parser_get_property (doc, "autoplay");
	/* Add a default as per the QuickTime docs */
	if (autoplay == NULL)
		autoplay = "true";

	idol_pl_parser_add_uri (parser,
				 IDOL_PL_PARSER_FIELD_URI, item_uri,
				 IDOL_PL_PARSER_FIELD_AUTOPLAY, autoplay,
				 NULL);
	xml_parser_free_tree (doc);

	return IDOL_PL_PARSER_RESULT_SUCCESS;
}
IdolPlParserResult
idol_pl_parser_add_m3u (IdolPlParser *parser,
			 GFile *file,
			 GFile *base_file,
			 IdolPlParseData *parse_data,
			 gpointer data)
{
	IdolPlParserResult retval = IDOL_PL_PARSER_RESULT_UNHANDLED;
	char *contents, **lines;
	gsize size;
	guint i, num_lines;
	gboolean dos_mode = FALSE;
	const char *extinfo;

	if (g_file_load_contents (file, NULL, &contents, &size, NULL, NULL) == FALSE)
		return IDOL_PL_PARSER_RESULT_ERROR;

	/* .pls files with a .m3u extension, the nasties */
	if (g_str_has_prefix (contents, "[playlist]") != FALSE
			|| g_str_has_prefix (contents, "[Playlist]") != FALSE
			|| g_str_has_prefix (contents, "[PLAYLIST]") != FALSE) {
		retval = idol_pl_parser_add_pls_with_contents (parser, file, base_file, contents, parse_data);
		g_free (contents);
		return retval;
	}

	/* Try to use ISO-8859-1 if we don't have valid UTF-8,
	 * try to parse anyway if it's not ISO-8859-1 */
	if (g_utf8_validate (contents, -1, NULL) == FALSE) {
		char *fixed;
		fixed = g_convert (contents, -1, "UTF-8", "ISO8859-1", NULL, NULL, NULL);
		if (fixed != NULL) {
			g_free (contents);
			contents = fixed;
		}
	}

	/* is non-NULL if there's an EXTINF on a preceding line */
	extinfo = NULL;

	/* figure out whether we're a unix m3u or dos m3u */
	if (strstr(contents, "\x0d")) {
		dos_mode = TRUE;
	}

	lines = g_strsplit_set (contents, "\r\n", 0);
	g_free (contents);
	num_lines = g_strv_length (lines);
	/* We don't count the terminating NULL */
	num_lines--;

	for (i = 0; lines[i] != NULL; i++) {
		const char *line;

		line = lines[i];

		if (line[0] == '\0')
			continue;

		retval = IDOL_PL_PARSER_RESULT_SUCCESS;

		/* Ignore leading spaces */
		for (; g_ascii_isspace (line[0]); line++)
			;

		/* Ignore comments, but mark it if we have extra info */
		if (line[0] == '#') {
			if (extinfo == NULL && g_str_has_prefix (line, EXTINF) != FALSE)
				extinfo = line;
			continue;
		}

		/* Either it's a URI, or it has a proper path ... */
		if (strstr(line, "://") != NULL
				|| line[0] == G_DIR_SEPARATOR) {
			GFile *uri;

			uri = g_file_new_for_commandline_arg (line);
			if (idol_pl_parser_parse_internal (parser, uri, NULL, parse_data) != IDOL_PL_PARSER_RESULT_SUCCESS) {
				idol_pl_parser_add_one_uri (parser, line,
						idol_pl_parser_get_extinfo_title (extinfo));
			}
			g_object_unref (uri);
			extinfo = NULL;
		} else if (g_ascii_isalpha (line[0]) != FALSE
			   && g_str_has_prefix (line + 1, ":\\")) {
			/* Path relative to a drive on Windows, we need to use
			 * the base that was passed to us */
			GFile *uri;

			lines[i] = g_strdelimit (lines[i], "\\", '/');
			/* + 2, skip drive letter */
			uri = g_file_get_child (base_file, line + 2);
			idol_pl_parser_add_one_file (parser, uri,
						     idol_pl_parser_get_extinfo_title (extinfo));
			g_object_unref (uri);
			extinfo = NULL;
		} else if (line[0] == '\\' && line[1] == '\\') {
			/* ... Or it's in the windows smb form
			 * (\\machine\share\filename), Note drive names
			 * (C:\ D:\ etc) are unhandled (unknown base for
			 * drive letters) */
		        char *tmpuri;

			lines[i] = g_strdelimit (lines[i], "\\", '/');
			tmpuri = g_strjoin (NULL, "smb:", line, NULL);

			idol_pl_parser_add_one_uri (parser, line,
					idol_pl_parser_get_extinfo_title (extinfo));
			extinfo = NULL;

			g_free (tmpuri);
		} else {
			/* Try with a base */
			GFile *uri, *_base_file;
			char sep;

			_base_file = g_file_get_parent (file);
			sep = (dos_mode ? '\\' : '/');
			if (sep == '\\')
				lines[i] = g_strdelimit (lines[i], "\\", '/');
			uri = g_file_get_child (_base_file, line);
			g_object_unref (_base_file);
			idol_pl_parser_add_one_file (parser, uri,
						     idol_pl_parser_get_extinfo_title (extinfo));
			g_object_unref (uri);
			extinfo = NULL;
		}
	}

	g_strfreev (lines);

	return retval;
}
static gboolean
install_from (FlatpakDir *dir,
              GOptionContext *context,
              int argc, char **argv,
              GCancellable *cancellable,
              GError **error)
{
  g_autoptr(GFile) file = NULL;
  g_autoptr(GBytes) file_data = NULL;
  g_autofree char *data = NULL;
  gsize data_len;
  const char *filename;
  g_autoptr(FlatpakTransaction) transaction = NULL;

  if (argc < 2)
    return usage_error (context, _("Filename or uri must be specified"), error);

  if (argc > 2)
    return usage_error (context, _("Too many arguments"), error);


  filename = argv[1];

  if (g_str_has_prefix (filename, "http:") ||
      g_str_has_prefix (filename, "https:"))
    {
      file_data = download_uri (filename, error);
      if (file_data == NULL)
        {
          g_prefix_error (error, "Can't load uri %s: ", filename);
          return FALSE;
        }
    }
  else
    {
      file = g_file_new_for_commandline_arg (filename);

      if (!g_file_load_contents (file, cancellable, &data, &data_len, NULL, error))
        return FALSE;

      file_data = g_bytes_new_take (g_steal_pointer (&data), data_len);
    }

  if (opt_noninteractive)
    transaction = flatpak_quiet_transaction_new (dir, error);
  else
    transaction = flatpak_cli_transaction_new (dir, opt_yes, TRUE, error);
  if (transaction == NULL)
    return FALSE;

  flatpak_transaction_set_no_pull (transaction, opt_no_pull);
  flatpak_transaction_set_no_deploy (transaction, opt_no_deploy);
  flatpak_transaction_set_disable_static_deltas (transaction, opt_no_static_deltas);
  flatpak_transaction_set_disable_dependencies (transaction, opt_no_deps);
  flatpak_transaction_set_disable_related (transaction, opt_no_related);
  flatpak_transaction_set_reinstall (transaction, opt_reinstall);
  flatpak_transaction_set_default_arch (transaction, opt_arch);

  if (!flatpak_transaction_add_install_flatpakref (transaction, file_data, error))
    return FALSE;

  if (!flatpak_transaction_run (transaction, cancellable, error))
    {
      if (g_error_matches (*error, FLATPAK_ERROR, FLATPAK_ERROR_ABORTED))
        {
          g_clear_error (error);
          return TRUE;
        }

      return FALSE;
    }

  return TRUE;
}
/**
 * seahorse_service_crypto_decrypt_file:
 * @crypto: the crypto service (#SeahorseServiceCrypto)
 * @recipients: A list of recipients (keyids "openpgp:B8098FB063E2C811")
 * @signer: optional, if the text was signed, the signer's keyid will be returned
 * @flags: FLAG_QUIET for no notification
 * @crypturi: the data of an inout file. This will be encrypted
 * @clearuri: the uri of the output file. Will be overwritten
 * @error: an error (out)
 *
 * DBus: DecryptFile
 *
 * This function decrypts a file and stores the results in another file (@crypturi)
 *
 * Returns: TRUE on success
 */
gboolean
seahorse_service_crypto_decrypt_file (SeahorseServiceCrypto *crypto,
                                      const char *ktype, int flags,
                                      const char * crypturi, const char *clearuri,
                                      char **signer, GError **error)
{
    char         *lcleartext = NULL;
    char         *in_data = NULL;
    gsize        in_length;
    gboolean     res = FALSE;
    GFile        *in = NULL;
    GFile        *out = NULL;
    gsize        clearlength;


    if ((clearuri == NULL) || (clearuri[0] == 0))
    {
        g_set_error (error, SEAHORSE_DBUS_ERROR, SEAHORSE_DBUS_ERROR_INVALID, _("Please set clearuri"));
        return FALSE;
    }

    if ((crypturi == NULL) || (crypturi[0] == 0))
    {
        g_set_error (error, SEAHORSE_DBUS_ERROR, SEAHORSE_DBUS_ERROR_INVALID, _("Please set crypturi"));
        return FALSE;
    }
    
    in = g_file_new_for_uri(crypturi);
    g_file_load_contents(in,NULL, &in_data, &in_length, NULL, error);
    if (*error != NULL){
        g_object_unref (in);
        return FALSE;
    }
    else{
        res = crypto_decrypt_generic (crypto,
                                      ktype,flags,
                                      in_data, in_length,
                                      &lcleartext, &clearlength,
                                      signer, TRUE,
                                      TRUE, error);
        if (*error != NULL){
            g_object_unref (in);
            g_free (in_data);
            return FALSE;
        }
        out = g_file_new_for_uri (clearuri);
        g_file_replace_contents (out,
            lcleartext,
            clearlength,
            NULL,
            FALSE,
            G_FILE_CREATE_PRIVATE|G_FILE_CREATE_REPLACE_DESTINATION,
            NULL,
            NULL,
            error);
        if (*error != NULL){
            g_object_unref (in);
            g_free (in_data);
            g_free (lcleartext);
            return FALSE;
        }

        g_free (lcleartext);
        g_free (in_data);
        g_object_unref (in);
    }
    return res;
}
gboolean
ot_admin_builtin_deploy (int argc, char **argv, OstreeSysroot *sysroot, GCancellable *cancellable, GError **error)
{
  gboolean ret = FALSE;
  const char *refspec;
  GOptionContext *context;
  GKeyFile *origin = NULL;
  gs_unref_object OstreeRepo *repo = NULL;
  gs_unref_ptrarray GPtrArray *new_deployments = NULL;
  gs_unref_object OstreeDeployment *new_deployment = NULL;
  gs_unref_object OstreeDeployment *merge_deployment = NULL;
  gs_free char *revision = NULL;
  __attribute__((cleanup(_ostree_kernel_args_cleanup))) OstreeKernelArgs *kargs = NULL;

  context = g_option_context_new ("REFSPEC - Checkout revision REFSPEC as the new default deployment");

  g_option_context_add_main_entries (context, options, NULL);

  if (!g_option_context_parse (context, &argc, &argv, error))
    goto out;

  if (argc < 2)
    {
      ot_util_usage_error (context, "REF/REV must be specified", error);
      goto out;
    }

  refspec = argv[1];

  if (!ostree_sysroot_load (sysroot, cancellable, error))
    goto out;

  if (!ostree_sysroot_get_repo (sysroot, &repo, cancellable, error))
    goto out;

  /* Find the currently booted deployment, if any; we will ensure it
   * is present in the new deployment list.
   */
  if (!ot_admin_require_booted_deployment_or_osname (sysroot, opt_osname,
                                                     cancellable, error))
    {
      g_prefix_error (error, "Looking for booted deployment: ");
      goto out;
    }

  if (opt_origin_path)
    {
      origin = g_key_file_new ();
      
      if (!g_key_file_load_from_file (origin, opt_origin_path, 0, error))
        goto out;
    }
  else
    {
      origin = ostree_sysroot_origin_new_from_refspec (sysroot, refspec);
    }

  if (!ostree_repo_resolve_rev (repo, refspec, FALSE, &revision, error))
    goto out;

  merge_deployment = ostree_sysroot_get_merge_deployment (sysroot, opt_osname);

  /* Here we perform cleanup of any leftover data from previous
   * partial failures.  This avoids having to call gs_shutil_rm_rf()
   * at random points throughout the process.
   *
   * TODO: Add /ostree/transaction file, and only do this cleanup if
   * we find it.
   */
  if (!ostree_sysroot_cleanup (sysroot, cancellable, error))
    {
      g_prefix_error (error, "Performing initial cleanup: ");
      goto out;
    }

  kargs = _ostree_kernel_args_new ();

  /* If they want the current kernel's args, they very likely don't
   * want the ones from the merge.
   */
  if (opt_kernel_proc_cmdline)
    {
      gs_unref_object GFile *proc_cmdline_path = g_file_new_for_path ("/proc/cmdline");
      gs_free char *proc_cmdline = NULL;
      gsize proc_cmdline_len = 0;
      gs_strfreev char **proc_cmdline_args = NULL;

      if (!g_file_load_contents (proc_cmdline_path, cancellable,
                                 &proc_cmdline, &proc_cmdline_len,
                                 NULL, error))
        goto out;

      g_strchomp (proc_cmdline);

      proc_cmdline_args = g_strsplit (proc_cmdline, " ", -1);
      _ostree_kernel_args_replace_argv (kargs, proc_cmdline_args);
    }
  else if (merge_deployment)
    {
      OstreeBootconfigParser *bootconfig = ostree_deployment_get_bootconfig (merge_deployment);
      gs_strfreev char **previous_args = g_strsplit (ostree_bootconfig_parser_get (bootconfig, "options"), " ", -1);

      _ostree_kernel_args_replace_argv (kargs, previous_args);
    }

  if (opt_kernel_argv)
    {
      _ostree_kernel_args_replace_argv (kargs, opt_kernel_argv);
    }

  if (opt_kernel_argv_append)
    {
      _ostree_kernel_args_append_argv (kargs, opt_kernel_argv_append);
    }

  {
    gs_strfreev char **kargs_strv = _ostree_kernel_args_to_strv (kargs);

    if (!ostree_sysroot_deploy_tree (sysroot,
                                     opt_osname, revision, origin,
                                     merge_deployment, kargs_strv,
                                     &new_deployment,
                                     cancellable, error))
      goto out;
  }

  if (!ostree_sysroot_simple_write_deployment (sysroot, opt_osname,
                                               new_deployment, merge_deployment,
                                               opt_retain ? OSTREE_SYSROOT_SIMPLE_WRITE_DEPLOYMENT_FLAGS_RETAIN : 0,
                                               cancellable, error))
    goto out;

  ret = TRUE;
 out:
  if (origin)
    g_key_file_unref (origin);
  if (context)
    g_option_context_free (context);
  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;
}
static GIcon *
xfdesktop_load_icon_from_desktop_file(XfdesktopRegularFileIcon *regular_icon)
{
    gchar *contents, *icon_name;
    gsize length;
    GIcon *gicon = NULL;
    gchar *p;
    GKeyFile *key_file;

    /* try to load the file into memory */
    if(!g_file_load_contents(regular_icon->priv->file, NULL, &contents, &length, NULL, NULL))
        return NULL;

    /* allocate a new key file */
    key_file = g_key_file_new();

    /* try to parse the key file from the contents of the file */
    if(!g_key_file_load_from_data(key_file, contents, length, 0, NULL)) {
        g_free(contents);
        return NULL;
    }

    /* try to determine the custom icon name */
    icon_name = g_key_file_get_string(key_file,
                                      G_KEY_FILE_DESKTOP_GROUP,
                                      G_KEY_FILE_DESKTOP_KEY_ICON,
                                      NULL);

    /* No icon name in the desktop file */
    if(icon_name == NULL) {
        /* free key file and in-memory data */
        g_key_file_free(key_file);
        g_free(contents);
        return NULL;
    }

    /* icon_name is an absolute path, create it as a file icon */
    if(g_file_test(icon_name, G_FILE_TEST_IS_REGULAR)) {
        gicon = g_file_icon_new(g_file_new_for_path(icon_name));
    }

    /* check if the icon theme includes the icon name as-is */
    if(gicon == NULL) {
        if(gtk_icon_theme_has_icon(gtk_icon_theme_get_default(), icon_name)) {
            /* load it */
            gicon = g_themed_icon_new(icon_name);
        }
    }

    /* drop any suffix (e.g. '.png') from themed icons and try to laod that */
    if(gicon == NULL) {
        gchar *tmp_name = NULL;

        p = strrchr(icon_name, '.');
        if(p != NULL)
            tmp_name = g_strndup(icon_name, p - icon_name);

        /* check if the icon theme includes the icon name */
        if(tmp_name && gtk_icon_theme_has_icon(gtk_icon_theme_get_default(), tmp_name)) {
            /* load it */
            gicon = g_themed_icon_new(tmp_name);
        }
        g_free(tmp_name);
    }

    /* maybe it points to a file in the pixmaps folder */
    if(gicon == NULL) {
        gchar *filename = g_build_filename("pixmaps", icon_name, NULL);
        gchar *tmp_name = NULL;

        if(filename)
            tmp_name = xfce_resource_lookup(XFCE_RESOURCE_DATA, filename);

        if(tmp_name)
            gicon = g_file_icon_new(g_file_new_for_path(tmp_name));

        g_free(filename);
        g_free(tmp_name);
    }

    /* free key file and in-memory data */
    g_key_file_free(key_file);
    g_free(contents);
    g_free(icon_name);

    return gicon;
}
Example #23
0
static void
extension_search_result(GFile *parent, GFileInfo *info, gpointer unused, I7SearchWindow *self)
{
	I7_SEARCH_WINDOW_USE_PRIVATE(self, priv);
	GError *err = NULL;
	const char *basename = g_file_info_get_name(info);
	GFile *file = g_file_get_child(parent, basename);
	char *contents;
	GtkTextBuffer *buffer;
	GtkTreeIter result;
	GtkTextIter search_from, match_start, match_end;

	if(!g_file_load_contents(file, NULL, &contents, NULL, NULL, &err)) {
		char *author_display_name = file_get_display_name(parent);
		const char *ext_display_name = g_file_info_get_display_name(info);

		error_dialog_file_operation(GTK_WINDOW(self), file, err, I7_FILE_ERROR_OTHER,
		  /* TRANSLATORS: Error opening EXTENSION_NAME by AUTHOR_NAME */
		  _("Error opening extension '%s' by '%s':"), author_display_name, ext_display_name);

		g_free(author_display_name);
		g_object_unref(file);
		return;
	}

	buffer = GTK_TEXT_BUFFER(gtk_source_buffer_new(NULL));
	gtk_text_buffer_set_text(buffer, contents, -1);
	g_free(contents);

	gtk_text_buffer_get_start_iter(buffer, &search_from);

	start_spinner(self);

	while(find_no_wrap(&search_from, priv->text, TRUE,
		GTK_SOURCE_SEARCH_TEXT_ONLY | (priv->ignore_case? GTK_SOURCE_SEARCH_CASE_INSENSITIVE : 0),
		priv->algorithm, &match_start, &match_end))
	{
		unsigned lineno;
		char *sort, *context;

		while(gtk_events_pending())
			gtk_main_iteration();

		search_from = match_end;

		/* Get the line number (counted from 0) */
		lineno = gtk_text_iter_get_line(&match_start) + 1;

		context = extract_context(buffer, &match_start, &match_end);

		/* Make a sort string */
		sort = g_strdup_printf("%s %04i", basename, lineno);

		gtk_list_store_append(priv->results, &result);
		gtk_list_store_set(priv->results, &result,
			I7_RESULT_CONTEXT_COLUMN, context,
			I7_RESULT_SORT_STRING_COLUMN, sort,
			I7_RESULT_FILE_COLUMN, file,
			I7_RESULT_RESULT_TYPE_COLUMN, I7_RESULT_TYPE_EXTENSION,
			I7_RESULT_LINE_NUMBER_COLUMN, lineno,
			-1);

		g_free(context);
		g_free(sort);
	}

	stop_spinner(self);

	g_object_unref(buffer);
	g_object_unref(file);
}
Example #24
0
static void
load_sliced_image (GTask        *result,
                   gpointer      object,
                   gpointer      task_data,
                   GCancellable *cancellable)
{
  AsyncImageData *data;
  GList *res = NULL;
  GdkPixbuf *pix;
  gint width, height, y, x;
  GdkPixbufLoader *loader;
  GError *error = NULL;
  gchar *buffer = NULL;
  gsize length;

  g_assert (!cancellable);

  data = task_data;
  g_assert (data);

  loader = gdk_pixbuf_loader_new ();
  g_signal_connect (loader, "size-prepared", G_CALLBACK (on_loader_size_prepared), data);

  if (!g_file_load_contents (data->gfile, NULL, &buffer, &length, NULL, &error))
    {
      g_warning ("Failed to open sliced image: %s", error->message);
      goto out;
    }

  if (!gdk_pixbuf_loader_write (loader, (const guchar *) buffer, length, &error))
    {
      g_warning ("Failed to load image: %s", error->message);
      goto out;
    }

  if (!gdk_pixbuf_loader_close (loader, NULL))
    goto out;

  pix = gdk_pixbuf_loader_get_pixbuf (loader);
  width = gdk_pixbuf_get_width (pix);
  height = gdk_pixbuf_get_height (pix);
  for (y = 0; y < height; y += data->grid_height * data->scale_factor)
    {
      for (x = 0; x < width; x += data->grid_width * data->scale_factor)
        {
          GdkPixbuf *pixbuf = gdk_pixbuf_new_subpixbuf (pix, x, y,
                                                        data->grid_width * data->scale_factor,
                                                        data->grid_height * data->scale_factor);
          g_assert (pixbuf != NULL);
          res = g_list_append (res, pixbuf);
        }
    }

 out:
  /* We don't need the original pixbuf anymore, which is owned by the loader,
   * though the subpixbufs will hold a reference. */
  g_object_unref (loader);
  g_free (buffer);
  g_clear_pointer (&error, g_error_free);
  g_task_return_pointer (result, res, free_glist_unref_gobjects);
}
Example #25
0
static gboolean
builder_source_file_download (BuilderSource *source,
                              gboolean update_vcs,
                              BuilderContext *context,
                              GError **error)
{
  BuilderSourceFile *self = BUILDER_SOURCE_FILE (source);
  g_autoptr(GFile) file = NULL;
  gboolean is_local, is_inline;
  g_autoptr (GFile) dir = NULL;
  g_autofree char *dir_path = NULL;
  g_autofree char *sha256 = NULL;
  g_autofree char *base_name = NULL;
  g_autoptr(GBytes) content = NULL;

  file = get_source_file (self, context, &is_local, &is_inline, error);
  if (file == NULL)
    return FALSE;

  base_name = g_file_get_basename (file);

  if (g_file_query_exists (file, NULL))
    {
      if (is_local && self->sha256 != NULL && *self->sha256 != 0)
        {
          g_autofree char *data = NULL;
          gsize len;

          if (!g_file_load_contents (file, NULL, &data, &len, NULL, error))
            return FALSE;

          sha256 = g_compute_checksum_for_string (G_CHECKSUM_SHA256, data, len);
          if (strcmp (sha256, self->sha256) != 0)
            {
              g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
                           "Wrong sha256 for %s, expected %s, was %s", base_name, self->sha256, sha256);
              return FALSE;
            }
        }
      return TRUE;
    }

  if (is_local)
    {
      g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Can't find file at %s", self->path);
      return FALSE;
    }

  content = download_uri (self->url,
                          context,
                          error);
  if (content == NULL)
    return FALSE;

  sha256 = g_compute_checksum_for_string (G_CHECKSUM_SHA256,
                                          g_bytes_get_data (content, NULL),
                                          g_bytes_get_size (content));

  /* sha256 is optional for inline data */
  if (((self->sha256 != NULL && *self->sha256 != 0) || !is_inline) &&
      strcmp (sha256, self->sha256) != 0)
    {
      g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
                   "Wrong sha256 for %s, expected %s, was %s", base_name, self->sha256, sha256);
      return FALSE;
    }

  dir = g_file_get_parent (file);
  dir_path = g_file_get_path (dir);
  g_mkdir_with_parents (dir_path, 0755);

  if (!g_file_replace_contents (file,
                                g_bytes_get_data (content, NULL),
                                g_bytes_get_size (content),
                                NULL, FALSE, G_FILE_CREATE_NONE, NULL,
                                NULL, error))
    return FALSE;

  return TRUE;
}
Example #26
0
static void
ide_compile_commands_load_worker (GTask        *task,
                                  gpointer      source_object,
                                  gpointer      task_data,
                                  GCancellable *cancellable)
{
  IdeCompileCommands *self = source_object;
  GFile *gfile = task_data;
  g_autoptr(JsonParser) parser = NULL;
  g_autoptr(GError) error = NULL;
  g_autoptr(GHashTable) info_by_file = NULL;
  g_autoptr(GHashTable) directories_by_path = NULL;
  g_autoptr(GPtrArray) vala_info = NULL;
  g_autofree gchar *contents = NULL;
  JsonNode *root;
  JsonArray *ar;
  gsize len = 0;
  guint n_items;

  IDE_ENTRY;

  g_assert (G_IS_TASK (task));
  g_assert (IDE_IS_COMPILE_COMMANDS (self));
  g_assert (G_IS_FILE (gfile));
  g_assert (!cancellable || G_IS_CANCELLABLE (cancellable));

  parser = json_parser_new ();

  if (!g_file_load_contents (gfile, cancellable, &contents, &len, NULL, &error) ||
      !json_parser_load_from_data (parser, contents, len, &error))
    {
      g_task_return_error (task, g_steal_pointer (&error));
      IDE_EXIT;
    }

  if (NULL == (root = json_parser_get_root (parser)) ||
      !JSON_NODE_HOLDS_ARRAY (root) ||
      NULL == (ar = json_node_get_array (root)))
    {
      g_task_return_new_error (task,
                               G_IO_ERROR,
                               G_IO_ERROR_INVALID_DATA,
                               "Failed to extract commands, invalid json");
      IDE_EXIT;
    }

  info_by_file = g_hash_table_new_full (g_file_hash,
                                        (GEqualFunc)g_file_equal,
                                        NULL,
                                        compile_info_free);

  directories_by_path = g_hash_table_new_full (g_str_hash,
                                               g_str_equal,
                                               NULL,
                                               g_object_unref);

  vala_info = g_ptr_array_new_with_free_func (compile_info_free);

  n_items = json_array_get_length (ar);

  for (guint i = 0; i < n_items; i++)
    {
      CompileInfo *info;
      JsonNode *item;
      JsonNode *value;
      JsonObject *obj;
      GFile *dir;
      const gchar *directory = NULL;
      const gchar *file = NULL;
      const gchar *command = NULL;

      item = json_array_get_element (ar, i);

      /* Skip past this node if its invalid for some reason, so we
       * can try to be tolerante of errors created by broken tooling.
       */
      if (item == NULL ||
          !JSON_NODE_HOLDS_OBJECT (item) ||
          NULL == (obj = json_node_get_object (item)))
        continue;

      if (json_object_has_member (obj, "file") &&
          NULL != (value = json_object_get_member (obj, "file")) &&
          JSON_NODE_HOLDS_VALUE (value))
        file = json_node_get_string (value);

      if (json_object_has_member (obj, "directory") &&
          NULL != (value = json_object_get_member (obj, "directory")) &&
          JSON_NODE_HOLDS_VALUE (value))
        directory = json_node_get_string (value);

      if (json_object_has_member (obj, "command") &&
          NULL != (value = json_object_get_member (obj, "command")) &&
          JSON_NODE_HOLDS_VALUE (value))
        command = json_node_get_string (value);

      /* Ignore items that are missing something or other */
      if (file == NULL || command == NULL || directory == NULL)
        continue;

      /* Try to reduce the number of GFile we have for directories */
      if (NULL == (dir = g_hash_table_lookup (directories_by_path, directory)))
        {
          dir = g_file_new_for_path (directory);
          g_hash_table_insert (directories_by_path, (gchar *)directory, dir);
        }

      info = g_slice_new (CompileInfo);
      info->file = g_file_resolve_relative_path (dir, file);
      info->directory = g_object_ref (dir);
      info->command = g_strdup (command);
      g_hash_table_replace (info_by_file, info->file, info);

      /*
       * We might need to keep a special copy of this for resolving .vala
       * builds which won't be able ot be matched based on the filename. We
       * keep all of them around right now in case we want to later on find
       * the closest match based on directory.
       */
      if (g_str_has_suffix (file, ".vala"))
        {
          info = g_slice_new (CompileInfo);
          info->file = g_file_resolve_relative_path (dir, file);
          info->directory = g_object_ref (dir);
          info->command = g_strdup (command);
          g_ptr_array_add (vala_info, info);
        }
    }

  self->info_by_file = g_steal_pointer (&info_by_file);
  self->vala_info = g_steal_pointer (&vala_info);

  g_task_return_boolean (task, TRUE);

  IDE_EXIT;
}
Example #27
0
static gboolean
do_initial_setup (GCancellable     *cancellable,
                  GError          **error)
{
  gboolean ret = FALSE;
  gs_unref_object GFile *etc_os_release =
    g_file_new_for_path ("/etc/os-release");
  gs_free char *contents = NULL;
  gs_unref_hashtable GHashTable *osrelease_values = NULL;
  const char *pretty_name;
  const char *passwd_root_argv[] = { "passwd", "root", NULL };
  gsize len;
  guint i;
  const guint max_passwd_attempts = 5;

  if (!g_file_load_contents (etc_os_release, cancellable,
                             &contents, &len, NULL, error))
    {
      g_prefix_error (error, "Reading /etc/os-release: ");
      goto out;
    }

  osrelease_values = parse_os_release (contents, "\n");
  pretty_name = g_hash_table_lookup (osrelease_values, "PRETTY_NAME");
  if (!pretty_name)
    pretty_name = g_hash_table_lookup (osrelease_values, "ID");
  if (!pretty_name)
    pretty_name = " (/etc/os-release not found)";

  g_print (_("Welcome to %s"), pretty_name);
  g_print ("\n");

  (void) readline (_("Press Enter to begin setup"));

  g_print (_("No user accounts found, and root password is locked"));
  g_print ("\n");

  for (i = 0; i < max_passwd_attempts; i++)
    {
      int estatus;

      if (!g_spawn_sync (NULL, (char**)passwd_root_argv, NULL,
                         G_SPAWN_CHILD_INHERITS_STDIN,
                         NULL, NULL, NULL, NULL,
                         &estatus, error))
        goto out;

      if (g_spawn_check_exit_status (estatus, NULL))
        break;
    }
  if (i == max_passwd_attempts)
    {
      g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
                   "Failed to run \"passwd root\" after %u attempts",
                   max_passwd_attempts);
      goto out;
    }

  ret = TRUE;
 out:
  return ret;
}
TotemPlParserResult
totem_pl_parser_add_m3u (TotemPlParser *parser,
			 GFile *file,
			 GFile *base_file,
			 TotemPlParseData *parse_data,
			 gpointer data)
{
	TotemPlParserResult retval = TOTEM_PL_PARSER_RESULT_UNHANDLED;
	char *contents, **lines;
	gsize size;
	guint i, num_lines;
	gboolean dos_mode = FALSE;
	const char *extinfo, *extvlcopt_audiotrack;
	char *pl_uri;

	if (g_file_load_contents (file, NULL, &contents, &size, NULL, NULL) == FALSE) {
		DEBUG (file, g_print ("Failed to load '%s'\n", uri));
		return TOTEM_PL_PARSER_RESULT_ERROR;
	}

	/* .pls files with a .m3u extension, the nasties */
	if (g_str_has_prefix (contents, "[playlist]") != FALSE
			|| g_str_has_prefix (contents, "[Playlist]") != FALSE
			|| g_str_has_prefix (contents, "[PLAYLIST]") != FALSE) {
		DEBUG (file, g_print ("Parsing '%s' playlist as PLS\n", uri));
		retval = totem_pl_parser_add_pls_with_contents (parser, file, base_file, contents, parse_data);
		g_free (contents);
		return retval;
	}

	if (strstr (contents, EXTINF_HLS) ||
	    strstr (contents, EXTINF_HLS2)) {
		DEBUG (file, g_print ("Unhandled HLS playlist '%s', should be passed to player\n", uri));
		g_free (contents);
		return retval;
	}

	/* Try to use ISO-8859-1 if we don't have valid UTF-8,
	 * try to parse anyway if it's not ISO-8859-1 */
	if (g_utf8_validate (contents, -1, NULL) == FALSE) {
		char *fixed;
		fixed = g_convert (contents, -1, "UTF-8", "ISO8859-1", NULL, NULL, NULL);
		if (fixed != NULL) {
			g_free (contents);
			contents = fixed;
		}
	}

	/* is non-NULL if there's an EXTINF on a preceding line */
	extinfo = NULL;
	extvlcopt_audiotrack = NULL;

	/* figure out whether we're a unix m3u or dos m3u */
	if (strstr(contents, "\x0d")) {
		dos_mode = TRUE;
	}

	lines = g_strsplit_set (contents, "\r\n", 0);
	g_free (contents);
	num_lines = g_strv_length (lines);
	/* We don't count the terminating NULL */
	num_lines--;

	/* Send out the playlist start and get crackin' */
	pl_uri = g_file_get_uri (file);
	totem_pl_parser_add_uri (parser,
				 TOTEM_PL_PARSER_FIELD_IS_PLAYLIST, TRUE,
				 TOTEM_PL_PARSER_FIELD_URI, pl_uri,
				 TOTEM_PL_PARSER_FIELD_CONTENT_TYPE, "audio/x-mpegurl",
				 NULL);

	for (i = 0; lines[i] != NULL; i++) {
		const char *line;
		char *length;
		gint64 length_num = 0;
		char *audio_track;

		line = lines[i];

		if (line[0] == '\0')
			continue;

		retval = TOTEM_PL_PARSER_RESULT_SUCCESS;

		/* Ignore leading spaces */
		for (; g_ascii_isspace (line[0]); line++)
			;

		/* Ignore comments, but mark it if we have extra info */
		if (line[0] == '#') {
			if (extinfo == NULL && g_str_has_prefix (line, EXTINF) != FALSE)
				extinfo = line;
			if (extvlcopt_audiotrack == NULL && g_str_has_prefix (line, EXTVLCOPT_AUDIOTRACK) != FALSE)
				extvlcopt_audiotrack = line;
			continue;
		}

		length = totem_pl_parser_get_extinfo_length (extinfo);
		if (length != NULL)
			length_num = totem_pl_parser_parse_duration (length, totem_pl_parser_is_debugging_enabled (parser));
		g_free (length);

		audio_track = totem_pl_parser_get_extvlcopt_audio_track (extvlcopt_audiotrack);

		/* Either it's a URI, or it has a proper path ... */
		if (strstr(line, "://") != NULL
				|| line[0] == G_DIR_SEPARATOR) {
			GFile *uri;

			uri = g_file_new_for_commandline_arg (line);
			if (length_num < 0 ||
			    totem_pl_parser_parse_internal (parser, uri, NULL, parse_data) != TOTEM_PL_PARSER_RESULT_SUCCESS) {
				totem_pl_parser_add_uri (parser,
							 TOTEM_PL_PARSER_FIELD_URI, line,
							 TOTEM_PL_PARSER_FIELD_TITLE, totem_pl_parser_get_extinfo_title (extinfo),
							 TOTEM_PL_PARSER_FIELD_AUDIO_TRACK, audio_track,
							 NULL);
			}
			g_object_unref (uri);
		} else if (g_ascii_isalpha (line[0]) != FALSE
			   && g_str_has_prefix (line + 1, ":\\")) {
			/* Path relative to a drive on Windows, we need to use
			 * the base that was passed to us */
			GFile *uri;

			lines[i] = g_strdelimit (lines[i], "\\", '/');
			/* + 2, skip drive letter */
			uri = g_file_get_child (base_file, line + 2);
			totem_pl_parser_add_uri (parser,
						 TOTEM_PL_PARSER_FIELD_FILE, uri,
						 TOTEM_PL_PARSER_FIELD_TITLE, totem_pl_parser_get_extinfo_title (extinfo),
						 TOTEM_PL_PARSER_FIELD_AUDIO_TRACK, audio_track,
						 NULL);
			g_object_unref (uri);
		} else if (line[0] == '\\' && line[1] == '\\') {
			/* ... Or it's in the windows smb form
			 * (\\machine\share\filename), Note drive names
			 * (C:\ D:\ etc) are unhandled (unknown base for
			 * drive letters) */
		        char *tmpuri;

			lines[i] = g_strdelimit (lines[i], "\\", '/');
			tmpuri = g_strjoin (NULL, "smb:", line, NULL);

			totem_pl_parser_add_uri (parser,
						 TOTEM_PL_PARSER_FIELD_URI, tmpuri,
						 TOTEM_PL_PARSER_FIELD_TITLE, totem_pl_parser_get_extinfo_title (extinfo),
						 TOTEM_PL_PARSER_FIELD_AUDIO_TRACK, audio_track,
						 NULL);

			g_free (tmpuri);
		} else {
			/* Try with a base */
			GFile *uri, *_base_file;
			char sep;

			_base_file = g_file_get_parent (file);
			sep = (dos_mode ? '\\' : '/');
			if (sep == '\\')
				lines[i] = g_strdelimit (lines[i], "\\", '/');
			uri = g_file_get_child (_base_file, line);
			g_object_unref (_base_file);
			totem_pl_parser_add_uri (parser,
						 TOTEM_PL_PARSER_FIELD_FILE, uri,
						 TOTEM_PL_PARSER_FIELD_TITLE, totem_pl_parser_get_extinfo_title (extinfo),
						 TOTEM_PL_PARSER_FIELD_AUDIO_TRACK, audio_track,
						 NULL);
			g_object_unref (uri);
		}
		extinfo = NULL;
		extvlcopt_audiotrack = NULL;

		g_free (audio_track);
	}

	g_strfreev (lines);

	totem_pl_parser_playlist_end (parser, pl_uri);
	g_free (pl_uri);

	return retval;
}
gboolean
flatpak_builtin_build (int argc, char **argv, GCancellable *cancellable, GError **error)
{
  g_autoptr(GOptionContext) context = NULL;
  g_autoptr(FlatpakDeploy) runtime_deploy = NULL;
  g_autoptr(GVariant) runtime_deploy_data = NULL;
  g_autoptr(FlatpakDeploy) extensionof_deploy = NULL;
  g_autoptr(GFile) var = NULL;
  g_autoptr(GFile) var_tmp = NULL;
  g_autoptr(GFile) var_lib = NULL;
  g_autoptr(GFile) usr = NULL;
  g_autoptr(GFile) res_deploy = NULL;
  g_autoptr(GFile) res_files = NULL;
  g_autoptr(GFile) app_files = NULL;
  gboolean app_files_ro = FALSE;
  g_autoptr(GFile) runtime_files = NULL;
  g_autoptr(GFile) metadata = NULL;
  g_autofree char *metadata_contents = NULL;
  g_autofree char *runtime = NULL;
  g_autofree char *runtime_ref = NULL;
  g_autofree char *extensionof_ref = NULL;
  g_autofree char *extensionof_tag = NULL;
  g_autofree char *extension_point = NULL;
  g_autofree char *extension_tmpfs_point = NULL;
  g_autoptr(GKeyFile) metakey = NULL;
  g_autoptr(GKeyFile) runtime_metakey = NULL;
  g_autoptr(FlatpakBwrap) bwrap = NULL;
  g_auto(GStrv) minimal_envp = NULL;
  gsize metadata_size;
  const char *directory = NULL;
  const char *command = "/bin/sh";
  g_autofree char *id = NULL;
  int i;
  int rest_argv_start, rest_argc;
  g_autoptr(FlatpakContext) arg_context = NULL;
  g_autoptr(FlatpakContext) app_context = NULL;
  gboolean custom_usr;
  g_auto(GStrv) runtime_ref_parts = NULL;
  FlatpakRunFlags run_flags;
  const char *group = NULL;
  const char *runtime_key = NULL;
  const char *dest = NULL;
  gboolean is_app = FALSE;
  gboolean is_extension = FALSE;
  gboolean is_app_extension = FALSE;
  g_autofree char *app_info_path = NULL;
  g_autofree char *app_extensions = NULL;
  g_autofree char *runtime_extensions = NULL;
  g_autofree char *instance_id_host_dir = NULL;
  char pid_str[64];
  g_autofree char *pid_path = NULL;
  g_autoptr(GFile) app_id_dir = NULL;

  context = g_option_context_new (_("DIRECTORY [COMMAND [ARGUMENT…]] - Build in directory"));
  g_option_context_set_translation_domain (context, GETTEXT_PACKAGE);

  rest_argc = 0;
  for (i = 1; i < argc; i++)
    {
      /* The non-option is the directory, take it out of the arguments */
      if (argv[i][0] != '-')
        {
          rest_argv_start = i;
          rest_argc = argc - i;
          argc = i;
          break;
        }
    }

  arg_context = flatpak_context_new ();
  g_option_context_add_group (context, flatpak_context_get_options (arg_context));

  if (!flatpak_option_context_parse (context, options, &argc, &argv, FLATPAK_BUILTIN_FLAG_NO_DIR, NULL, cancellable, error))
    return FALSE;

  if (rest_argc == 0)
    return usage_error (context, _("DIRECTORY must be specified"), error);

  directory = argv[rest_argv_start];
  if (rest_argc >= 2)
    command = argv[rest_argv_start + 1];

  res_deploy = g_file_new_for_commandline_arg (directory);
  metadata = g_file_get_child (res_deploy, opt_metadata ? opt_metadata : "metadata");

  if (!g_file_query_exists (res_deploy, NULL) ||
      !g_file_query_exists (metadata, NULL))
    return flatpak_fail (error, _("Build directory %s not initialized, use flatpak build-init"), directory);

  if (!g_file_load_contents (metadata, cancellable, &metadata_contents, &metadata_size, NULL, error))
    return FALSE;

  metakey = g_key_file_new ();
  if (!g_key_file_load_from_data (metakey, metadata_contents, metadata_size, 0, error))
    return FALSE;

  if (g_key_file_has_group (metakey, FLATPAK_METADATA_GROUP_APPLICATION))
    {
      group = FLATPAK_METADATA_GROUP_APPLICATION;
      is_app = TRUE;
    }
  else if (g_key_file_has_group (metakey, FLATPAK_METADATA_GROUP_RUNTIME))
    {
      group = FLATPAK_METADATA_GROUP_RUNTIME;
    }
  else
    return flatpak_fail (error, _("metadata invalid, not application or runtime"));

  extensionof_ref = g_key_file_get_string (metakey,
                                           FLATPAK_METADATA_GROUP_EXTENSION_OF,
                                           FLATPAK_METADATA_KEY_REF, NULL);
  if (extensionof_ref != NULL)
    {
      is_extension = TRUE;
      if (g_str_has_prefix (extensionof_ref, "app/"))
        is_app_extension = TRUE;
    }

  extensionof_tag = g_key_file_get_string (metakey,
                                           FLATPAK_METADATA_GROUP_EXTENSION_OF,
                                           FLATPAK_METADATA_KEY_TAG, NULL);

  id = g_key_file_get_string (metakey, group, FLATPAK_METADATA_KEY_NAME, error);
  if (id == NULL)
    return FALSE;

  if (opt_runtime)
    runtime_key = FLATPAK_METADATA_KEY_RUNTIME;
  else
    runtime_key = FLATPAK_METADATA_KEY_SDK;

  runtime = g_key_file_get_string (metakey, group, runtime_key, error);
  if (runtime == NULL)
    return FALSE;

  runtime_ref = g_build_filename ("runtime", runtime, NULL);

  runtime_ref_parts = flatpak_decompose_ref (runtime_ref, error);
  if (runtime_ref_parts == NULL)
    return FALSE;

  custom_usr = FALSE;
  usr = g_file_get_child (res_deploy,  opt_sdk_dir ? opt_sdk_dir : "usr");
  if (g_file_query_exists (usr, cancellable))
    {
      custom_usr = TRUE;
      runtime_files = g_object_ref (usr);
    }
  else
    {
      runtime_deploy = flatpak_find_deploy_for_ref (runtime_ref, NULL, cancellable, error);
      if (runtime_deploy == NULL)
        return FALSE;

      runtime_deploy_data = flatpak_deploy_get_deploy_data (runtime_deploy, FLATPAK_DEPLOY_VERSION_ANY, cancellable, error);
      if (runtime_deploy_data == NULL)
        return FALSE;

      runtime_metakey = flatpak_deploy_get_metadata (runtime_deploy);

      runtime_files = flatpak_deploy_get_files (runtime_deploy);
    }

  var = g_file_get_child (res_deploy, "var");
  var_tmp = g_file_get_child (var, "tmp");
  if (!flatpak_mkdir_p (var_tmp, cancellable, error))
    return FALSE;
  var_lib = g_file_get_child (var, "lib");
  if (!flatpak_mkdir_p (var_lib, cancellable, error))
    return FALSE;

  res_files = g_file_get_child (res_deploy, "files");

  if (is_app)
    {
      app_files = g_object_ref (res_files);
      if (opt_with_appdir)
        app_id_dir = flatpak_ensure_data_dir (id, cancellable, NULL);
    }
  else if (is_extension)
    {
      g_autoptr(GKeyFile) x_metakey = NULL;
      g_autofree char *x_group = NULL;
      g_autofree char *x_dir = NULL;
      g_autofree char *x_subdir_suffix = NULL;
      char *x_subdir = NULL;
      g_autofree char *bare_extension_point = NULL;

      extensionof_deploy = flatpak_find_deploy_for_ref (extensionof_ref, NULL, cancellable, error);
      if (extensionof_deploy == NULL)
        return FALSE;

      x_metakey = flatpak_deploy_get_metadata (extensionof_deploy);

      /* Since we have tagged extensions, it is possible that an extension could
       * be listed more than once in the "parent" flatpak. In that case, we should
       * try and disambiguate using the following rules:
       *
       * 1. Use the 'tag=' key in the ExtensionOfSection and if not found:
       * 2. Use the only extension point available if there is only one.
       * 3. If there are no matching groups, return NULL.
       * 4. In all other cases, error out.
       */
      if (!find_matching_extension_group_in_metakey (x_metakey,
                                                     id,
                                                     extensionof_tag,
                                                     &x_group,
                                                     error))
        return FALSE;

      if (x_group == NULL)
        {
          /* Failed, look for subdirectories=true parent */
          char *last_dot = strrchr (id, '.');

          if (last_dot != NULL)
            {
              char *parent_id = g_strndup (id, last_dot - id);
              if (!find_matching_extension_group_in_metakey (x_metakey,
                                                             parent_id,
                                                             extensionof_tag,
                                                             &x_group,
                                                             error))
                return FALSE;

              if (x_group != NULL &&
                  g_key_file_get_boolean (x_metakey, x_group,
                                          FLATPAK_METADATA_KEY_SUBDIRECTORIES,
                                          NULL))
                x_subdir = last_dot + 1;
            }

          if (x_subdir == NULL)
            return flatpak_fail (error, _("No extension point matching %s in %s"), id, extensionof_ref);
        }

      x_dir = g_key_file_get_string (x_metakey, x_group,
                                     FLATPAK_METADATA_KEY_DIRECTORY, error);
      if (x_dir == NULL)
        return FALSE;

      x_subdir_suffix = g_key_file_get_string (x_metakey, x_group,
                                               FLATPAK_METADATA_KEY_SUBDIRECTORY_SUFFIX,
                                               NULL);

      if (is_app_extension)
        {
          app_files = flatpak_deploy_get_files (extensionof_deploy);
          app_files_ro = TRUE;
          if (x_subdir != NULL)
            extension_tmpfs_point = g_build_filename ("/app", x_dir, NULL);
          bare_extension_point = g_build_filename ("/app", x_dir, x_subdir, NULL);
        }
      else
        {
          if (x_subdir != NULL)
            extension_tmpfs_point = g_build_filename ("/usr", x_dir, NULL);
          bare_extension_point = g_build_filename ("/usr", x_dir, x_subdir, NULL);
        }

      extension_point = g_build_filename (bare_extension_point, x_subdir_suffix, NULL);
    }

  app_context = flatpak_app_compute_permissions (metakey,
                                                 runtime_metakey,
                                                 error);
  if (app_context == NULL)
    return FALSE;

  flatpak_context_allow_host_fs (app_context);
  flatpak_context_merge (app_context, arg_context);

  minimal_envp = flatpak_run_get_minimal_env (TRUE, FALSE);
  bwrap = flatpak_bwrap_new (minimal_envp);
  flatpak_bwrap_add_args (bwrap, flatpak_get_bwrap (), NULL);

  run_flags =
    FLATPAK_RUN_FLAG_DEVEL | FLATPAK_RUN_FLAG_MULTIARCH | FLATPAK_RUN_FLAG_NO_SESSION_HELPER |
    FLATPAK_RUN_FLAG_SET_PERSONALITY | FLATPAK_RUN_FLAG_NO_A11Y_BUS_PROXY;
  if (opt_die_with_parent)
    run_flags |= FLATPAK_RUN_FLAG_DIE_WITH_PARENT;
  if (custom_usr)
    run_flags |= FLATPAK_RUN_FLAG_WRITABLE_ETC;

  run_flags |= flatpak_context_get_run_flags (app_context);

  /* Unless manually specified, we disable dbus proxy */
  if (!flatpak_context_get_needs_session_bus_proxy (arg_context))
    run_flags |= FLATPAK_RUN_FLAG_NO_SESSION_BUS_PROXY;

  if (!flatpak_context_get_needs_system_bus_proxy (arg_context))
    run_flags |= FLATPAK_RUN_FLAG_NO_SYSTEM_BUS_PROXY;

  if (opt_log_session_bus)
    run_flags |= FLATPAK_RUN_FLAG_LOG_SESSION_BUS;

  if (opt_log_system_bus)
    run_flags |= FLATPAK_RUN_FLAG_LOG_SYSTEM_BUS;

  /* Never set up an a11y bus for builds */
  run_flags |= FLATPAK_RUN_FLAG_NO_A11Y_BUS_PROXY;

  if (!flatpak_run_setup_base_argv (bwrap, runtime_files, app_id_dir, runtime_ref_parts[2],
                                    run_flags, error))
    return FALSE;

  flatpak_bwrap_add_args (bwrap,
                          (custom_usr && !opt_readonly)  ? "--bind" : "--ro-bind", flatpak_file_get_path_cached (runtime_files), "/usr",
                          NULL);

  if (!custom_usr)
    flatpak_bwrap_add_args (bwrap,
                            "--lock-file", "/usr/.ref",
                            NULL);

  if (app_files)
    flatpak_bwrap_add_args (bwrap,
                            (app_files_ro || opt_readonly) ? "--ro-bind" : "--bind", flatpak_file_get_path_cached (app_files), "/app",
                            NULL);
  else
    flatpak_bwrap_add_args (bwrap,
                            "--dir", "/app",
                            NULL);

  if (extension_tmpfs_point)
    flatpak_bwrap_add_args (bwrap,
                            "--tmpfs", extension_tmpfs_point,
                            NULL);

  /* We add the actual bind below so that we're not shadowed by other extensions or their tmpfs */

  if (extension_point)
    dest = extension_point;
  else if (is_app)
    dest = g_strdup ("/app");
  else
    dest = g_strdup ("/usr");

  flatpak_bwrap_add_args (bwrap,
                          "--setenv", "FLATPAK_DEST", dest,
                          "--setenv", "FLATPAK_ID", id,
                          "--setenv", "FLATPAK_ARCH", runtime_ref_parts[2],
                          NULL);

  /* Persist some stuff in /var. We can't persist everything because  that breaks /var things
   * from the host to work. For example the /home -> /var/home on atomic.
   * The interesting things to contain during the build is /var/tmp (for tempfiles shared during builds)
   * and things like /var/lib/rpm, if the installation uses packages.
   */
  flatpak_bwrap_add_args (bwrap,
                          "--bind", flatpak_file_get_path_cached (var_lib), "/var/lib",
                          NULL);
  flatpak_bwrap_add_args (bwrap,
                          "--bind", flatpak_file_get_path_cached (var_tmp), "/var/tmp",
                          NULL);

  flatpak_run_apply_env_vars (bwrap, app_context);

  if (is_app)
    {
      /* We don't actually know the final branchname yet, so use "nobranch" as fallback to avoid unexpected matches.
         This means any extension point used at build time must have explicit versions to work. */
      g_autofree char *fake_ref = g_strdup_printf ("app/%s/%s/nobranch", id, runtime_ref_parts[2]);
      if (!flatpak_run_add_extension_args (bwrap, metakey, fake_ref, FALSE, &app_extensions, cancellable, error))
        return FALSE;
    }

  if (!custom_usr &&
      !flatpak_run_add_extension_args (bwrap, runtime_metakey, runtime_ref, FALSE, &runtime_extensions, cancellable, error))
    return FALSE;

  /* Mount this after the above extensions so we always win */
  if (extension_point)
    flatpak_bwrap_add_args (bwrap,
                            "--bind", flatpak_file_get_path_cached (res_files), extension_point,
                            NULL);

  if (!flatpak_run_add_app_info_args (bwrap,
                                      app_files, NULL, app_extensions,
                                      runtime_files, runtime_deploy_data, runtime_extensions,
                                      id, NULL,
                                      runtime_ref,
                                      app_id_dir, app_context, NULL,
                                      FALSE, TRUE, TRUE,
                                      &app_info_path,
                                      &instance_id_host_dir,
                                      error))
    return FALSE;

  if (!flatpak_run_add_environment_args (bwrap, app_info_path, run_flags, id,
                                         app_context, app_id_dir, NULL, cancellable, error))
    return FALSE;

  for (i = 0; opt_bind_mounts != NULL && opt_bind_mounts[i] != NULL; i++)
    {
      char *split = strchr (opt_bind_mounts[i], '=');
      if (split == NULL)
        {
          g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
                       _("Missing '=' in bind mount option '%s'"), opt_bind_mounts[i]);
          return FALSE;
        }

      *split++ = 0;
      flatpak_bwrap_add_args (bwrap,
                              "--bind", split, opt_bind_mounts[i],
                              NULL);
    }

  if (opt_build_dir != NULL)
    {
      flatpak_bwrap_add_args (bwrap,
                              "--chdir", opt_build_dir,
                              NULL);
    }

  if (!flatpak_bwrap_bundle_args (bwrap, 1, -1, FALSE, error))
    return FALSE;

  flatpak_bwrap_add_args (bwrap, command, NULL);
  flatpak_bwrap_append_argsv (bwrap,
                              &argv[rest_argv_start + 2],
                              rest_argc - 2);

  g_ptr_array_add (bwrap->argv, NULL);

  g_snprintf (pid_str, sizeof (pid_str), "%d", getpid ());
  pid_path = g_build_filename (instance_id_host_dir, "pid", NULL);
  g_file_set_contents (pid_path, pid_str, -1, NULL);

  /* Ensure we unset O_CLOEXEC */
  child_setup (bwrap->fds);
  if (execvpe (flatpak_get_bwrap (), (char **) bwrap->argv->pdata, bwrap->envp) == -1)
    {
      g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errno),
                   _("Unable to start app"));
      return FALSE;
    }

  /* Not actually reached... */
  return TRUE;
}
static gboolean
import_oci (OstreeRepo *repo, GFile *file,
            GCancellable *cancellable, GError **error)
{
#if !defined(HAVE_OSTREE_EXPORT_PATH_PREFIX)
  /* This code actually doesn't user path_prefix, but it need the support
     for reading commits from the transaction that was added at the same time. */
  g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
               "This version of ostree is to old to support OCI exports");
  return FALSE;
#elif !defined(HAVE_LIBARCHIVE)
  g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
               "This version of flatpak is not compiled with libarchive support");
  return FALSE;
#else
  g_autoptr(OstreeMutableTree) archive_mtree = NULL;
  g_autoptr(OstreeMutableTree) mtree = NULL;
  g_autoptr(OstreeMutableTree) files_mtree = NULL;
  g_autoptr(OstreeMutableTree) export_mtree = NULL;
  g_autoptr(GFile) archive_root = NULL;
  g_autoptr(GFile) root = NULL;
  g_autoptr(GFile) files = NULL;
  g_autoptr(GFile) export = NULL;
  g_autoptr(GFile) ref = NULL;
  g_autoptr(GFile) commit = NULL;
  g_autoptr(GFile) commitmeta = NULL;
  g_autoptr(GFile) metadata = NULL;
  g_autofree char *commit_checksum = NULL;
  g_autofree char *ref_data = NULL;
  g_autofree char *commit_data = NULL;
  gsize commit_size;
  g_autofree char *commitmeta_data = NULL;
  g_autofree char *parent = NULL;
  const char *subject;
  const char *body;
  const char *target_ref;
  const char *files_source;
  gsize commitmeta_size;
  g_autoptr(GVariant) commitv = NULL;
  g_autoptr(GVariant) commitv_metadata = NULL;
  g_autoptr(GVariant) commitmetav = NULL;

  if (!ostree_repo_prepare_transaction (repo, NULL, cancellable, error))
    return FALSE;

  /* There is no way to write a subset of the archive to a mtree, so instead
     we write all of it and then build a new mtree with the subset */
  archive_mtree = ostree_mutable_tree_new ();
  if (!ostree_repo_write_archive_to_mtree (repo, file, archive_mtree, NULL,
                                           TRUE,
                                           cancellable, error))
    return FALSE;

  if (!ostree_repo_write_mtree (repo, archive_mtree, &archive_root, cancellable, error))
    return FALSE;

  if (!ostree_repo_file_ensure_resolved ((OstreeRepoFile *) archive_root, error))
    return FALSE;

  ref = g_file_resolve_relative_path (archive_root, "rootfs/ref");
  metadata = g_file_resolve_relative_path (archive_root, "rootfs/metadata");
  commit = g_file_resolve_relative_path (archive_root, "rootfs/commit");
  commitmeta = g_file_resolve_relative_path (archive_root, "rootfs/commitmeta");

  if (!g_file_query_exists (ref, NULL))
    return flatpak_fail (error, "Required file ref not in tarfile");
  if (!g_file_query_exists (metadata, NULL))
    return flatpak_fail (error, "Required file metadata not in tarfile");
  if (!g_file_query_exists (commit, NULL))
    return flatpak_fail (error, "Required file commit not in tarfile");

  if (!g_file_load_contents (ref, cancellable,
                             &ref_data, NULL,
                             NULL, error))
    return FALSE;

  if (g_str_has_prefix (ref_data, "app/"))
    files_source = "rootfs/app";
  else
    files_source = "rootfs/usr";

  files = g_file_resolve_relative_path (archive_root, files_source);
  if (!g_file_query_exists (files, NULL))
    return flatpak_fail (error, "Required directory %s not in tarfile", files_source);

  export = g_file_resolve_relative_path (archive_root, "rootfs/export");