[gnome-multi-writer] Optionally check that USB drives are indeed their advertised size



commit 630287b5b97228247d6beb6463774e041261cc08
Author: Richard Hughes <richard hughsie com>
Date:   Wed Jan 28 20:25:21 2015 +0000

    Optionally check that USB drives are indeed their advertised size

 contrib/gnome-multi-writer.spec.in     |    1 +
 data/Makefile.am                       |    7 +++
 data/org.gnome.MultiWriter.gschema.xml |    7 +++
 data/org.gnome.MultiWriter.policy.in   |   28 ++++++++++++++
 po/POTFILES.in                         |    1 +
 src/gmw-device.c                       |    2 +
 src/gmw-main.c                         |   65 ++++++++++++++++++++++++++++++-
 7 files changed, 108 insertions(+), 3 deletions(-)
---
diff --git a/contrib/gnome-multi-writer.spec.in b/contrib/gnome-multi-writer.spec.in
index 091d57a..eaeefd9 100644
--- a/contrib/gnome-multi-writer.spec.in
+++ b/contrib/gnome-multi-writer.spec.in
@@ -63,6 +63,7 @@ fi
 %{_datadir}/applications/org.gnome.MultiWriter.desktop
 %{_datadir}/glib-2.0/schemas/org.gnome.MultiWriter.gschema.xml
 %{_datadir}/icons/hicolor/*/apps/*
+%{_datadir}/polkit-1/actions/org.gnome.MultiWriter.policy
 %{_mandir}/man1/gnome-multi-writer.1.gz
 
 %changelog
diff --git a/data/Makefile.am b/data/Makefile.am
index 2302ed6..71f67ad 100644
--- a/data/Makefile.am
+++ b/data/Makefile.am
@@ -11,6 +11,11 @@ desktop_DATA = $(desktop_in_files:.desktop.in=.desktop)
 @GSETTINGS_RULES@
 gsettings_SCHEMAS = org.gnome.MultiWriter.gschema.xml
 
+ INTLTOOL_POLICY_RULE@
+polkit_policydir = $(datadir)/polkit-1/actions
+polkit_policy_DATA =                                   \
+       org.gnome.MultiWriter.policy
+
 UI_FILES =                                             \
        gmw-main.ui                                     \
        gmw-menus.ui
@@ -19,6 +24,7 @@ SVG_FILES =                                           \
        usb.svg
 
 EXTRA_DIST =                                           \
+       org.gnome.MultiWriter.policy.in                 \
        $(desktop_in_files)                             \
        $(gsettings_SCHEMAS)                            \
        $(pkgdata_DATA)                                 \
@@ -30,6 +36,7 @@ clean-local :
 
 DISTCLEANFILES =                                       \
        org.gnome.MultiWriter.desktop                   \
+       org.gnome.MultiWriter.policy                    \
        org.gnome.MultiWriter.gschema.xml.valid
 
 -include $(top_srcdir)/git.mk
diff --git a/data/org.gnome.MultiWriter.gschema.xml b/data/org.gnome.MultiWriter.gschema.xml
index 553e950..6554b05 100644
--- a/data/org.gnome.MultiWriter.gschema.xml
+++ b/data/org.gnome.MultiWriter.gschema.xml
@@ -28,6 +28,13 @@
       <!-- TRANSLATORS: schema description -->
       <description>Read and verify the ISO image from each device after writing is complete.</description>
     </key>
+    <key name="enable-probe" type="b">
+      <default>false</default>
+      <!-- TRANSLATORS: schema summary -->
+      <summary>Inspect the device before writing images</summary>
+      <!-- TRANSLATORS: schema description -->
+      <description>Inspect the device to verify the reported device size is the actual media 
size.</description>
+    </key>
     <key name="show-warning" type="b">
       <default>true</default>
       <!-- TRANSLATORS: schema summary -->
diff --git a/data/org.gnome.MultiWriter.policy.in b/data/org.gnome.MultiWriter.policy.in
new file mode 100644
index 0000000..6d96e58
--- /dev/null
+++ b/data/org.gnome.MultiWriter.policy.in
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE policyconfig PUBLIC
+ "-//freedesktop//DTD PolicyKit Policy Configuration 1.0//EN"
+ "http://www.freedesktop.org/standards/PolicyKit/1.0/policyconfig.dtd";>
+<policyconfig>
+
+  <!--
+    Policy definitions for MultiWriter system actions.
+    Copyright (c) 2015 Richard Hughes <richard hughsie com>
+  -->
+
+  <vendor>GNOME</vendor>
+  <vendor_url>https://wiki.gnome.org/Apps/MultiWriter</vendor_url>
+  <icon_name>gnome-multi-writer</icon_name>
+
+  <action id="org.gnome.MultiWriter.probe">
+    <_description>Check the device</_description>
+    <_message>Authentication is required to probe the device</_message>
+    <icon_name>drive-harddisk-usb</icon_name>
+    <defaults>
+      <allow_any>auth_admin</allow_any>
+      <allow_inactive>auth_admin</allow_inactive>
+      <allow_active>auth_admin_keep</allow_active>
+    </defaults>
+    <annotate key="org.freedesktop.policykit.exec.path">/usr/bin/gnome-multi-writer-probe</annotate>
+  </action>
+
+</policyconfig>
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 1fc0a25..2aa7188 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -4,6 +4,7 @@
 data/appdata/org.gnome.MultiWriter.appdata.xml.in
 data/org.gnome.MultiWriter.gschema.xml
 data/org.gnome.MultiWriter.desktop.in
+data/org.gnome.MultiWriter.policy.in
 src/gmw-device.c
 src/gmw-main.c
 src/gmw-probe.c
diff --git a/src/gmw-device.c b/src/gmw-device.c
index 6c4958b..c47e0e6 100644
--- a/src/gmw-device.c
+++ b/src/gmw-device.c
@@ -361,6 +361,8 @@ gmw_device_set_error (GmwDevice *device, const GError *error)
        priv->error = g_error_copy (error);
        g_mutex_unlock (&priv->mutex);
        gmw_device_set_state (device, GMW_DEVICE_STATE_FAILED);
+       gmw_device_set_complete_read (device, 0.f);
+       gmw_device_set_complete_write (device, 0.f);
 }
 
 /**
diff --git a/src/gmw-main.c b/src/gmw-main.c
index 2c6ae8e..c37a434 100644
--- a/src/gmw-main.c
+++ b/src/gmw-main.c
@@ -63,6 +63,7 @@ typedef struct {
        GMutex                   idle_id_mutex;
        GtkWidget               *switch_verify;
        GtkWidget               *switch_blank;
+       GtkWidget               *switch_probe;
 } GmwPrivate;
 
 /**
@@ -406,8 +407,12 @@ gmw_refresh_ui (GmwPrivate *priv)
                        w = gtk_progress_bar_new ();
                        gtk_widget_set_valign (w, GTK_ALIGN_CENTER);
                        gtk_grid_attach (GTK_GRID (grid), w, col + 2, row, 1, 1);
-                       gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (w),
-                                                      gmw_device_get_complete (device));
+                       if (gmw_device_get_complete (device) <= 100.f) {
+                               gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (w),
+                                                              gmw_device_get_complete (device));
+                       } else {
+                               gtk_progress_bar_pulse (GTK_PROGRESS_BAR (w));
+                       }
                }
 
                /* add optional status text */
