Add erase parameter to Block.Format() to zero out device before formatting it
authorDavid Zeuthen <zeuthen@gmail.com>
Mon, 25 Jun 2012 15:38:29 +0000 (11:38 -0400)
committerDavid Zeuthen <zeuthen@gmail.com>
Mon, 25 Jun 2012 15:38:29 +0000 (11:38 -0400)
... and also provide new job properties so it's possible to build a
meaningful UI around it. This makes things like this possible

 http://people.freedesktop.org/~david/gnome-disks-erase-overwrite-option.png
 http://people.freedesktop.org/~david/gnome-disks-long-running-operations.png

Signed-off-by: David Zeuthen <zeuthen@gmail.com>
27 files changed:
data/org.freedesktop.UDisks2.xml
data/org.freedesktop.udisks2.policy.in
doc/udisks2-sections.txt
src/tests/test.c
src/udisksbasejob.c
src/udisksbasejob.h
src/udiskscleanup.c
src/udisksdaemon.c
src/udisksdaemon.h
src/udisksdaemonutil.c
src/udiskslinuxblock.c
src/udiskslinuxdrive.c
src/udiskslinuxdriveata.c
src/udiskslinuxencrypted.c
src/udiskslinuxfilesystem.c
src/udiskslinuxloop.c
src/udiskslinuxpartition.c
src/udiskslinuxpartitiontable.c
src/udiskslinuxswapspace.c
src/udiskssimplejob.c
src/udiskssimplejob.h
src/udisksspawnedjob.c
src/udisksspawnedjob.h
src/udisksthreadedjob.c
src/udisksthreadedjob.h
udisks/udisksclient.c
udisks/udisksclient.h

index fef2b9f..956a921 100644 (file)
     <!--
         Format:
         @type: The type of file system, partition table or other content to format the device with.
-        @options: Options - known options (in addition to <link linkend="udisks-std-options">standard options</link>) includes <parameter>label</parameter> (of type 's'), <parameter>take-ownership</parameter> (of type 'b') and <parameter>encrypt.passphrase</parameter> (of type 's').
+        @options: Options - known options (in addition to <link linkend="udisks-std-options">standard options</link>) includes <parameter>label</parameter> (of type 's'), <parameter>take-ownership</parameter> (of type 'b'), <parameter>encrypt.passphrase</parameter> (of type 's') and <parameter>erase</parameter> (of type 's').
 
         Formats the device with a file system, partition table or
         other well-known content.
         given then a LUKS device is created with the given passphrase
         and the file system is created on the unlocked device. The
         unlocked device will be left open.
+
+        If the option <parameter>erase</parameter> is given then the
+        underlying device will be erased. Valid values include
+        <quote>zero</quote> to write zeroes over the entire device
+        before formatting it.
     -->
     <method name="Format">
       <arg name="type" direction="in" type="s"/>
       things, this can be used to draw a spinner in the user interface
       next to e.g. an icon for the drive or device in question.
 
-      A job <emphasis>may</emphasis> convey progress (if the
-      underlying tool used supports it), see the
-      #org.freedesktop.UDisks2.Job:ExpectedEndTime property.
+      The #org.freedesktop.UDisks2.Job:Operation property is used to
+      convey the type of job currently in progress.
+
+      The user id of the user who started the job is set in the
+      #org.freedesktop.UDisks2.Job:StartedByUID property.
+
+      A job <emphasis>may</emphasis> convey how much progress has been
+      made, see the #org.freedesktop.UDisks2.Job:Progress and
+      #org.freedesktop.UDisks2.Job:ProgressValid properties.
 
       When a job completes, the #org.freedesktop.UDisks2.Job::Completed signal
       is emitted.
       To cancel a job use the org.freedesktop.UDisks2.Job.Cancel()
       method. This will cause the job to complete (with @success set
       to %FALSE) and the D-Bus method used to initiate the operation
-      to return, usually returning the <literal>org.freedesktop.UDisks2.Error.Cancelled</literal> error.
+      to return, usually returning the
+      <literal>org.freedesktop.UDisks2.Error.Cancelled</literal> error.
   -->
   <interface name="org.freedesktop.UDisks2.Job">
 
-    <!-- Progress: How much progress has been made. Values are in the range 0 to 1. -->
+    <!-- Operation:
+         The type of the operation that the job represents.
+
+         Known job operation types include:
+         <variablelist>
+           <varlistentry><term>ata-smart-selftest</term>
+             <listitem><para>SMART self-test operation.</para></listitem></varlistentry>
+           <varlistentry><term>drive-eject</term>
+             <listitem><para>Ejecting the medium from a drive.</para></listitem></varlistentry>
+           <varlistentry><term>encrypted-unlock</term>
+             <listitem><para>Unlocking encrypted device.</para></listitem></varlistentry>
+           <varlistentry><term>encrypted-lock</term>
+             <listitem><para>Locking encrypted device.</para></listitem></varlistentry>
+           <varlistentry><term>encrypted-modify</term>
+             <listitem><para>Modifying encrypted device.</para></listitem></varlistentry>
+           <varlistentry><term>swapspace-start</term>
+             <listitem><para>Starting swapspace.</para></listitem></varlistentry>
+           <varlistentry><term>swapspace-stop</term>
+             <listitem><para>Stopping swapspace.</para></listitem></varlistentry>
+           <varlistentry><term>filesystem-mount</term>
+             <listitem><para>Mounting a filesystem.</para></listitem></varlistentry>
+           <varlistentry><term>filesystem-unmount</term>
+             <listitem><para>Unmounting a filesystem.</para></listitem></varlistentry>
+           <varlistentry><term>filesystem-modify</term>
+             <listitem><para>Modifying a filesystem.</para></listitem></varlistentry>
+           <varlistentry><term>format-erase</term>
+             <listitem><para>Erasing a device.</para></listitem></varlistentry>
+           <varlistentry><term>format-mkfs</term>
+             <listitem><para>Creating a filesystem.</para></listitem></varlistentry>
+           <varlistentry><term>loop-setup</term>
+             <listitem><para>Setting up a loop device.</para></listitem></varlistentry>
+           <varlistentry><term>partition-modify</term>
+             <listitem><para>Modifying a partition.</para></listitem></varlistentry>
+           <varlistentry><term>partition-delete</term>
+             <listitem><para>Deleting a partition.</para></listitem></varlistentry>
+           <varlistentry><term>partition-create</term>
+             <listitem><para>Creating a partition.</para></listitem></varlistentry>
+           <varlistentry><term>cleanup</term>
+             <listitem><para>Cleaning up devices that were removed without being properly unmounted or shut down.</para></listitem></varlistentry>
+         </variablelist>
+         The
+         <link linkend="udisks-client-get-job-description">udisks_client_get_job_description()</link>
+         function can be used to get a localized human readable description.
+    -->
+    <property name="Operation" type="s" access="read"/>
+
+    <!-- Progress:
+         How much progress has been made. Values are in the range 0 to 1.
+
+         Do not use unless #org.freedesktop.UDisks2.Job:ProgressValid is %TRUE.
+    -->
     <property name="Progress" type="d" access="read"/>
+
+    <!-- ProgressValid: Set to %TRUE if the #org.freedesktop.UDisks2.Job:Progress is valid. -->
+    <property name="ProgressValid" type="b" access="read"/>
+
     <!-- StartTime:
 
          The point in time (seconds since the <ulink
          Epoch</ulink>) that the job was started.
     -->
     <property name="StartTime" type="t" access="read"/>