@@ -874,6 +879,35 @@ gmw_refresh_titlebar_idle_cb (gpointer user_data)
 }
 
 /**
+ * gmw_block_device_probe:
+ **/
+static gboolean
+gmw_block_device_probe (const gchar *block_dev, GError **error)
+{
+       gboolean ret;
+       gint exit_status = 0;
+       _cleanup_free_ gchar *standard_output = NULL;
+       const gchar *argv[] = { "/usr/bin/pkexec",
+                               "/usr/bin/gnome-multi-writer-probe",
+                               block_dev,
+                               NULL };
+       const gchar *envp[] = { NULL };
+
+       ret = g_spawn_sync (NULL, (gchar **) argv, (gchar **) envp,
+                           G_SPAWN_STDERR_TO_DEV_NULL,
+                           NULL, NULL,
+                           &standard_output, NULL, &exit_status, error);
+       if (!ret)
+               return FALSE;
+       g_strdelimit (standard_output, "\n", '\0');
+       if (exit_status != 0) {
+               g_set_error_literal (error, 1, 0, standard_output);
+               return FALSE;
+       }
+       return TRUE;
+}
+
+/**
  * gmw_copy_thread_cb:
  **/
 static void
@@ -889,6 +923,17 @@ gmw_copy_thread_cb (gpointer data, gpointer user_data)
        if (!g_settings_get_boolean (priv->settings, "enable-verify"))
                gmw_device_set_write_alloc (device, 1.f);
 