+
     <!-- ExpectedEndTime:
 
          The expected point in time (seconds since the <ulink
     <!-- Objects: The objects that the job is related to, if any. -->
     <property name="Objects" type="ao" access="read"/>
 
+    <!-- StartedByUID:
+         The id of the user who started the job or 0 if started
+         by root or not through udisks.
+    -->
+    <property name="StartedByUID" type="u" access="read"/>
+
     <!--
         Cancel:
         @options: Options (currently unused except for <link linkend="udisks-std-options">standard options</link>).
index 39c86f2..b7802bf 100644 (file)
     </defaults>
   </action>
 
+  <!-- ###################################################################### -->
+  <!-- Canceling jobs -->
+
+  <!-- Cancel own job -->
+  <action id="org.freedesktop.udisks2.cancel-job">
+    <_description>Cancel job</_description>
+    <_message>Authentication is required to cancel a job</_message>
+    <defaults>
+      <allow_any>auth_admin</allow_any>
+      <allow_inactive>auth_admin</allow_inactive>
+      <allow_active>yes</allow_active>
+    </defaults>
+  </action>
+
+  <!-- Cancel own job -->
+  <action id="org.freedesktop.udisks2.cancel-job-other-user">
+    <_description>Cancel job started by another user</_description>
+    <_message>Authentication is required to cancel a job started by another user</_message>
+    <defaults>
+      <allow_any>auth_admin</allow_any>
+      <allow_inactive>auth_admin</allow_inactive>
+      <allow_active>auth_admin_keep</allow_active>
+    </defaults>
+  </action>
+
 </policyconfig>
index 1ac10b6..9871c1f 100644 (file)
@@ -47,6 +47,7 @@ udisks_client_get_partition_table
 udisks_client_get_loop_for_block
 udisks_client_get_partitions
 udisks_client_get_jobs_for_object
+udisks_client_get_job_description
 <SUBSECTION>
 udisks_client_get_drive_info
 udisks_client_get_partition_info
index 1855deb..7f25ecb 100644 (file)
@@ -69,7 +69,7 @@ test_spawned_job_successful (void)
 {
   UDisksSpawnedJob *job;
 
-  job = udisks_spawned_job_new ("/bin/true", NULL, getuid (), geteuid (), NULL);
+  job = udisks_spawned_job_new ("/bin/true", NULL, getuid (), geteuid (), NULL, NULL);
   _g_assert_signal_received (job, "completed", G_CALLBACK (on_completed_expect_success), NULL);
   g_object_unref (job);
 }
@@ -81,7 +81,7 @@ test_spawned_job_failure (void)
 {
   UDisksSpawnedJob *job;
 
-  job = udisks_spawned_job_new ("/bin/false", NULL, getuid (), geteuid (), NULL);
+  job = udisks_spawned_job_new ("/bin/false", NULL, getuid (), geteuid (), NULL, NULL);
   _g_assert_signal_received (job, "completed", G_CALLBACK (on_completed_expect_failure),
                              "Command-line `/bin/false' exited with non-zero exit status 1: ");
   g_object_unref (job);
@@ -94,7 +94,7 @@ test_spawned_job_missing_program (void)
 {
   UDisksSpawnedJob *job;
 
-  job = udisks_spawned_job_new ("/path/to/unknown/file", NULL, getuid (), geteuid (), NULL);
+  job = udisks_spawned_job_new ("/path/to/unknown/file", NULL, getuid (), geteuid (), NULL, NULL);
   _g_assert_signal_received (job, "completed", G_CALLBACK (on_completed_expect_failure),
                              "Error spawning command-line `/path/to/unknown/file': Failed to execute child process \"/path/to/unknown/file\" (No such file or directory) (g-exec-error-quark, 8)");
   g_object_unref (job);
@@ -110,7 +110,7 @@ test_spawned_job_cancelled_at_start (void)
 
   cancellable = g_cancellable_new ();
   g_cancellable_cancel (cancellable);
-  job = udisks_spawned_job_new ("/bin/true", NULL, getuid (), geteuid (), cancellable);
+  job = udisks_spawned_job_new ("/bin/true", NULL, getuid (), geteuid (), NULL, cancellable);
   _g_assert_signal_received (job, "completed", G_CALLBACK (on_completed_expect_failure),
                              "Operation was cancelled (g-io-error-quark, 19)");
   g_object_unref (job);
@@ -135,7 +135,7 @@ test_spawned_job_cancelled_midway (void)
   GCancellable *cancellable;
 
   cancellable = g_cancellable_new ();
-  job = udisks_spawned_job_new ("/bin/sleep 0.5", NULL, getuid (), geteuid (), cancellable);
+  job = udisks_spawned_job_new ("/bin/sleep 0.5", NULL, getuid (), geteuid (), NULL, cancellable);
   g_timeout_add (10, on_timeout, cancellable); /* 10 msec */
   g_main_loop_run (loop);
   _g_assert_signal_received (job, "completed", G_CALLBACK (on_completed_expect_failure),
@@ -167,7 +167,7 @@ test_spawned_job_override_signal_handler (void)
   UDisksSpawnedJob *job;
   gboolean handler_ran;
 
-  job = udisks_spawned_job_new ("/path/to/unknown/file", NULL, getuid (), geteuid (), NULL /* GCancellable */);
+  job = udisks_spawned_job_new ("/path/to/unknown/file", NULL, getuid (), geteuid (), NULL, NULL /* GCancellable */);
   handler_ran = FALSE;
   g_signal_connect (job, "spawned-job-completed", G_CALLBACK (on_spawned_job_completed), &handler_ran);
   _g_assert_signal_received (job, "completed", G_CALLBACK (on_completed_expect_failure),
@@ -183,7 +183,7 @@ test_spawned_job_premature_termination (void)
 {
   UDisksSpawnedJob *job;
 
-  job = udisks_spawned_job_new ("/bin/sleep 1000", NULL, getuid (), geteuid (), NULL /* GCancellable */);
+  job = udisks_spawned_job_new ("/bin/sleep 1000", NULL, getuid (), geteuid (), NULL, NULL /* GCancellable */);
   g_object_unref (job);
 }
 
@@ -214,7 +214,7 @@ test_spawned_job_read_stdout (void)
   gchar *s;
 
   s = g_strdup_printf (UDISKS_TEST_DIR "/udisks-test-helper 0");
-  job = udisks_spawned_job_new (s, NULL, getuid (), geteuid (), NULL);
+  job = udisks_spawned_job_new (s, NULL, getuid (), geteuid (), NULL, NULL);
   _g_assert_signal_received (job, "spawned-job-completed", G_CALLBACK (read_stdout_on_spawned_job_completed), NULL);
   g_object_unref (job);
   g_free (s);
@@ -247,7 +247,7 @@ test_spawned_job_read_stderr (void)
   gchar *s;
 
   s = g_strdup_printf (UDISKS_TEST_DIR "/udisks-test-helper 1");
-  job = udisks_spawned_job_new (s, NULL, getuid (), geteuid (), NULL);
+  job = udisks_spawned_job_new (s, NULL, getuid (), geteuid (), NULL, NULL);
   _g_assert_signal_received (job, "spawned-job-completed", G_CALLBACK (read_stderr_on_spawned_job_completed), NULL);
   g_object_unref (job);
   g_free (s);
@@ -278,14 +278,14 @@ test_spawned_job_exit_status (void)
   gchar *s;
 
   s = g_strdup_printf (UDISKS_TEST_DIR "/udisks-test-helper 2");
-  job = udisks_spawned_job_new (s, NULL, getuid (), geteuid (), NULL);
+  job = udisks_spawned_job_new (s, NULL, getuid (), geteuid (), NULL, NULL);
   _g_assert_signal_received (job, "spawned-job-completed", G_CALLBACK (exit_status_on_spawned_job_completed),
                              GINT_TO_POINTER (1));
   g_object_unref (job);
   g_free (s);
 
   s = g_strdup_printf (UDISKS_TEST_DIR "/udisks-test-helper 3");
-  job = udisks_spawned_job_new (s, NULL, getuid (), geteuid (), NULL);
+  job = udisks_spawned_job_new (s, NULL, getuid (), geteuid (), NULL, NULL);
   _g_assert_signal_received (job, "spawned-job-completed", G_CALLBACK (exit_status_on_spawned_job_completed),
                              GINT_TO_POINTER (2));
   g_object_unref (job);
@@ -301,7 +301,7 @@ test_spawned_job_abnormal_termination (void)
   gchar *s;
 
   s = g_strdup_printf (UDISKS_TEST_DIR "/udisks-test-helper 4");
-  job = udisks_spawned_job_new (s, NULL, getuid (), geteuid (), NULL);
+  job = udisks_spawned_job_new (s, NULL, getuid (), geteuid (), NULL, NULL);
   _g_assert_signal_received (job, "completed", G_CALLBACK (on_completed_expect_failure),
                              "Command-line `./udisks-test-helper 4' was signaled with signal SIGSEGV (11): "
                              "OK, deliberately causing a segfault\n");
@@ -309,7 +309,7 @@ test_spawned_job_abnormal_termination (void)
   g_free (s);
 
   s = g_strdup_printf (UDISKS_TEST_DIR "/udisks-test-helper 5");
-  job = udisks_spawned_job_new (s, NULL, getuid (), geteuid (), NULL);
+  job = udisks_spawned_job_new (s, NULL, getuid (), geteuid (), NULL, NULL);
   _g_assert_signal_received (job, "completed", G_CALLBACK (on_completed_expect_failure),
                              "Command-line `./udisks-test-helper 5' was signaled with signal SIGABRT (6): "
                              "OK, deliberately abort()'ing\n");
@@ -350,7 +350,7 @@ test_spawned_job_binary_output (void)
   gchar *s;
 
   s = g_strdup_printf (UDISKS_TEST_DIR "/udisks-test-helper 6");
-  job = udisks_spawned_job_new (s, NULL, getuid (), geteuid (), NULL);
+  job = udisks_spawned_job_new (s, NULL, getuid (), geteuid (), NULL, NULL);
   _g_assert_signal_received (job, "spawned-job-completed", G_CALLBACK (binary_output_on_spawned_job_completed), NULL);
   g_object_unref (job);
   g_free (s);
@@ -381,7 +381,7 @@ test_spawned_job_input_string (void)
   gchar *s;
 
   s = g_strdup_printf (UDISKS_TEST_DIR "/udisks-test-helper 7");
-  job = udisks_spawned_job_new (s, "foobar", getuid (), geteuid (), NULL);
+  job = udisks_spawned_job_new (s, "foobar", getuid (), geteuid (), NULL, NULL);
   _g_assert_signal_received (job, "spawned-job-completed", G_CALLBACK (input_string_on_spawned_job_completed), NULL);
   g_object_unref (job);
   g_free (s);
@@ -404,7 +404,7 @@ test_threaded_job_successful (void)
 {
   UDisksThreadedJob *job;
 
-  job = udisks_threaded_job_new (threaded_job_successful_func, NULL, NULL, NULL);
+  job = udisks_threaded_job_new (threaded_job_successful_func, NULL, NULL, NULL, NULL);
   _g_assert_signal_received (job, "completed", G_CALLBACK (on_completed_expect_success), NULL);
   g_object_unref (job);
 }
@@ -430,7 +430,7 @@ test_threaded_job_failure (void)
 {
   UDisksThreadedJob *job;
 
-  job = udisks_threaded_job_new (threaded_job_failure_func, NULL, NULL, NULL);
+  job = udisks_threaded_job_new (threaded_job_failure_func, NULL, NULL, NULL, NULL);
   _g_assert_signal_received (job, "completed", G_CALLBACK (on_completed_expect_failure),
                              "Threaded job failed with error: some error (g-key-file-error-quark, 5)");
   g_object_unref (job);
@@ -446,7 +446,7 @@ test_threaded_job_cancelled_at_start (void)
 
   cancellable = g_cancellable_new ();
   g_cancellable_cancel (cancellable);
-  job = udisks_threaded_job_new (threaded_job_successful_func, NULL, NULL, cancellable);
+  job = udisks_threaded_job_new (threaded_job_successful_func, NULL, NULL, NULL, cancellable);
   _g_assert_signal_received (job, "completed", G_CALLBACK (on_completed_expect_failure),
                              "Threaded job failed with error: Operation was cancelled (g-io-error-quark, 19)");
   g_object_unref (job);
@@ -485,7 +485,7 @@ test_threaded_job_cancelled_midway (void)
 
   cancellable = g_cancellable_new ();
   count = 0;
-  job = udisks_threaded_job_new (threaded_job_sleep_until_cancelled, &count, NULL, cancellable);
+  job = udisks_threaded_job_new (threaded_job_sleep_until_cancelled, &count, NULL, NULL, cancellable);
   g_timeout_add (10, on_timeout, cancellable); /* 10 msec */
   g_main_loop_run (loop);
   _g_assert_signal_received (job, "completed", G_CALLBACK (on_completed_expect_failure),
@@ -518,7 +518,7 @@ test_threaded_job_override_signal_handler (void)
   UDisksThreadedJob *job;
   gboolean handler_ran;
 
-  job = udisks_threaded_job_new (threaded_job_failure_func, NULL, NULL, NULL);
+  job = udisks_threaded_job_new (threaded_job_failure_func, NULL, NULL, NULL, NULL);
   handler_ran = FALSE;
   g_signal_connect (job, "threaded-job-completed", G_CALLBACK (on_threaded_job_completed), &handler_ran);
   _g_assert_signal_received (job, "completed", G_CALLBACK (on_completed_expect_failure),
index d298792..e113b67 100644 (file)
@@ -25,6 +25,8 @@
 #include <sys/wait.h>
 
 #include "udisksbasejob.h"
+#include "udisksdaemon.h"
+#include "udisksdaemonutil.h"
 #include "udisks-daemon-marshal.h"
 
 /**
@@ -38,6 +40,7 @@
 struct _UDisksBaseJobPrivate
 {
   GCancellable *cancellable;
+  UDisksDaemon *daemon;
 };
 
 static void job_iface_init (UDisksJobIface *iface);
@@ -45,6 +48,7 @@ static void job_iface_init (UDisksJobIface *iface);
 enum
 {
   PROP_0,
+  PROP_DAEMON,
   PROP_CANCELLABLE,
 };
 
@@ -76,6 +80,10 @@ udisks_base_job_get_property (GObject    *object,
 
   switch (prop_id)
     {
+    case PROP_DAEMON:
+      g_value_set_object (value, udisks_base_job_get_daemon (job));
+      break;
+
     case PROP_CANCELLABLE:
       g_value_set_object (value, job->priv->cancellable);
       break;
@@ -96,6 +104,12 @@ udisks_base_job_set_property (GObject      *object,
 
   switch (prop_id)
     {
+    case PROP_DAEMON:
+      g_assert (job->priv->daemon == NULL);
+      /* we don't take a reference to the daemon */
+      job->priv->daemon = g_value_get_object (value);
+      break;
+
     case PROP_CANCELLABLE:
       g_assert (job->priv->cancellable == NULL);
       job->priv->cancellable = g_value_dup_object (value);
@@ -126,7 +140,12 @@ udisks_base_job_constructed (GObject *object)
 static void
 udisks_base_job_init (UDisksBaseJob *job)
 {
+  gint64 now_usec;
+
   job->priv = G_TYPE_INSTANCE_GET_PRIVATE (job, UDISKS_TYPE_BASE_JOB, UDisksBaseJobPrivate);
+
+  now_usec = g_get_real_time ();
+  udisks_job_set_start_time (UDISKS_JOB (job), now_usec / G_USEC_PER_SEC);
 }
 
 static void
@@ -141,6 +160,22 @@ udisks_base_job_class_init (UDisksBaseJobClass *klass)
   gobject_class->get_property = udisks_base_job_get_property;
 
   /**
+   * UDisksBaseJob:daemon:
+   *
+   * The #UDisksDaemon the object is for.
+   */
+  g_object_class_install_property (gobject_class,
+                                   PROP_DAEMON,
+                                   g_param_spec_object ("daemon",
+                                                        "Daemon",
+                                                        "The daemon the object is for",
+                                                        UDISKS_TYPE_DAEMON,
+                                                        G_PARAM_READABLE |
+                                                        G_PARAM_WRITABLE |
+                                                        G_PARAM_CONSTRUCT_ONLY |
+                                                        G_PARAM_STATIC_STRINGS));
+
+  /**
    * UDisksBaseJob:cancellable:
    *
    * The #GCancellable to use.
@@ -179,6 +214,23 @@ udisks_base_job_get_cancellable  (UDisksBaseJob  *job)
 /* ---------------------------------------------------------------------------------------------------- */
 
 /**
+ * udisks_base_job_get_daemon:
+ * @job: A #UDisksBaseJob.
+ *
+ * Gets the #UDisksDaemon for @job.
+ *
+ * Returns: A #UDisksDaemon. Do not free, the object belongs to @job.
+ */
+UDisksDaemon *
+udisks_base_job_get_daemon  (UDisksBaseJob  *job)
+{
+  g_return_val_if_fail (UDISKS_IS_BASE_JOB (job), NULL);
+  return job->priv->daemon;
+}
+
+/* ---------------------------------------------------------------------------------------------------- */
+
+/**
  * udisks_base_job_add_object:
  * @job: A #UDisksBaseJob.
  * @object: A #UDisksObject.
@@ -264,11 +316,51 @@ udisks_base_job_remove_object (UDisksBaseJob  *job,
 /* ---------------------------------------------------------------------------------------------------- */
 
 static gboolean
-handle_cancel (UDisksJob              *object,
+handle_cancel (UDisksJob              *_job,
                GDBusMethodInvocation  *invocation,
                GVariant               *options)
 {
-  UDisksBaseJob *job = UDISKS_BASE_JOB (object);
+  UDisksBaseJob *job = UDISKS_BASE_JOB (_job);
+  UDisksObject *object = NULL;
+  const gchar *action_id;
+  const gchar *message;
+  uid_t caller_uid;
+  gid_t caller_gid;
+  GError *error = NULL;
+
+  object = udisks_daemon_util_dup_object (job, &error);
+  if (object == NULL)
+    {
+      g_dbus_method_invocation_take_error (invocation, error);
+      goto out;
+    }
+
+  if (!udisks_daemon_util_get_caller_uid_sync (job->priv->daemon,
+                                               invocation,
+                                               NULL /* GCancellable */,
+                                               &caller_uid,
+                                               &caller_gid,
+                                               NULL,
+                                               &error))
+    {
+      g_dbus_method_invocation_take_error (invocation, error);
+      goto out;
+    }
+
+  /* Translators: Shown in authentication dialog when canceling a job.
+   */
+  message = N_("Authentication is required to cancel a job");
+  action_id = "org.freedesktop.udisks2.cancel-job";
+  if (caller_uid != udisks_job_get_started_by_uid (UDISKS_JOB (job)))
+    action_id = "org.freedesktop.udisks2.cancel-job-other-user";
+
+  if (!udisks_daemon_util_check_authorization_sync (job->priv->daemon,
+                                                    object,
+                                                    action_id,
+                                                    options,
+                                                    message,
+                                                    invocation))
+    goto out;
 
   if (g_cancellable_is_cancelled (job->priv->cancellable))
     {
@@ -280,9 +372,11 @@ handle_cancel (UDisksJob              *object,
   else
     {
       g_cancellable_cancel (job->priv->cancellable);
-      udisks_job_complete_cancel (object, invocation);
+      udisks_job_complete_cancel (UDISKS_JOB (job), invocation);
     }
 
+ out:
+  g_clear_object (&object);
   return TRUE;
 }
 
index 35f8495..c78eb30 100644 (file)
@@ -62,7 +62,9 @@ struct _UDisksBaseJobClass
 };
 
 GType              udisks_base_job_get_type         (void) G_GNUC_CONST;
+UDisksDaemon      *udisks_base_job_get_daemon       (UDisksBaseJob  *job);
 GCancellable      *udisks_base_job_get_cancellable  (UDisksBaseJob  *job);
+
 void               udisks_base_job_add_object       (UDisksBaseJob  *job,
                                                      UDisksObject   *object);
 void               udisks_base_job_remove_object    (UDisksBaseJob  *job,
index 4ec1fd7..308cc21 100644 (file)
@@ -677,6 +677,7 @@ udisks_cleanup_check_mounted_fs_entry (UDisksCleanup  *cleanup,
           /* right now -l is the only way to "force unmount" file systems... */
           if (!udisks_daemon_launch_spawned_job_sync (cleanup->daemon,
                                                       NULL, /* UDisksObject */
+                                                      "cleanup", 0, /* StartedByUID */
                                                       NULL, /* GCancellable */
                                                       0,    /* uid_t run_as_uid */
                                                       0,    /* uid_t run_as_euid */
@@ -1168,6 +1169,7 @@ udisks_cleanup_check_unlocked_luks_entry (UDisksCleanup  *cleanup,
           escaped_device_file = udisks_daemon_util_escape_and_quote (device_file_cleartext);
           if (!udisks_daemon_launch_spawned_job_sync (cleanup->daemon,
                                                       NULL, /* UDisksObject */
+                                                      "cleanup", 0, /* StartedByUID */
                                                       NULL, /* GCancellable */
                                                       0,    /* uid_t run_as_uid */
                                                       0,    /* uid_t run_as_euid */
index 2929ee7..4042412 100644 (file)
@@ -518,6 +518,8 @@ static guint job_id = 0;
 UDisksBaseJob *
 udisks_daemon_launch_simple_job (UDisksDaemon    *daemon,
                                  UDisksObject    *object,
+                                 const gchar     *job_operation,
+                                 uid_t            job_started_by_uid,
                                  GCancellable    *cancellable)
 {
   UDisksSimpleJob *job;
@@ -526,7 +528,7 @@ udisks_daemon_launch_simple_job (UDisksDaemon    *daemon,
 
   g_return_val_if_fail (UDISKS_IS_DAEMON (daemon), NULL);
 
-  job = udisks_simple_job_new (cancellable);
+  job = udisks_simple_job_new (daemon, cancellable);
   if (object != NULL)
     udisks_base_job_add_object (UDISKS_BASE_JOB (job), object);
 
@@ -536,6 +538,9 @@ udisks_daemon_launch_simple_job (UDisksDaemon    *daemon,
   udisks_object_skeleton_set_job (job_object, UDISKS_JOB (job));
   g_free (job_object_path);
 
+  udisks_job_set_operation (UDISKS_JOB (job), job_operation);
+  udisks_job_set_started_by_uid (UDISKS_JOB (job), job_started_by_uid);
+
   g_dbus_object_manager_server_export (daemon->object_manager, G_DBUS_OBJECT_SKELETON (job_object));
   g_signal_connect_after (job,
                           "completed",
@@ -575,6 +580,8 @@ udisks_daemon_launch_simple_job (UDisksDaemon    *daemon,
 UDisksBaseJob *
 udisks_daemon_launch_threaded_job  (UDisksDaemon    *daemon,
                                     UDisksObject    *object,
+                                    const gchar     *job_operation,
+                                    uid_t            job_started_by_uid,
                                     UDisksThreadedJobFunc job_func,
                                     gpointer         user_data,
                                     GDestroyNotify   user_data_free_func,
@@ -590,6 +597,7 @@ udisks_daemon_launch_threaded_job  (UDisksDaemon    *daemon,
   job = udisks_threaded_job_new (job_func,
                                  user_data,
                                  user_data_free_func,
+                                 daemon,
                                  cancellable);
   if (object != NULL)
     udisks_base_job_add_object (UDISKS_BASE_JOB (job), object);
@@ -600,6 +608,9 @@ udisks_daemon_launch_threaded_job  (UDisksDaemon    *daemon,
   udisks_object_skeleton_set_job (job_object, UDISKS_JOB (job));
   g_free (job_object_path);
 
+  udisks_job_set_operation (UDISKS_JOB (job), job_operation);
+  udisks_job_set_started_by_uid (UDISKS_JOB (job), job_started_by_uid);
+
   g_dbus_object_manager_server_export (daemon->object_manager, G_DBUS_OBJECT_SKELETON (job_object));
   g_signal_connect_after (job,
                           "completed",
@@ -638,6 +649,8 @@ udisks_daemon_launch_threaded_job  (UDisksDaemon    *daemon,
 UDisksBaseJob *
 udisks_daemon_launch_spawned_job (UDisksDaemon    *daemon,
                                   UDisksObject    *object,
+                                  const gchar     *job_operation,
+                                  uid_t            job_started_by_uid,
                                   GCancellable    *cancellable,
                                   uid_t            run_as_uid,
                                   uid_t            run_as_euid,
@@ -658,7 +671,7 @@ udisks_daemon_launch_spawned_job (UDisksDaemon    *daemon,
   va_start (var_args, command_line_format);
   command_line = g_strdup_vprintf (command_line_format, var_args);
   va_end (var_args);
-  job = udisks_spawned_job_new (command_line, input_string, run_as_uid, run_as_euid, cancellable);
+  job = udisks_spawned_job_new (command_line, input_string, run_as_uid, run_as_euid, daemon, cancellable);
   g_free (command_line);
 
   if (object != NULL)
@@ -670,6 +683,9 @@ udisks_daemon_launch_spawned_job (UDisksDaemon    *daemon,
   udisks_object_skeleton_set_job (job_object, UDISKS_JOB (job));
   g_free (job_object_path);
 
+  udisks_job_set_operation (UDISKS_JOB (job), job_operation);
+  udisks_job_set_started_by_uid (UDISKS_JOB (job), job_started_by_uid);
+
   g_dbus_object_manager_server_export (daemon->object_manager, G_DBUS_OBJECT_SKELETON (job_object));
   g_signal_connect_after (job,
                           "completed",
@@ -736,6 +752,8 @@ spawned_job_sync_on_completed (UDisksJob    *job,
 gboolean
 udisks_daemon_launch_spawned_job_sync (UDisksDaemon    *daemon,
                                        UDisksObject    *object,
+                                       const gchar     *job_operation,
+                                       uid_t            job_started_by_uid,
                                        GCancellable    *cancellable,
                                        uid_t            run_as_uid,
                                        uid_t            run_as_euid,
@@ -766,6 +784,8 @@ udisks_daemon_launch_spawned_job_sync (UDisksDaemon    *daemon,
   va_end (var_args);
   job = udisks_daemon_launch_spawned_job (daemon,
                                           object,
+                                          job_operation,
+                                          job_started_by_uid,
                                           cancellable,
                                           run_as_uid,
                                           run_as_euid,
index f0ad422..47ac61e 100644 (file)
@@ -76,17 +76,23 @@ UDisksObject             *udisks_daemon_find_object           (UDisksDaemon
 
 UDisksBaseJob            *udisks_daemon_launch_simple_job     (UDisksDaemon    *daemon,
                                                                UDisksObject    *object,
+                                                               const gchar     *job_operation,
+                                                               uid_t            job_started_by_uid,
                                                                GCancellable    *cancellable);
 UDisksBaseJob            *udisks_daemon_launch_spawned_job    (UDisksDaemon    *daemon,
                                                                UDisksObject    *object,
+                                                               const gchar     *job_operation,
+                                                               uid_t            job_started_by_uid,
                                                                GCancellable    *cancellable,
                                                                uid_t            run_as_uid,
                                                                uid_t            run_as_euid,
                                                                const gchar     *input_string,
                                                                const gchar     *command_line_format,
-                                                               ...) G_GNUC_PRINTF (7, 8);
+                                                               ...) G_GNUC_PRINTF (9, 10);
 gboolean                  udisks_daemon_launch_spawned_job_sync (UDisksDaemon    *daemon,
                                                                  UDisksObject    *object,
+                                                                 const gchar     *job_operation,
+                                                                 uid_t            job_started_by_uid,
                                                                  GCancellable    *cancellable,
                                                                  uid_t            run_as_uid,
                                                                  uid_t            run_as_euid,
@@ -94,9 +100,11 @@ gboolean                  udisks_daemon_launch_spawned_job_sync (UDisksDaemon
                                                                  gchar          **out_message,
                                                                  const gchar     *input_string,
                                                                  const gchar     *command_line_format,
-                                                                 ...) G_GNUC_PRINTF (9, 10);
+                                                                 ...) G_GNUC_PRINTF (11, 12);
 UDisksBaseJob            *udisks_daemon_launch_threaded_job   (UDisksDaemon    *daemon,
                                                                UDisksObject    *object,
+                                                               const gchar     *job_operation,
+                                                               uid_t            job_started_by_uid,
                                                                UDisksThreadedJobFunc job_func,
                                                                gpointer         user_data,
                                                                GDestroyNotify   user_data_free_func,
index ff50fba..06982d1 100644 (file)
@@ -20,6 +20,7 @@
 
 #include "config.h"
 #include <glib/gi18n-lib.h>
+#include <glib/gstdio.h>
 
 #include <stdio.h>
 
index ac1df48..2948050 100644 (file)
@@ -51,6 +51,8 @@
 #include "udiskscrypttabmonitor.h"
 #include "udiskscrypttabentry.h"
 #include "udisksdaemonutil.h"
+#include "udisksbasejob.h"
+#include "udiskssimplejob.h"
 
 /**
  * SECTION:udiskslinuxblock
@@ -1717,6 +1719,112 @@ wait_for_luks_cleartext (UDisksDaemon *daemon,
 
 /* ---------------------------------------------------------------------------------------------------- */
 
+#define ERASE_SIZE (1 * 1024*1024)
+
+static gboolean
+erase_device (UDisksBlock  *block,
+              UDisksObject *object,
+              UDisksDaemon *daemon,
+              uid_t         caller_uid,
+              const gchar  *erase_type,
+              GError      **error)
+{
+  gboolean ret = FALSE;
+  const gchar *device_file = NULL;
+  UDisksBaseJob *job = NULL;
+  gint fd = -1;
+  guint64 size;
+  guint64 pos;
+  guchar *buf = NULL;
+  gint64 time_of_last_signal;
+  GError *local_error = NULL;
+
+  if (g_strcmp0 (erase_type, "zero") != 0)
+    {
+      g_set_error (&local_error, UDISKS_ERROR, UDISKS_ERROR_FAILED,
+                   "Unknown or unsupported erase type `%s'",
+                   erase_type);
+      goto out;
+    }
+
+  device_file = udisks_block_get_device (block);
+  fd = open (device_file, O_WRONLY | O_SYNC | O_EXCL);
+  if (fd == -1)
+    {
+      g_set_error (&local_error, UDISKS_ERROR, UDISKS_ERROR_FAILED,
+                   "Error opening device %s: %m", device_file);
+      goto out;
+    }
+
+  job = udisks_daemon_launch_simple_job (daemon, object, "format-erase", caller_uid, NULL);
+  udisks_job_set_progress_valid (UDISKS_JOB (job), TRUE);
+
+  if (ioctl (fd, BLKGETSIZE64, &size) != 0)
+    {
+      g_set_error (&local_error, UDISKS_ERROR, UDISKS_ERROR_FAILED,
+                   "Error doing BLKGETSIZE64 iotctl on %s: %m", device_file);
+      goto out;
+    }
+
+  buf = g_new0 (guchar, ERASE_SIZE);
+  pos = 0;
+  time_of_last_signal = g_get_monotonic_time ();
+  while (pos < size)
+    {
+      size_t to_write;
+      ssize_t num_written;
+      gint64 now;
+
+      to_write = MIN (size - pos, ERASE_SIZE);
+    again:
+      num_written = write (fd, buf, to_write);
+      if (num_written == -1 || num_written == 0)
+        {
+          if (errno == EINTR)
+            goto again;
+          g_set_error (&local_error, UDISKS_ERROR, UDISKS_ERROR_FAILED,
+                       "Error writing %d bytes to %s: %m",
+                       (gint) to_write, device_file);
+          goto out;
+        }
+      pos += num_written;
+
+      if (g_cancellable_is_cancelled (udisks_base_job_get_cancellable (job)))
+        {
+          g_set_error (&local_error, UDISKS_ERROR, UDISKS_ERROR_CANCELLED,
+                       "Job was canceled");
+          goto out;
+        }
+
+      /* only emit D-Bus signal at most once a second */
+      now = g_get_monotonic_time ();
+      if (now - time_of_last_signal > G_USEC_PER_SEC)
+        {
+          /* TODO: estimation etc. */
+          udisks_job_set_progress (UDISKS_JOB (job), ((gdouble) pos) / size);
+          time_of_last_signal = now;
+        }
+    }
+
+  ret = TRUE;
+
+ out:
+  if (job != NULL)
+    {
+      if (local_error != NULL)
+        udisks_simple_job_complete (UDISKS_SIMPLE_JOB (job), FALSE, local_error->message);
+      else
+        udisks_simple_job_complete (UDISKS_SIMPLE_JOB (job), TRUE, "");
+    }
+  g_propagate_error (error, local_error);
+  g_free (buf);
+  if (fd != -1)
+    close (fd);
+  return ret;
+}
+
+/* ---------------------------------------------------------------------------------------------------- */
+
 static gboolean
 handle_format (UDisksBlock           *block,
                GDBusMethodInvocation *invocation,
@@ -1745,6 +1853,7 @@ handle_format (UDisksBlock           *block,
   pid_t caller_pid;
   gboolean take_ownership = FALSE;
   gchar *encrypt_passphrase = NULL;
+  gchar *erase_type = NULL;
   gchar *mapped_name = NULL;
   const gchar *label = NULL;
   gchar *escaped_device = NULL;
@@ -1824,6 +1933,7 @@ handle_format (UDisksBlock           *block,
 
   g_variant_lookup (options, "take-ownership", "b", &take_ownership);
   g_variant_lookup (options, "encrypt.passphrase", "s", &encrypt_passphrase);
+  g_variant_lookup (options, "erase", "s", &erase_type);
 
   escaped_device = udisks_daemon_util_escape_and_quote (udisks_block_get_device (block));
 
@@ -1832,6 +1942,7 @@ handle_format (UDisksBlock           *block,
   wait_data->object = object;
   if (!udisks_daemon_launch_spawned_job_sync (daemon,
                                               object,
+                                              "format-erase", caller_uid,
                                               NULL, /* cancellable */
                                               0,    /* uid_t run_as_uid */
                                               0,    /* uid_t run_as_euid */
@@ -1861,6 +1972,17 @@ handle_format (UDisksBlock           *block,
       goto out;
     }
 
+  /* Erase the device, if requested */
+  if (erase_type != NULL)
+    {
+      if (!erase_device (block, object, daemon, caller_uid, erase_type, &error))
+        {
+          g_prefix_error (&error, "Error erasing device: ");
+          g_dbus_method_invocation_take_error (invocation, error);
+          goto out;
+        }
+    }
+
   /* And now create the desired filesystem */
   wait_data->type = type;
 
@@ -1869,6 +1991,7 @@ handle_format (UDisksBlock           *block,
       /* Create it */
       if (!udisks_daemon_launch_spawned_job_sync (daemon,
                                                   object,
+                                                  "format-mkfs", caller_uid,
                                                   NULL, /* cancellable */
                                                   0,    /* uid_t run_as_uid */
                                                   0,    /* uid_t run_as_euid */
@@ -1904,6 +2027,7 @@ handle_format (UDisksBlock           *block,
       mapped_name = g_strdup_printf ("luks-%s", udisks_block_get_id_uuid (block));
       if (!udisks_daemon_launch_spawned_job_sync (daemon,
                                                   object,
+                                                  "format-mkfs", caller_uid,
                                                   NULL, /* cancellable */
                                                   0,    /* uid_t run_as_uid */
                                                   0,    /* uid_t run_as_euid */
@@ -1982,6 +2106,7 @@ handle_format (UDisksBlock           *block,
   g_free (tmp);
   if (!udisks_daemon_launch_spawned_job_sync (daemon,
                                               object_to_mkfs,
+                                              "format-mkfs", caller_uid,
                                               NULL, /* cancellable */
                                               0,    /* uid_t run_as_uid */
                                               0,    /* uid_t run_as_euid */
@@ -2096,6 +2221,7 @@ handle_format (UDisksBlock           *block,
   g_free (escaped_device);
   g_free (mapped_name);
   g_free (command);
+  g_free (erase_type);
   g_free (encrypt_passphrase);
   g_clear_object (&cleartext_object);
   g_clear_object (&cleartext_block);
index 5c7eba3..c7a81d7 100644 (file)
@@ -894,6 +894,8 @@ handle_eject (UDisksDrive           *_drive,
   gchar *error_message = NULL;
   GError *error = NULL;
   gchar *escaped_device = NULL;
+  uid_t caller_uid;
+  gid_t caller_gid;
   pid_t caller_pid;
 
   object = udisks_daemon_util_dup_object (drive, &error);
@@ -935,6 +937,20 @@ handle_eject (UDisksDrive           *_drive,
       goto out;
     }
 
+  error = NULL;
+  if (!udisks_daemon_util_get_caller_uid_sync (daemon,
+                                               invocation,
+                                               NULL /* GCancellable */,
+                                               &caller_uid,
+                                               &caller_gid,
+                                               NULL,
+                                               &error))
+    {
+      g_dbus_method_invocation_return_gerror (invocation, error);
+      g_error_free (error);
+      goto out;
+    }
+
   /* Translators: Shown in authentication dialog when the user
    * requests ejecting media from a drive.
    *
@@ -965,6 +981,7 @@ handle_eject (UDisksDrive           *_drive,
 
   if (!udisks_daemon_launch_spawned_job_sync (daemon,
                                               UDISKS_OBJECT (object),
+                                              "drive-eject", caller_uid,
                                               NULL, /* GCancellable */
                                               0,    /* uid_t run_as_uid */
                                               0,    /* uid_t run_as_euid */
index d93a550..bbebbfb 100644 (file)
@@ -872,10 +872,14 @@ selftest_job_func (UDisksThreadedJob  *job,
   if (object == NULL)
     goto out;
 
+  udisks_job_set_progress_valid (UDISKS_JOB (job), TRUE);
+  udisks_job_set_progress (UDISKS_JOB (job), 0.0);
+
   while (TRUE)
     {
       gboolean still_in_progress;
       GPollFD poll_fd;
+      gdouble progress;
 
       if (!udisks_linux_drive_ata_refresh_smart_sync (drive,
                                                       FALSE, /* nowakeup */
@@ -893,6 +897,7 @@ selftest_job_func (UDisksThreadedJob  *job,
 
       G_LOCK (object_lock);
       still_in_progress = (g_strcmp0 (drive->smart_selftest_status, "inprogress") == 0);
+      progress = (100.0 - drive->smart_selftest_percent_remaining) / 100.0;
       G_UNLOCK (object_lock);
       if (!still_in_progress)
         {
@@ -900,6 +905,12 @@ selftest_job_func (UDisksThreadedJob  *job,
           goto out;
         }
 
+      if (progress < 0.0)
+        progress = 0.0;
+      if (progress > 1.0)
+        progress = 1.0;
+      udisks_job_set_progress (UDISKS_JOB (job), progress);
+
       /* Sleep for 30 seconds or until we're cancelled */
       if (g_cancellable_make_pollfd (cancellable, &poll_fd))
         {
@@ -923,10 +934,36 @@ selftest_job_func (UDisksThreadedJob  *job,
       /* Check if we're cancelled */
       if (g_cancellable_is_cancelled (cancellable))
         {
+          GError *c_error;
+
           g_set_error (error,
                        UDISKS_ERROR,
                        UDISKS_ERROR_CANCELLED,
                        "Self-test was cancelled");
+
+          /* OK, cancelled ... still need to a) abort the test; and b) update the status */
+          c_error = NULL;
+          if (!udisks_linux_drive_ata_smart_selftest_sync (drive,
+                                                           "abort",
+                                                           NULL, /* cancellable */
+                                                           &c_error))
+            {
+              udisks_warning ("Error aborting SMART selftest for %s on cancel path: %s (%s, %d)",
+                              g_dbus_object_get_object_path (G_DBUS_OBJECT (object)),
+                              c_error->message, g_quark_to_string (c_error->domain), c_error->code);
+              g_clear_error (&c_error);
+            }
+          if (!udisks_linux_drive_ata_refresh_smart_sync (drive,
+                                                          FALSE, /* nowakeup */
+                                                          NULL,  /* blob */
+                                                          NULL,  /* cancellable */
+                                                          &c_error))
+            {
+              udisks_warning ("Error updating ATA smart for %s on cancel path: %s (%s, %d)",
+                              g_dbus_object_get_object_path (G_DBUS_OBJECT (object)),
+                              c_error->message, g_quark_to_string (c_error->domain), c_error->code);
+              g_clear_error (&c_error);
+            }
           goto out;
         }
     }
@@ -953,6 +990,8 @@ handle_smart_selftest_start (UDisksDriveAta        *_drive,
   UDisksLinuxBlockObject *block_object;
   UDisksDaemon *daemon;
   UDisksLinuxDriveAta *drive = UDISKS_LINUX_DRIVE_ATA (_drive);
+  uid_t caller_uid;
+  gid_t caller_gid;
   GError *error;
 
   error = NULL;
@@ -984,6 +1023,20 @@ handle_smart_selftest_start (UDisksDriveAta        *_drive,
       goto out;
     }
 
+  error = NULL;
+  if (!udisks_daemon_util_get_caller_uid_sync (daemon,
+                                               invocation,
+                                               NULL /* GCancellable */,
+                                               &caller_uid,
+                                               &caller_gid,
+                                               NULL,
+                                               &error))
+    {
+      g_dbus_method_invocation_return_gerror (invocation, error);
+      g_error_free (error);
+      goto out;
+    }
+
   G_LOCK (object_lock);
   if (drive->selftest_job != NULL)
     {
@@ -1028,6 +1081,7 @@ handle_smart_selftest_start (UDisksDriveAta        *_drive,
     {
       drive->selftest_job = UDISKS_THREADED_JOB (udisks_daemon_launch_threaded_job (daemon,
                                                                                     UDISKS_OBJECT (object),
+                                                                                    "ata-smart-selftest", caller_uid,
                                                                                     selftest_job_func,
                                                                                     g_object_ref (drive),
                                                                                     g_object_unref,
index 5fad4ef..a8418f5 100644 (file)
@@ -395,6 +395,7 @@ handle_unlock (UDisksEncrypted        *encrypted,
 
   if (!udisks_daemon_launch_spawned_job_sync (daemon,
                                               object,
+                                              "encrypted-unlock", caller_uid,
                                               NULL, /* GCancellable */
                                               0,    /* uid_t run_as_uid */
                                               0,    /* uid_t run_as_euid */
@@ -590,6 +591,7 @@ handle_lock (UDisksEncrypted        *encrypted,
 
   if (!udisks_daemon_launch_spawned_job_sync (daemon,
                                               object,
+                                              "encrypted-lock", caller_uid,
                                               NULL, /* GCancellable */
                                               0,    /* uid_t run_as_uid */
                                               0,    /* uid_t run_as_euid */
@@ -710,6 +712,7 @@ handle_change_passphrase (UDisksEncrypted        *encrypted,
   passphrases = g_strdup_printf ("%s\n%s", passphrase, new_passphrase);
   if (!udisks_daemon_launch_spawned_job_sync (daemon,
                                               object,
+                                              "encrypted-modify", caller_uid,
                                               NULL, /* GCancellable */
                                               0,    /* uid_t run_as_uid */
                                               0,    /* uid_t run_as_euid */
index b6ed08d..efd030a 100644 (file)
@@ -1103,9 +1103,9 @@ handle_mount (UDisksFilesystem       *filesystem,
   UDisksBlock *block;
   UDisksDaemon *daemon;
   UDisksCleanup *cleanup;
-  pid_t caller_pid;
   uid_t caller_uid;
   gid_t caller_gid;
+  pid_t caller_pid;
   const gchar * const *existing_mount_points;
   const gchar *probed_fs_usage;
   gchar *fs_type_to_use;
@@ -1260,6 +1260,7 @@ handle_mount (UDisksFilesystem       *filesystem,
     mount_fstab_again:
       if (!udisks_daemon_launch_spawned_job_sync (daemon,
                                                   object,
+                                                  "filesystem-mount", caller_uid,
                                                   NULL,  /* GCancellable */
                                                   mount_fstab_as_root ? 0 : caller_uid, /* uid_t run_as_uid */
                                                   mount_fstab_as_root ? 0 : caller_uid, /* uid_t run_as_euid */
@@ -1436,6 +1437,7 @@ handle_mount (UDisksFilesystem       *filesystem,
   /* run mount(8) */
   if (!udisks_daemon_launch_spawned_job_sync (daemon,
                                               object,
+                                              "filesystem-mount", caller_uid,
                                               NULL, /* GCancellable */
                                               0,    /* uid_t run_as_uid */
                                               0,    /* uid_t run_as_euid */
@@ -1601,6 +1603,7 @@ handle_unmount (UDisksFilesystem       *filesystem,
       /* right now -l is the only way to "force unmount" file systems... */
       if (!udisks_daemon_launch_spawned_job_sync (daemon,
                                                   object,
+                                                  "filesystem-unmount", caller_uid,
                                                   NULL, /* GCancellable */
                                                   unmount_fstab_as_root ? 0 : caller_uid, /* uid_t run_as_uid */
                                                   unmount_fstab_as_root ? 0 : caller_uid, /* uid_t run_as_euid */
@@ -1698,6 +1701,7 @@ handle_unmount (UDisksFilesystem       *filesystem,
       escaped_mount_point = udisks_daemon_util_escape_and_quote (mount_point);
       rc = udisks_daemon_launch_spawned_job_sync (daemon,
                                                   object,
+                                                  "filesystem-unmount", caller_uid,
                                                   NULL, /* GCancellable */
                                                   0,    /* uid_t run_as_uid */
                                                   0,    /* uid_t run_as_euid */
@@ -1713,6 +1717,7 @@ handle_unmount (UDisksFilesystem       *filesystem,
       /* mount_point == NULL */
       rc = udisks_daemon_launch_spawned_job_sync (daemon,
                                                   object,
+                                                  "filesystem-unmount", caller_uid,
                                                   NULL, /* GCancellable */
                                                   0,    /* uid_t run_as_uid */
                                                   0,    /* uid_t run_as_euid */
@@ -1795,6 +1800,8 @@ handle_set_label (UDisksFilesystem       *filesystem,
   UDisksBaseJob *job;
   const gchar *action_id;
   const gchar *message;
+  uid_t caller_uid;
+  gid_t caller_gid;
   pid_t caller_pid;
   gchar *command;
   gchar *tmp;
@@ -1827,6 +1834,20 @@ handle_set_label (UDisksFilesystem       *filesystem,
       goto out;
     }
 
+  error = NULL;
+  if (!udisks_daemon_util_get_caller_uid_sync (daemon,
+                                               invocation,
+                                               NULL /* GCancellable */,
+                                               &caller_uid,
+                                               &caller_gid,
+                                               NULL,
+                                               &error))
+    {
+      g_dbus_method_invocation_return_gerror (invocation, error);
+      g_error_free (error);
+      goto out;
+    }
+
   probed_fs_usage = udisks_block_get_id_usage (block);
   probed_fs_type = udisks_block_get_id_type (block);
 
@@ -1931,6 +1952,7 @@ handle_set_label (UDisksFilesystem       *filesystem,
 
   job = udisks_daemon_launch_spawned_job (daemon,
                                           object,
+                                          "filesystem-modify", caller_uid,
                                           NULL, /* cancellable */
                                           0,    /* uid_t run_as_uid */
                                           0,    /* uid_t run_as_euid */
index b83babb..d59fa6a 100644 (file)
@@ -250,6 +250,7 @@ handle_delete (UDisksLoop             *loop,
 
   if (!udisks_daemon_launch_spawned_job_sync (daemon,
                                               NULL, /* UDisksObject */
+                                              "loop-setup", caller_uid,
                                               NULL, /* GCancellable */
                                               0,    /* uid_t run_as_uid */
                                               0,    /* uid_t run_as_euid */
index 195554d..07e6ba5 100644 (file)
@@ -225,6 +225,8 @@ handle_set_flags (UDisksPartition        *partition,
   UDisksBlock *partition_table_block = NULL;
   gchar *command_line = NULL;
   gint fd = -1;
+  uid_t caller_uid;
+  gid_t caller_gid;
   pid_t caller_pid;
   GError *error;
 
@@ -251,6 +253,20 @@ handle_set_flags (UDisksPartition        *partition,
       goto out;
     }
 
+  error = NULL;
+  if (!udisks_daemon_util_get_caller_uid_sync (daemon,
+                                               invocation,
+                                               NULL /* GCancellable */,
+                                               &caller_uid,
+                                               &caller_gid,
+                                               NULL,
+                                               &error))
+    {
+      g_dbus_method_invocation_return_gerror (invocation, error);
+      g_error_free (error);
+      goto out;
+    }
+
   partition_table_object = udisks_daemon_find_object (daemon, udisks_partition_get_table (partition));
   partition_table = udisks_object_get_partition_table (partition_table_object);
   partition_table_block = udisks_object_get_block (partition_table_object);
@@ -311,6 +327,7 @@ handle_set_flags (UDisksPartition        *partition,
 
   if (!udisks_daemon_launch_spawned_job_sync (daemon,
                                               object,
+                                              "partition-modify", caller_uid,
                                               NULL, /* GCancellable */
                                               0,    /* uid_t run_as_uid */
                                               0,    /* uid_t run_as_euid */
@@ -370,6 +387,8 @@ handle_set_name (UDisksPartition        *partition,
   UDisksBlock *partition_table_block = NULL;
   gchar *command_line = NULL;
   gint fd = -1;
+  uid_t caller_uid;
+  gid_t caller_gid;
   pid_t caller_pid;
   GError *error;
 
@@ -396,6 +415,20 @@ handle_set_name (UDisksPartition        *partition,
       goto out;
     }
 
+  error = NULL;
+  if (!udisks_daemon_util_get_caller_uid_sync (daemon,
+                                               invocation,
+                                               NULL /* GCancellable */,
+                                               &caller_uid,
+                                               &caller_gid,
+                                               NULL,
+                                               &error))
+    {
+      g_dbus_method_invocation_return_gerror (invocation, error);
+      g_error_free (error);
+      goto out;
+    }
+
   partition_table_object = udisks_daemon_find_object (daemon, udisks_partition_get_table (partition));
   partition_table = udisks_object_get_partition_table (partition_table_object);
   partition_table_block = udisks_object_get_block (partition_table_object);
@@ -461,6 +494,7 @@ handle_set_name (UDisksPartition        *partition,
 
   if (!udisks_daemon_launch_spawned_job_sync (daemon,
                                               object,
+                                              "partition-modify", caller_uid,
                                               NULL, /* GCancellable */
                                               0,    /* uid_t run_as_uid */
                                               0,    /* uid_t run_as_euid */
@@ -552,6 +586,8 @@ handle_set_type (UDisksPartition        *partition,
   UDisksBlock *partition_table_block = NULL;
   gchar *command_line = NULL;
   gint fd = -1;
+  uid_t caller_uid;
+  gid_t caller_gid;
   pid_t caller_pid;
   GError *error;
 
@@ -578,6 +614,20 @@ handle_set_type (UDisksPartition        *partition,
       goto out;
     }
 
+  error = NULL;
+  if (!udisks_daemon_util_get_caller_uid_sync (daemon,
+                                               invocation,
+                                               NULL /* GCancellable */,
+                                               &caller_uid,
+                                               &caller_gid,
+                                               NULL,
+                                               &error))
+    {
+      g_dbus_method_invocation_return_gerror (invocation, error);
+      g_error_free (error);
+      goto out;
+    }
+
   partition_table_object = udisks_daemon_find_object (daemon, udisks_partition_get_table (partition));
   partition_table = udisks_object_get_partition_table (partition_table_object);
   partition_table_block = udisks_object_get_block (partition_table_object);
@@ -668,6 +718,7 @@ handle_set_type (UDisksPartition        *partition,
 
   if (!udisks_daemon_launch_spawned_job_sync (daemon,
                                               object,
+                                              "partition-modify", caller_uid,
                                               NULL, /* GCancellable */
                                               0,    /* uid_t run_as_uid */
                                               0,    /* uid_t run_as_euid */
@@ -725,6 +776,8 @@ handle_delete (UDisksPartition        *partition,
   UDisksPartitionTable *partition_table = NULL;
   UDisksBlock *partition_table_block = NULL;
   gchar *command_line = NULL;
+  uid_t caller_uid;
+  gid_t caller_gid;
   pid_t caller_pid;
   GError *error;
 
@@ -751,6 +804,20 @@ handle_delete (UDisksPartition        *partition,
       goto out;
     }
 
+  error = NULL;
+  if (!udisks_daemon_util_get_caller_uid_sync (daemon,
+                                               invocation,
+                                               NULL /* GCancellable */,
+                                               &caller_uid,
+                                               &caller_gid,
+                                               NULL,
+                                               &error))
+    {
+      g_dbus_method_invocation_return_gerror (invocation, error);
+      g_error_free (error);
+      goto out;
+    }
+
   partition_table_object = udisks_daemon_find_object (daemon, udisks_partition_get_table (partition));
   partition_table = udisks_object_get_partition_table (partition_table_object);
   partition_table_block = udisks_object_get_block (partition_table_object);
@@ -784,6 +851,7 @@ handle_delete (UDisksPartition        *partition,
 
   if (!udisks_daemon_launch_spawned_job_sync (daemon,
                                               partition_table_object,
+                                              "partition-delete", caller_uid,
                                               NULL, /* GCancellable */
                                               0,    /* uid_t run_as_uid */
                                               0,    /* uid_t run_as_euid */
index 055bd30..e95e502 100644 (file)
@@ -291,6 +291,8 @@ handle_create_partition (UDisksPartitionTable   *table,
   gchar *escaped_partition_device = NULL;
   const gchar *table_type;
   pid_t caller_pid;
+  uid_t caller_uid;
+  gid_t caller_gid;
   GError *error;
 
   error = NULL;
@@ -322,6 +324,20 @@ handle_create_partition (UDisksPartitionTable   *table,
       goto out;
     }
 
+  error = NULL;
+  if (!udisks_daemon_util_get_caller_uid_sync (daemon,
+                                               invocation,
+                                               NULL /* GCancellable */,
+                                               &caller_uid,
+                                               &caller_gid,
+                                               NULL,
+                                               &error))
+    {
+      g_dbus_method_invocation_return_gerror (invocation, error);
+      g_error_free (error);
+      goto out;
+    }
+
   action_id = "org.freedesktop.udisks2.modify-device";
   /* Translators: Shown in authentication dialog when the user
    * requests creating a new partition.
@@ -502,6 +518,7 @@ handle_create_partition (UDisksPartitionTable   *table,
 
   if (!udisks_daemon_launch_spawned_job_sync (daemon,
                                               object,
+                                              "partition-create", caller_uid,
                                               NULL, /* GCancellable */
                                               0,    /* uid_t run_as_uid */
                                               0,    /* uid_t run_as_euid */
@@ -552,6 +569,7 @@ handle_create_partition (UDisksPartitionTable   *table,
   /* wipe the newly created partition */
   if (!udisks_daemon_launch_spawned_job_sync (daemon,
                                               partition_object,
+                                              "partition-create", caller_uid,
                                               NULL, /* GCancellable */
                                               0,    /* uid_t run_as_uid */
                                               0,    /* uid_t run_as_euid */
index 2309c92..29e83e6 100644 (file)
@@ -160,6 +160,8 @@ handle_start (UDisksSwapspace        *swapspace,
   UDisksBaseJob *job;
   GError *error;
   gchar *escaped_device = NULL;
+  uid_t caller_uid;
+  gid_t caller_gid;
 
   error = NULL;
   object = udisks_daemon_util_dup_object (swapspace, &error);
@@ -172,6 +174,20 @@ handle_start (UDisksSwapspace        *swapspace,
   daemon = udisks_linux_block_object_get_daemon (UDISKS_LINUX_BLOCK_OBJECT (object));
   block = udisks_object_peek_block (object);
 
+  error = NULL;
+  if (!udisks_daemon_util_get_caller_uid_sync (daemon,
+                                               invocation,
+                                               NULL /* GCancellable */,
+                                               &caller_uid,
+                                               &caller_gid,
+                                               NULL,
+                                               &error))
+    {
+      g_dbus_method_invocation_return_gerror (invocation, error);
+      g_error_free (error);
+      goto out;
+    }
+
   if (!udisks_daemon_util_check_authorization_sync (daemon,
                                                     object,
                                                     "org.freedesktop.udisks2.manage-swapspace",
@@ -190,6 +206,7 @@ handle_start (UDisksSwapspace        *swapspace,
 
   job = udisks_daemon_launch_spawned_job (daemon,
                                           object,
+                                          "swapspace-start", caller_uid,
                                           NULL, /* cancellable */
                                           0,    /* uid_t run_as_uid */
                                           0,    /* uid_t run_as_euid */
@@ -235,12 +252,29 @@ handle_stop (UDisksSwapspace        *swapspace,
   UDisksDaemon *daemon;
   UDisksBlock *block;
   UDisksBaseJob *job;
+  uid_t caller_uid;
+  gid_t caller_gid;
   gchar *escaped_device = NULL;
+  GError *error = NULL;
 
   object = UDISKS_OBJECT (g_dbus_interface_get_object (G_DBUS_INTERFACE (swapspace)));
   daemon = udisks_linux_block_object_get_daemon (UDISKS_LINUX_BLOCK_OBJECT (object));
   block = udisks_object_peek_block (object);
 
+  error = NULL;
+  if (!udisks_daemon_util_get_caller_uid_sync (daemon,
+                                               invocation,
+                                               NULL /* GCancellable */,
+                                               &caller_uid,
+                                               &caller_gid,
+                                               NULL,
+                                               &error))
+    {
+      g_dbus_method_invocation_return_gerror (invocation, error);
+      g_error_free (error);
+      goto out;
+    }
+
   /* Now, check that the user is actually authorized to stop the swap space.
    *
    * TODO: want nicer authentication message + special treatment if the
@@ -264,6 +298,7 @@ handle_stop (UDisksSwapspace        *swapspace,
 
   job = udisks_daemon_launch_spawned_job (daemon,
                                           object,
+                                          "swapspace-stop", caller_uid,
                                           NULL, /* cancellable */
                                           0,    /* uid_t run_as_uid */
                                           0,    /* uid_t run_as_euid */
index b8bcdf3..d13ef36 100644 (file)
@@ -27,6 +27,7 @@
 #include "udisksbasejob.h"
 #include "udiskssimplejob.h"
 #include "udisks-daemon-marshal.h"
+#include "udisksdaemon.h"
 
 /**
  * SECTION:udiskssimplejob
@@ -74,6 +75,7 @@ udisks_simple_job_class_init (UDisksSimpleJobClass *klass)
 
 /**
  * udisks_simple_job_new:
+ * @daemon: A #UDisksDaemon.
  * @cancellable: A #GCancellable or %NULL.
  *
  * Creates a new #UDisksSimpleJob instance.
@@ -83,10 +85,13 @@ udisks_simple_job_class_init (UDisksSimpleJobClass *klass)
  * Returns: A new #UDisksSimpleJob. Free with g_object_unref().
  */
 UDisksSimpleJob *
-udisks_simple_job_new (GCancellable  *cancellable)
+udisks_simple_job_new (UDisksDaemon  *daemon,
+                       GCancellable  *cancellable)
 {
+  /* g_return_val_if_fail (UDISKS_IS_DAEMON (daemon), NULL); */
   g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), NULL);
   return UDISKS_SIMPLE_JOB (g_object_new (UDISKS_TYPE_SIMPLE_JOB,
+                                          "daemon", daemon,
                                           "cancellable", cancellable,
                                           NULL));
 }
index c61ca4f..493b008 100644 (file)
@@ -30,7 +30,8 @@ G_BEGIN_DECLS
 #define UDISKS_IS_SIMPLE_JOB(o)        (G_TYPE_CHECK_INSTANCE_TYPE ((o), UDISKS_TYPE_SIMPLE_JOB))
 
 GType            udisks_simple_job_get_type         (void) G_GNUC_CONST;
-UDisksSimpleJob *udisks_simple_job_new              (GCancellable        *cancellable);
+UDisksSimpleJob *udisks_simple_job_new              (UDisksDaemon        *daemon,
+                                                     GCancellable        *cancellable);
 void             udisks_simple_job_complete         (UDisksSimpleJob     *job,
                                                      gboolean             succeess,
                                                      const gchar         *message);
index 41cbc6c..802551f 100644 (file)
@@ -33,6 +33,7 @@
 #include "udisksbasejob.h"
 #include "udisksspawnedjob.h"
 #include "udisks-daemon-marshal.h"
+#include "udisksdaemon.h"
 
 /**
  * SECTION:udisksspawnedjob
@@ -662,6 +663,7 @@ udisks_spawned_job_class_init (UDisksSpawnedJobClass *klass)
  * @input_string: A string to write to stdin of the spawned program or %NULL.
  * @run_as_uid: The #uid_t to run the program as.
  * @run_as_euid: The effective #uid_t to run the program as.
+ * @daemon: A #UDisksDaemon.
  * @cancellable: A #GCancellable or %NULL.
  *
  * Creates a new #UDisksSpawnedJob instance.
@@ -677,15 +679,18 @@ udisks_spawned_job_new (const gchar  *command_line,
                         const gchar  *input_string,
                         uid_t         run_as_uid,
                         uid_t         run_as_euid,
+                        UDisksDaemon *daemon,
                         GCancellable *cancellable)
 {
   g_return_val_if_fail (command_line != NULL, NULL);
+  /* g_return_val_if_fail (UDISKS_IS_DAEMON (daemon), NULL); */
   g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), NULL);
   return UDISKS_SPAWNED_JOB (g_object_new (UDISKS_TYPE_SPAWNED_JOB,
                                            "command-line", command_line,
                                            "input-string", input_string,
                                            "run-as-uid", run_as_uid,
                                            "run-as-euid", run_as_euid,
+                                           "daemon", daemon,
                                            "cancellable", cancellable,
                                            NULL));
 }
index f14e876..311931a 100644 (file)
@@ -34,6 +34,7 @@ UDisksSpawnedJob  *udisks_spawned_job_new              (const gchar  *command_li
                                                         const gchar  *input_string,
                                                         uid_t         run_as_uid,
                                                         uid_t         run_as_euid,
+                                                        UDisksDaemon *daemon,
                                                         GCancellable *cancellable);
 const gchar       *udisks_spawned_job_get_command_line (UDisksSpawnedJob *job);
 
index 891171e..2ecf8ce 100644 (file)
@@ -27,6 +27,7 @@
 #include "udisksbasejob.h"
 #include "udisksthreadedjob.h"
 #include "udisks-daemon-marshal.h"
+#include "udisksdaemon.h"
 
 /**
  * SECTION:udisksthreadedjob
@@ -334,6 +335,7 @@ udisks_threaded_job_class_init (UDisksThreadedJobClass *klass)
  * @job_func: The function to run in another thread.
  * @user_data: User data to pass to @job_func.
  * @user_data_free_func: Function to free @user_data with or %NULL.
+ * @daemon: A #UDisksDaemon.
  * @cancellable: A #GCancellable or %NULL.
  *
  * Creates a new #UDisksThreadedJob instance.
@@ -348,13 +350,16 @@ UDisksThreadedJob *
 udisks_threaded_job_new (UDisksThreadedJobFunc  job_func,
                          gpointer               user_data,
                          GDestroyNotify         user_data_free_func,
+                         UDisksDaemon          *daemon,
                          GCancellable          *cancellable)
 {
+  /* g_return_val_if_fail (UDISKS_IS_DAEMON (daemon), NULL); */
   g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), NULL);
   return UDISKS_THREADED_JOB (g_object_new (UDISKS_TYPE_THREADED_JOB,
                                             "job-func", job_func,
                                             "user-data", user_data,
                                             "user-data-free-func", user_data_free_func,
+                                            "daemon", daemon,
                                             "cancellable", cancellable,
                                             NULL));
 }
index 800fd84..6463e41 100644 (file)
@@ -33,6 +33,7 @@ GType              udisks_threaded_job_get_type         (void) G_GNUC_CONST;
 UDisksThreadedJob *udisks_threaded_job_new              (UDisksThreadedJobFunc  job_func,
                                                          gpointer               user_data,
                                                          GDestroyNotify         user_data_free_func,
+                                                         UDisksDaemon          *daemon,
                                                          GCancellable          *cancellable);
 gpointer           udisks_threaded_job_get_user_data    (UDisksThreadedJob     *job);
 
index 6c6e0f6..93ef677 100644 (file)
@@ -2594,6 +2594,58 @@ udisks_client_get_partition_type_for_display (UDisksClient  *client,
 
 /* ---------------------------------------------------------------------------------------------------- */
 
+/**
+ * udisks_client_get_job_description:
+ * @client: A #UDisksClient.
+ * @job: A #UDisksJob.
+ *
+ * Gets a human-readable and localized text string describing the
+ * operation of @job.
+ *
+ * Returns: A string that should be freed with g_free().
+ */
+gchar *
+udisks_client_get_job_description (UDisksClient   *client,
+                                   UDisksJob      *job)
+{
+  static gsize once = 0;
+  static GHashTable *hash = NULL;
+  gchar *ret = NULL;
+
+  g_return_val_if_fail (UDISKS_IS_CLIENT (client), NULL);
+
+  if (g_once_init_enter (&once))
+    {
+      hash = g_hash_table_new (g_str_hash, g_str_equal);
+      g_hash_table_insert (hash, "ata-smart-selftest",   (gpointer) C_("job", "SMART self-test"));
+      g_hash_table_insert (hash, "drive-eject",          (gpointer) C_("job", "Ejecting Medium"));
+      g_hash_table_insert (hash, "encrypted-unlock",     (gpointer) C_("job", "Unlocking Device"));
+      g_hash_table_insert (hash, "encrypted-lock",       (gpointer) C_("job", "Locking Device"));
+      g_hash_table_insert (hash, "encrypted-modify",     (gpointer) C_("job", "Modifying Encrypted Device"));
+      g_hash_table_insert (hash, "swapspace-start",      (gpointer) C_("job", "Starting Swap Device"));
+      g_hash_table_insert (hash, "swapspace-stop",       (gpointer) C_("job", "Stopping Swap Device"));
+      g_hash_table_insert (hash, "filesystem-mount",     (gpointer) C_("job", "Mounting Filesystem"));
+      g_hash_table_insert (hash, "filesystem-unmount",   (gpointer) C_("job", "Unmounting Filesystem"));
+      g_hash_table_insert (hash, "filesystem-modify",    (gpointer) C_("job", "Modifying Filesystem"));
+      g_hash_table_insert (hash, "format-erase",         (gpointer) C_("job", "Erasing Device"));
+      g_hash_table_insert (hash, "format-mkfs",          (gpointer) C_("job", "Creating Filesystem"));
+      g_hash_table_insert (hash, "loop-setup",           (gpointer) C_("job", "Setting Up Loop Device"));
+      g_hash_table_insert (hash, "partition-modify",     (gpointer) C_("job", "Modifying Partition"));
+      g_hash_table_insert (hash, "partition-delete",     (gpointer) C_("job", "Deleting Partition"));
+      g_hash_table_insert (hash, "partition-create",     (gpointer) C_("job", "Creating Partition"));
+      g_hash_table_insert (hash, "cleanup",              (gpointer) C_("job", "Cleaning Up"));
+      g_once_init_leave (&once, (gsize) 1);
+    }
+
+  ret = g_strdup (g_hash_table_lookup (hash, udisks_job_get_operation (job)));
+  if (ret == NULL)
+    ret = g_strdup_printf (C_("unknown-job", "Unknown (%s)"), udisks_job_get_operation (job));
+
+  return ret;
+}
+
+/* ---------------------------------------------------------------------------------------------------- */
+
 static UDisksPartitionTypeInfo *
 udisks_partition_type_info_new (void)
 {
index 7b716b4..d8d917f 100644 (file)
@@ -125,6 +125,9 @@ const gchar        *udisks_client_get_partition_table_subtype_for_display (UDisk
                                                                            const gchar   *partition_table_type,
                                                                            const gchar   *partition_table_subtype);
 
+gchar *udisks_client_get_job_description (UDisksClient   *client,
+                                          UDisksJob      *job);
+
 /**
  * UDisksPartitionTypeInfo:
  * @table_type: A partition table type e.g. 'dos' or 'gpt'