+       /* probe the devices */
+       if (g_settings_get_boolean (priv->settings, "enable-probe")) {
+               const gchar *block_dev;
+               gmw_device_set_state (device, GMW_DEVICE_STATE_VERIFY);
+               block_dev = gmw_device_get_block_path (device);
+               if (!gmw_block_device_probe (block_dev, &error)) {
+                       gmw_device_set_error (device, error);
+                       goto out;
+               }
+       }
+
        /* open input stream */
        image_stream = (GInputStream *) g_file_read (priv->image_file, NULL, &error);
        if (image_stream == NULL) {
@@ -918,7 +963,8 @@ out:
        gmw_refresh_in_idle (priv);
        g_idle_add (gmw_refresh_titlebar_idle_cb, priv);
        g_timeout_add_seconds (2, gmw_refresh_in_idle_cb, priv);
-       g_input_stream_close (G_INPUT_STREAM (image_stream), NULL, NULL);
+       if (image_stream != NULL)
+               g_input_stream_close (G_INPUT_STREAM (image_stream), NULL, NULL);
        gmw_copy_done (priv);
 }
 
@@ -1375,6 +1421,9 @@ gmw_settings_clicked_cb (GtkWidget *widget, GmwPrivate *priv)
        if (gtk_widget_get_parent (priv->switch_blank) != NULL)
                g_object_ref (priv->switch_blank);
        gtk_widget_unparent (priv->switch_blank);
+       if (gtk_widget_get_parent (priv->switch_probe) != NULL)
+               g_object_ref (priv->switch_probe);
+       gtk_widget_unparent (priv->switch_probe);
 
        /* show settings */
        pop = gtk_popover_new (widget);
@@ -1395,6 +1444,12 @@ gmw_settings_clicked_cb (GtkWidget *widget, GmwPrivate *priv)
                         gtk_label_new (_("Wipe")),
                         0, 1, 1, 1);
        gtk_grid_attach (GTK_GRID (box), priv->switch_blank, 1, 1, 1, 1);
+       gtk_grid_attach (GTK_GRID (box),
+                        /* TRANSLATORS: a switch label: we check the device
+                         * is actually the size it says it is */
+                        gtk_label_new (_("Probe")),
+                        0, 2, 1, 1);
+       gtk_grid_attach (GTK_GRID (box), priv->switch_probe, 1, 2, 1, 1);
        gtk_container_add (GTK_CONTAINER (pop), box);
        gtk_widget_show_all (pop);
 }
@@ -1823,12 +1878,16 @@ main (int argc, char **argv)
        /* keep these local as they get reparented to the popover */
        priv->switch_verify = gtk_switch_new ();
        priv->switch_blank = gtk_switch_new ();
+       priv->switch_probe = gtk_switch_new ();
        g_settings_bind (priv->settings, "enable-verify",
                         priv->switch_verify, "active",
                         G_SETTINGS_BIND_DEFAULT);
        g_settings_bind (priv->settings, "blank-drive",
                         priv->switch_blank, "active",
                         G_SETTINGS_BIND_DEFAULT);
+       g_settings_bind (priv->settings, "enable-probe",
+                        priv->switch_probe, "active",
+                        G_SETTINGS_BIND_DEFAULT);
 
        /* wait */
        status = g_application_run (G_APPLICATION (priv->application), argc, argv);


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]