1
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
3
* Copyright (C) 2011 David Zeuthen <zeuthen@gmail.com>
5
* This library is free software; you can redistribute it and/or
6
* modify it under the terms of the GNU Lesser General Public
7
* License as published by the Free Software Foundation; either
8
* version 2 of the License, or (at your option) any later version.
10
* This library is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
* Lesser General Public License for more details.
15
* You should have received a copy of the GNU Lesser General
16
* Public License along with this library; if not, write to the
17
* Free Software Foundation, Inc., 59 Temple Place, Suite 330,
18
* Boston, MA 02111-1307, USA.
22
#include <glib/gi18n-lib.h>
24
#include "udisksclient.h"
25
#include "udiskserror.h"
26
#include "udisks-generated.h"
29
* SECTION:udisksclient
30
* @title: UDisksClient
31
* @short_description: Utility routines for accessing the UDisks service
33
* #UDisksClient is used for accessing the UDisks service from a
37
G_LOCK_DEFINE_STATIC (init_lock);
42
* The #UDisksClient structure contains only private data and should
43
* only be accessed using the provided API.
47
GObject parent_instance;
49
gboolean is_initialized;
50
GError *initialization_error;
52
GDBusObjectManager *object_manager;
54
GMainContext *context;
56
GSource *changed_timeout_source;
61
GObjectClass parent_class;
77
static guint signals[LAST_SIGNAL] = { 0 };
79
static void initable_iface_init (GInitableIface *initable_iface);
80
static void async_initable_iface_init (GAsyncInitableIface *async_initable_iface);
82
static void on_object_added (GDBusObjectManager *manager,
86
static void on_object_removed (GDBusObjectManager *manager,
90
static void on_interface_added (GDBusObjectManager *manager,
92
GDBusInterface *interface,
95
static void on_interface_removed (GDBusObjectManager *manager,
97
GDBusInterface *interface,
100
static void on_interface_proxy_properties_changed (GDBusObjectManagerClient *manager,
101
GDBusObjectProxy *object_proxy,
102
GDBusProxy *interface_proxy,
103
GVariant *changed_properties,
104
const gchar *const *invalidated_properties,
107
static void maybe_emit_changed_now (UDisksClient *client);
109
static void init_interface_proxy (UDisksClient *client,
112
static UDisksPartitionTypeInfo *udisks_partition_type_info_new (void);
114
G_DEFINE_TYPE_WITH_CODE (UDisksClient, udisks_client, G_TYPE_OBJECT,
115
G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, initable_iface_init)
116
G_IMPLEMENT_INTERFACE (G_TYPE_ASYNC_INITABLE, async_initable_iface_init)
120
udisks_client_finalize (GObject *object)
122
UDisksClient *client = UDISKS_CLIENT (object);
124
if (client->changed_timeout_source != NULL)
125
g_source_destroy (client->changed_timeout_source);
127
if (client->initialization_error != NULL)
128
g_error_free (client->initialization_error);
130
g_signal_handlers_disconnect_by_func (client->object_manager,
131
G_CALLBACK (on_object_added),
133
g_signal_handlers_disconnect_by_func (client->object_manager,
134
G_CALLBACK (on_object_removed),
136
g_signal_handlers_disconnect_by_func (client->object_manager,
137
G_CALLBACK (on_interface_added),
139
g_signal_handlers_disconnect_by_func (client->object_manager,
140
G_CALLBACK (on_interface_removed),
142
g_signal_handlers_disconnect_by_func (client->object_manager,
143
G_CALLBACK (on_interface_proxy_properties_changed),
145
g_object_unref (client->object_manager);
147
if (client->context != NULL)
148
g_main_context_unref (client->context);
150
G_OBJECT_CLASS (udisks_client_parent_class)->finalize (object);
154
udisks_client_init (UDisksClient *client)
156
static volatile GQuark udisks_error_domain = 0;
157
/* this will force associating errors in the UDISKS_ERROR error
158
* domain with org.freedesktop.UDisks2.Error.* errors via
159
* g_dbus_error_register_error_domain().
161
udisks_error_domain = UDISKS_ERROR;
162
udisks_error_domain; /* shut up -Wunused-but-set-variable */
166
udisks_client_get_property (GObject *object,
171
UDisksClient *client = UDISKS_CLIENT (object);
175
case PROP_OBJECT_MANAGER:
176
g_value_set_object (value, udisks_client_get_object_manager (client));
180
g_value_set_object (value, udisks_client_get_manager (client));
184
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
190
udisks_client_class_init (UDisksClientClass *klass)
192
GObjectClass *gobject_class;
194
gobject_class = G_OBJECT_CLASS (klass);
195
gobject_class->finalize = udisks_client_finalize;
196
gobject_class->get_property = udisks_client_get_property;
199
* UDisksClient:object-manager:
201
* The #GDBusObjectManager used by the #UDisksClient instance.
203
g_object_class_install_property (gobject_class,
205
g_param_spec_object ("object-manager",
207
"The GDBusObjectManager used by the UDisksClient",
208
G_TYPE_DBUS_OBJECT_MANAGER,
210
G_PARAM_STATIC_STRINGS));
213
* UDisksClient:manager:
215
* The #UDisksManager interface on the well-known
216
* <literal>/org/freedesktop/UDisks2/Manager</literal> object
218
g_object_class_install_property (gobject_class,
220
g_param_spec_object ("manager",
225
G_PARAM_STATIC_STRINGS));
228
* UDisksClient::changed:
229
* @client: A #UDisksClient.
231
* This signal is emitted either when an object or interface is
232
* added or removed a when property has changed. Additionally,
233
* multiple received signals are coalesced into a single signal that
234
* is rate-limited to fire at most every 100ms.
236
* Note that calling udisks_client_settle() will cause this signal
237
* to fire if any changes are outstanding.
239
* For greater detail, connect to the
240
* #GDBusObjectManager::object-added,
241
* #GDBusObjectManager::object-removed,
242
* #GDBusObjectManager::interface-added,
243
* #GDBusObjectManager::interface-removed,
244
* #GDBusObjectManagerClient::interface-proxy-properties-changed and
245
* signals on the #UDisksClient:object-manager object.
247
signals[CHANGED_SIGNAL] = g_signal_new ("changed",
248
G_OBJECT_CLASS_TYPE (klass),
250
0, /* G_STRUCT_OFFSET */
252
NULL, /* accu data */
253
g_cclosure_marshal_generic,
261
* @cancellable: A #GCancellable or %NULL.
262
* @callback: Function that will be called when the result is ready.
263
* @user_data: Data to pass to @callback.
265
* Asynchronously gets a #UDisksClient. When the operation is
266
* finished, @callback will be invoked in the <link
267
* linkend="g-main-context-push-thread-default">thread-default main
268
* loop</link> of the thread you are calling this method from.
271
udisks_client_new (GCancellable *cancellable,
272
GAsyncReadyCallback callback,
275
g_async_initable_new_async (UDISKS_TYPE_CLIENT,
284
* udisks_client_new_finish:
285
* @res: A #GAsyncResult.
286
* @error: Return location for error or %NULL.
288
* Finishes an operation started with udisks_client_new().
290
* Returns: A #UDisksClient or %NULL if @error is set. Free with
291
* g_object_unref() when done with it.
294
udisks_client_new_finish (GAsyncResult *res,
298
GObject *source_object;
299
source_object = g_async_result_get_source_object (res);
300
ret = g_async_initable_new_finish (G_ASYNC_INITABLE (source_object), res, error);
301
g_object_unref (source_object);
303
return UDISKS_CLIENT (ret);
309
* udisks_client_new_sync:
310
* @cancellable: (allow-none): A #GCancellable or %NULL.
311
* @error: (allow-none): Return location for error or %NULL.
313
* Synchronously gets a #UDisksClient for the local system.
315
* Returns: A #UDisksClient or %NULL if @error is set. Free with
316
* g_object_unref() when done with it.
319
udisks_client_new_sync (GCancellable *cancellable,
323
ret = g_initable_new (UDISKS_TYPE_CLIENT,
328
return UDISKS_CLIENT (ret);
333
/* ---------------------------------------------------------------------------------------------------- */
336
initable_init (GInitable *initable,
337
GCancellable *cancellable,
340
UDisksClient *client = UDISKS_CLIENT (initable);
343
GList *interfaces, *ll;
347
/* This method needs to be idempotent to work with the singleton
348
* pattern. See the docs for g_initable_init(). We implement this by
352
if (client->is_initialized)
354
if (client->object_manager != NULL)
357
g_assert (client->initialization_error != NULL);
360
g_assert (client->initialization_error == NULL);
362
client->context = g_main_context_get_thread_default ();
363
if (client->context != NULL)
364
g_main_context_ref (client->context);
366
client->object_manager = udisks_object_manager_client_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
367
G_DBUS_OBJECT_MANAGER_CLIENT_FLAGS_NONE,
368
"org.freedesktop.UDisks2",
369
"/org/freedesktop/UDisks2",
371
&client->initialization_error);
372
if (client->object_manager == NULL)
375
/* init all proxies */
376
objects = g_dbus_object_manager_get_objects (client->object_manager);
377
for (l = objects; l != NULL; l = l->next)
379
interfaces = g_dbus_object_get_interfaces (G_DBUS_OBJECT (l->data));
380
for (ll = interfaces; ll != NULL; ll = ll->next)
382
init_interface_proxy (client, G_DBUS_PROXY (ll->data));
384
g_list_foreach (interfaces, (GFunc) g_object_unref, NULL);
385
g_list_free (interfaces);
387
g_list_foreach (objects, (GFunc) g_object_unref, NULL);
388
g_list_free (objects);
390
g_signal_connect (client->object_manager,
392
G_CALLBACK (on_object_added),
394
g_signal_connect (client->object_manager,
396
G_CALLBACK (on_object_removed),
398
g_signal_connect (client->object_manager,
400
G_CALLBACK (on_interface_added),
402
g_signal_connect (client->object_manager,
404
G_CALLBACK (on_interface_removed),
406
g_signal_connect (client->object_manager,
407
"interface-proxy-properties-changed",
408
G_CALLBACK (on_interface_proxy_properties_changed),
414
client->is_initialized = TRUE;
417
g_assert (client->initialization_error != NULL);
418
g_propagate_error (error, g_error_copy (client->initialization_error));
420
G_UNLOCK (init_lock);
425
initable_iface_init (GInitableIface *initable_iface)
427
initable_iface->init = initable_init;
431
async_initable_iface_init (GAsyncInitableIface *async_initable_iface)
433
/* Use default implementation (e.g. run GInitable code in a thread) */
437
* udisks_client_get_object_manager:
438
* @client: A #UDisksClient.
440
* Gets the #GDBusObjectManager used by @client.
442
* Returns: (transfer none): A #GDBusObjectManager. Do not free, the
443
* instance is owned by @client.
446
udisks_client_get_object_manager (UDisksClient *client)
448
g_return_val_if_fail (UDISKS_IS_CLIENT (client), NULL);
449
return client->object_manager;
453
* udisks_client_get_manager:
454
* @client: A #UDisksClient.
456
* Gets the #UDisksManager interface on the well-known
457
* <literal>/org/freedesktop/UDisks2/Manager</literal> object.
459
* Returns: (transfer none): A #UDisksManager or %NULL if the udisksd
460
* daemon is not currently running. Do not free, the instance is owned
464
udisks_client_get_manager (UDisksClient *client)
466
UDisksManager *ret = NULL;
469
g_return_val_if_fail (UDISKS_IS_CLIENT (client), NULL);
471
obj = g_dbus_object_manager_get_object (client->object_manager, "/org/freedesktop/UDisks2/Manager");
475
ret = udisks_object_peek_manager (UDISKS_OBJECT (obj));
476
g_object_unref (obj);
483
* udisks_client_settle:
484
* @client: A #UDisksClient.
486
* Blocks until all pending D-Bus messages have been delivered. Also
487
* emits the (rate-limited) #UDisksClient::changed signal if changes
488
* are currently pending.
490
* This is useful in two situations: 1. when using synchronous method
491
* calls since e.g. D-Bus signals received while waiting for the reply
492
* are queued up and dispatched after the synchronous call ends; and
493
* 2. when using asynchronous calls where the return value references
494
* a newly created object (such as the <link
495
* linkend="gdbus-method-org-freedesktop-UDisks2-Manager.LoopSetup">Manager.LoopSetup()</link> method).
498
udisks_client_settle (UDisksClient *client)
500
while (g_main_context_iteration (client->context, FALSE /* may_block */))
502
/* TODO: careful if on different thread... */
503
maybe_emit_changed_now (client);
506
/* ---------------------------------------------------------------------------------------------------- */
509
* udisks_client_get_object:
510
* @client: A #UDisksClient.
511
* @object_path: Object path.
513
* Convenience function for looking up an #UDisksObject for @object_path.
515
* Returns: (transfer full): A #UDisksObject corresponding to
516
* @object_path or %NULL if not found. The returned object must be
517
* freed with g_object_unref().
520
udisks_client_get_object (UDisksClient *client,
521
const gchar *object_path)
523
g_return_val_if_fail (UDISKS_IS_CLIENT (client), NULL);
524
return (UDisksObject *) g_dbus_object_manager_get_object (client->object_manager, object_path);
528
* udisks_client_peek_object:
529
* @client: A #UDisksClient.
530
* @object_path: Object path.
532
* Like udisks_client_get_object() but doesn't increase the reference
533
* count on the returned #UDisksObject.
535
* <warning>The returned object is only valid until removed so it is only safe to use this function on the thread where @client was constructed. Use udisks_client_get_object() if on another thread.</warning>
537
* Returns: (transfer none): A #UDisksObject corresponding to
538
* @object_path or %NULL if not found.
541
udisks_client_peek_object (UDisksClient *client,
542
const gchar *object_path)
545
ret = udisks_client_get_object (client, object_path);
547
g_object_unref (ret);
551
/* ---------------------------------------------------------------------------------------------------- */
554
* udisks_client_get_block_for_label:
555
* @client: A #UDisksClient.
558
* Gets all the #UDisksBlock instances with the given label, if any.
560
* Returns: (transfer full) (element-type UDisksBlock): A list of #UDisksBlock instances. The
561
* returned list should be freed with g_list_free() after each
562
* element has been freed with g_object_unref().
565
udisks_client_get_block_for_label (UDisksClient *client,
569
GList *l, *object_proxies = NULL;
571
g_return_val_if_fail (UDISKS_IS_CLIENT (client), NULL);
572
g_return_val_if_fail (label != NULL, NULL);
574
object_proxies = g_dbus_object_manager_get_objects (client->object_manager);
575
for (l = object_proxies; l != NULL; l = l->next)
577
UDisksObject *object = UDISKS_OBJECT (l->data);
580
block = udisks_object_get_block (object);
584
if (g_strcmp0 (udisks_block_get_id_label (block), label) == 0)
585
ret = g_list_prepend (ret, block);
587
g_object_unref (block);
590
g_list_foreach (object_proxies, (GFunc) g_object_unref, NULL);
591
g_list_free (object_proxies);
592
ret = g_list_reverse (ret);
596
/* ---------------------------------------------------------------------------------------------------- */
599
* udisks_client_get_block_for_uuid:
600
* @client: A #UDisksClient.
603
* Gets all the #UDisksBlock instances with the given uuid, if any.
605
* Returns: (transfer full) (element-type UDisksBlock): A list of #UDisksBlock instances. The
606
* returned list should be freed with g_list_free() after each
607
* element has been freed with g_object_unref().
610
udisks_client_get_block_for_uuid (UDisksClient *client,
614
GList *l, *object_proxies = NULL;
616
g_return_val_if_fail (UDISKS_IS_CLIENT (client), NULL);
617
g_return_val_if_fail (uuid != NULL, NULL);
619
object_proxies = g_dbus_object_manager_get_objects (client->object_manager);
620
for (l = object_proxies; l != NULL; l = l->next)
622
UDisksObject *object = UDISKS_OBJECT (l->data);
625
block = udisks_object_get_block (object);
629
if (g_strcmp0 (udisks_block_get_id_uuid (block), uuid) == 0)
630
ret = g_list_prepend (ret, block);
632
g_object_unref (block);
635
g_list_foreach (object_proxies, (GFunc) g_object_unref, NULL);
636
g_list_free (object_proxies);
637
ret = g_list_reverse (ret);
641
/* ---------------------------------------------------------------------------------------------------- */
644
* udisks_client_get_block_for_dev:
645
* @client: A #UDisksClient.
646
* @block_device_number: A #dev_t to get a #UDisksBlock for.
648
* Gets the #UDisksBlock corresponding to @block_device_number, if any.
650
* Returns: (transfer full): A #UDisksBlock or %NULL if not found.
653
udisks_client_get_block_for_dev (UDisksClient *client,
654
dev_t block_device_number)
656
UDisksBlock *ret = NULL;
657
GList *l, *object_proxies = NULL;
659
g_return_val_if_fail (UDISKS_IS_CLIENT (client), NULL);
661
object_proxies = g_dbus_object_manager_get_objects (client->object_manager);
662
for (l = object_proxies; l != NULL; l = l->next)
664
UDisksObject *object = UDISKS_OBJECT (l->data);
667
block = udisks_object_get_block (object);
671
if (udisks_block_get_device_number (block) == block_device_number)
676
g_object_unref (block);
680
g_list_foreach (object_proxies, (GFunc) g_object_unref, NULL);
681
g_list_free (object_proxies);
685
/* ---------------------------------------------------------------------------------------------------- */
688
get_top_level_blocks_for_drive (UDisksClient *client,
689
const gchar *drive_object_path)
693
GList *object_proxies;
694
GDBusObjectManager *object_manager;
696
object_manager = udisks_client_get_object_manager (client);
697
object_proxies = g_dbus_object_manager_get_objects (object_manager);
700
for (l = object_proxies; l != NULL; l = l->next)
702
UDisksObject *object = UDISKS_OBJECT (l->data);
704
UDisksPartition *partition;
706
block = udisks_object_get_block (object);
707
partition = udisks_object_peek_partition (object);
711
if (g_strcmp0 (udisks_block_get_drive (block), drive_object_path) == 0 &&
714
ret = g_list_append (ret, g_object_ref (object));
716
g_object_unref (block);
718
g_list_foreach (object_proxies, (GFunc) g_object_unref, NULL);
719
g_list_free (object_proxies);
724
* udisks_client_get_block_for_drive:
725
* @client: A #UDisksClient.
726
* @drive: A #UDisksDrive.
727
* @get_physical: %TRUE to get a physical device, %FALSE to get the logical device.
729
* Gets a block device corresponding to @drive. The returned block
730
* device, if any, is for the whole disk drive, e.g. a partition block
731
* device is never returned.
733
* Set @get_physical to %TRUE if you need a block device that you can
734
* send low-level SCSI commands with (for multipath, this returns one
735
* of the physical paths). Set it to %FALSE if you need a block device
736
* that you can read/write data with (for multipath, this returns the
739
* Returns: (transfer full): A #UDisksBlock or %NULL if the requested
740
* kind of block device is not available - use g_object_unref() to
741
* free the returned object.
744
udisks_client_get_block_for_drive (UDisksClient *client,
746
gboolean get_physical)
748
UDisksBlock *ret = NULL;
750
GList *blocks = NULL;
753
g_return_val_if_fail (UDISKS_IS_CLIENT (client), NULL);
754
g_return_val_if_fail (UDISKS_IS_DRIVE (drive), NULL);
756
object = g_dbus_interface_get_object (G_DBUS_INTERFACE (drive));
760
blocks = get_top_level_blocks_for_drive (client, g_dbus_object_get_object_path (object));
761
for (l = blocks; l != NULL; l = l->next)
763
UDisksBlock *block = udisks_object_peek_block (UDISKS_OBJECT (l->data));
766
/* TODO: actually look at @get_physical */
767
ret = g_object_ref (block);
773
g_list_foreach (blocks, (GFunc) g_object_unref, NULL);
774
g_list_free (blocks);
779
* udisks_client_get_drive_for_block:
780
* @client: A #UDisksClient.
781
* @block: A #UDisksBlock.
783
* Gets the #UDisksDrive that @block belongs to, if any.
785
* Returns: (transfer full): A #UDisksDrive or %NULL if there is no
786
* #UDisksDrive for @block - free the returned object with
790
udisks_client_get_drive_for_block (UDisksClient *client,
793
UDisksDrive *ret = NULL;
796
g_return_val_if_fail (UDISKS_IS_CLIENT (client), NULL);
797
g_return_val_if_fail (UDISKS_IS_BLOCK (block), NULL);
799
object = g_dbus_object_manager_get_object (client->object_manager, udisks_block_get_drive (block));
801
ret = udisks_object_get_drive (UDISKS_OBJECT (object));
805
/* ---------------------------------------------------------------------------------------------------- */
819
const gchar *media_name;
820
const gchar *media_family;
821
const gchar *media_icon;
822
DriveType media_type;
823
const gchar *drive_icon;
826
/* Translators: 'Thumb' here refers to "USB thumb drive", see http://en.wikipedia.org/wiki/Thumb_drive */
827
{"thumb", NC_("media-type", "Thumb"), NC_("media-type", "Thumb"), "media-removable", DRIVE_TYPE_DRIVE, "media-removable"},
829
{"floppy", NC_("media-type", "Floppy"), NC_("media-type", "Floppy"), "media-floppy", DRIVE_TYPE_DISK, "drive-removable-media-floppy"},
830
{"floppy_zip", NC_("media-type", "Zip"), NC_("media-type", "Zip"), "media-floppy-jaz", DRIVE_TYPE_DISK, "drive-removable-media-floppy-jaz"},
831
{"floppy_jaz", NC_("media-type", "Jaz"), NC_("media-type", "Jaz"), "media-floppy-zip", DRIVE_TYPE_DISK, "drive-removable-media-floppy-zip"},
833
{"flash", NC_("media-type", "Flash"), NC_("media-type", "Flash"), "media-flash", DRIVE_TYPE_CARD, "drive-removable-media-flash"},
834
{"flash_ms", NC_("media-type", "MemoryStick"), NC_("media-type", "MemoryStick"), "media-flash-ms", DRIVE_TYPE_CARD, "drive-removable-media-flash-ms"},
835
{"flash_sm", NC_("media-type", "SmartMedia"), NC_("media-type", "SmartMedia"), "media-flash-sm", DRIVE_TYPE_CARD, "drive-removable-media-flash-sm"},
836
{"flash_cf", NC_("media-type", "CompactFlash"), NC_("media-type", "CompactFlash"), "media-flash-cf", DRIVE_TYPE_CARD, "drive-removable-media-flash-cf"},
837
{"flash_mmc", NC_("media-type", "MMC"), NC_("media-type", "SD"), "media-flash-mmc", DRIVE_TYPE_CARD, "drive-removable-media-flash-mmc"},
838
{"flash_sd", NC_("media-type", "SD"), NC_("media-type", "SD"), "media-flash-sd", DRIVE_TYPE_CARD, "drive-removable-media-flash-sd"},
839
{"flash_sdxc", NC_("media-type", "SDXC"), NC_("media-type", "SD"), "media-flash-sd-xc", DRIVE_TYPE_CARD, "drive-removable-media-flash-sd-xc"},
840
{"flash_sdhc", NC_("media-type", "SDHC"), NC_("media-type", "SD"), "media-flash-sd-hc", DRIVE_TYPE_CARD, "drive-removable-media-flash-sd-hc"},
842
{"optical_cd", NC_("media-type", "CD-ROM"), NC_("media-type", "CD"), "media-optical-cd-rom", DRIVE_TYPE_DISC, "drive-optical"},
843
{"optical_cd_r", NC_("media-type", "CD-R"), NC_("media-type", "CD"), "media-optical-cd-r", DRIVE_TYPE_DISC, "drive-optical-recorder"},
844
{"optical_cd_rw", NC_("media-type", "CD-RW"), NC_("media-type", "CD"), "media-optical-cd-rw", DRIVE_TYPE_DISC, "drive-optical-recorder"},
845
{"optical_dvd", NC_("media-type", "DVD"), NC_("media-type", "DVD"), "media-optical-dvd-rom", DRIVE_TYPE_DISC, "drive-optical"},
846
{"optical_dvd_r", NC_("media-type", "DVD-R"), NC_("media-type", "DVD"), "media-optical-dvd-r", DRIVE_TYPE_DISC, "drive-optical-recorder"},
847
{"optical_dvd_rw", NC_("media-type", "DVD-RW"), NC_("media-type", "DVD"), "media-optical-dvd-rw", DRIVE_TYPE_DISC, "drive-optical-recorder"},
848
{"optical_dvd_ram", NC_("media-type", "DVD-RAM"), NC_("media-type", "DVD"), "media-optical-dvd-ram", DRIVE_TYPE_DISC, "drive-optical-recorder"},
849
{"optical_dvd_plus_r", NC_("media-type", "DVD+R"), NC_("media-type", "DVD"), "media-optical-dvd-r-plus", DRIVE_TYPE_DISC, "drive-optical-recorder"},
850
{"optical_dvd_plus_rw", NC_("media-type", "DVD+RW"), NC_("media-type", "DVD"), "media-optical-dvd-rw-plus", DRIVE_TYPE_DISC, "drive-optical-recorder"},
851
{"optical_dvd_plus_r_dl", NC_("media-type", "DVD+R DL"), NC_("media-type", "DVD"), "media-optical-dvd-dl-r-plus", DRIVE_TYPE_DISC, "drive-optical-recorder"},
852
{"optical_dvd_plus_rw_dl", NC_("media-type", "DVD+RW DL"), NC_("media-type", "DVD"), "media-optical-dvd-dl-r-plus", DRIVE_TYPE_DISC, "drive-optical-recorder"},
853
{"optical_bd", NC_("media-type", "BD-ROM"), NC_("media-type", "Blu-Ray"), "media-optical-bd-rom", DRIVE_TYPE_DISC, "drive-optical"},
854
{"optical_bd_r", NC_("media-type", "BD-R"), NC_("media-type", "Blu-Ray"), "media-optical-bd-r", DRIVE_TYPE_DISC, "drive-optical-recorder"},
855
{"optical_bd_re", NC_("media-type", "BD-RE"), NC_("media-type", "Blu-Ray"), "media-optical-bd-re", DRIVE_TYPE_DISC, "drive-optical-recorder"},
856
{"optical_hddvd", NC_("media-type", "HDDVD"), NC_("media-type", "HDDVD"), "media-optical-hddvd-rom", DRIVE_TYPE_DISC, "drive-optical"},
857
{"optical_hddvd_r", NC_("media-type", "HDDVD-R"), NC_("media-type", "HDDVD"), "media-optical-hddvd-r", DRIVE_TYPE_DISC, "drive-optical-recorder"},
858
{"optical_hddvd_rw", NC_("media-type", "HDDVD-RW"), NC_("media-type", "HDDVD"), "media-optical-hddvd-rw", DRIVE_TYPE_DISC, "drive-optical-recorder"},
859
{"optical_mo", NC_("media-type", "MO"), NC_("media-type", "CD"), "media-optical-mo", DRIVE_TYPE_DISC, "drive-optical"},
860
{"optical_mrw", NC_("media-type", "MRW"), NC_("media-type", "CD"), "media-optical-mrw", DRIVE_TYPE_DISC, "drive-optical-recorder"},
861
{"optical_mrw_w", NC_("media-type", "MRW-W"), NC_("media-type", "CD"), "media-optical-mrw-w", DRIVE_TYPE_DISC, "drive-optical-recorder"},
864
/* ---------------------------------------------------------------------------------------------------- */
867
strv_has (const gchar * const *haystack,
875
for (n = 0; haystack != NULL && haystack[n] != NULL; n++)
877
if (g_strcmp0 (haystack[n], needle) == 0)
889
* udisks_client_get_drive_info:
890
* @client: A #UDisksClient.
891
* @drive: A #UDisksDrive.
892
* @out_name: (out) (allow-none): Return location for name or %NULL.
893
* @out_description: (out) (allow-none): Return location for description or %NULL.
894
* @out_drive_icon: (out) (allow-none): Return location for icon representing the drive or %NULL.
895
* @out_media_description: (out) (allow-none): Return location for description of the media or %NULL.
896
* @out_media_icon: (out) (allow-none): Return location for icon representing the media or %NULL.
898
* Gets information about a #UDisksDrive object that is suitable to
899
* present in an user interface. The returned strings are localized.
901
* If there is no media in @drive, then @out_media_icon is set to the
902
* same value as @out_drive_icon.
904
* If the @drive doesn't support removable media or if no media is
905
* available, then %NULL is always returned for @out_media_description
906
* and @out_media_icon.
908
* If the <link linkend="gdbus-property-org-freedesktop-UDisks2-Block.HintName">HintName</link>
910
* <link linkend="gdbus-property-org-freedesktop-UDisks2-Block.HintName">HintIconName</link>
911
* properties on the block device for @drive are set (see <xref linkend="udisks.8"/>),
912
* their values are returned in the drive and media
913
* description and icon (e.g. @out_description, @out_drive_icon, @out_media_description and @out_media_icon).
915
* The returned data is best described by example:
920
* <entry>Device / Media</entry>
921
* <entry>name</entry>
922
* <entry>description</entry>
923
* <entry>icon</entry>
924
* <entry>media_description</entry>
925
* <entry>media_icon</entry>
930
* <entry>USB Thumb Drive</entry>
931
* <entry>Kingston DataTraveler 2.0</entry>
932
* <entry>4.0 GB Thumb Drive</entry>
933
* <entry>media-removable</entry>
934
* <entry>NULL</entry>
935
* <entry>NULL</entry>
938
* <entry>Internal System Disk (Hard Disk)</entry>
939
* <entry>ST3320620AS</entry>
940
* <entry>320 GB Hard Disk</entry>
941
* <entry>drive-harddisk</entry>
942
* <entry>NULL</entry>
943
* <entry>NULL</entry>
946
* <entry>Internal System Disk (Solid State)</entry>
947
* <entry>INTEL SSDSA2MH080G1GC</entry>
948
* <entry>80 GB Disk</entry>
949
* <entry>drive-harddisk</entry>
950
* <entry>NULL</entry>
951
* <entry>NULL</entry>
954
* <entry>Optical Drive (empty)</entry>
955
* <entry>LITE-ON DVDRW SOHW-812S</entry>
956
* <entry>CD/DVD Drive</entry>
957
* <entry>drive-optical</entry>
958
* <entry>NULL</entry>
959
* <entry>NULL</entry>
962
* <entry>Optical Drive (with CD-ROM data disc)</entry>
963
* <entry>LITE-ON DVDRW SOHW-812S</entry>
964
* <entry>CD/DVD Drive</entry>
965
* <entry>drive-optical</entry>
966
* <entry>CD-ROM Disc</entry>
967
* <entry>media-optical-cd-rom</entry>
970
* <entry>Optical Drive (with mixed disc)</entry>
971
* <entry>LITE-ON DVDRW SOHW-812S</entry>
972
* <entry>CD/DVD Drive</entry>
973
* <entry>drive-optical</entry>
974
* <entry>Audio/Data CD-ROM Disc</entry>
975
* <entry>media-optical-cd-rom</entry>
978
* <entry>Optical Drive (with audio disc)</entry>
979
* <entry>LITE-ON DVDRW SOHW-812S</entry>
980
* <entry>CD/DVD Drive</entry>
981
* <entry>drive-optical</entry>
982
* <entry>Audio Disc</entry>
983
* <entry>media-optical-cd-audio</entry>
986
* <entry>Optical Drive (with DVD-ROM disc)</entry>
987
* <entry>LITE-ON DVDRW SOHW-812S</entry>
988
* <entry>CD/DVD Drive</entry>
989
* <entry>drive-optical</entry>
990
* <entry>DVD-ROM Disc</entry>
991
* <entry>media-optical-dvd-rom</entry>
994
* <entry>Optical Drive (with blank DVD-R disc)</entry>
995
* <entry>LITE-ON DVDRW SOHW-812S</entry>
996
* <entry>CD/DVD Drive</entry>
997
* <entry>drive-optical</entry>
998
* <entry>Blank DVD-R Disc</entry>
999
* <entry>media-optical-dvd-r</entry>
1002
* <entry>External USB Hard Disk</entry>
1003
* <entry>WD 2500JB External</entry>
1004
* <entry>250 GB Hard Disk</entry>
1005
* <entry>drive-harddisk-usb</entry>
1006
* <entry>NULL</entry>
1007
* <entry>NULL</entry>
1010
* <entry>USB Compact Flash Reader (without media)</entry>
1011
* <entry>BELKIN USB 2 HS-CF</entry>
1012
* <entry>Compact Flash Drive</entry>
1013
* <entry>drive-removable-media-flash-cf</entry>
1014
* <entry>NULL</entry>
1015
* <entry>NULL</entry>
1018
* <entry>USB Compact Flash Reader (with media)</entry>
1019
* <entry>BELKIN USB 2 HS-CF</entry>
1020
* <entry>Compact Flash Drive</entry>
1021
* <entry>drive-removable-media-flash-cf</entry>
1022
* <entry>Compact Flash media</entry>
1023
* <entry>media-flash-cf</entry>
1030
udisks_client_get_drive_info (UDisksClient *client,
1033
gchar **out_description,
1035
gchar **out_media_description,
1036
GIcon **out_media_icon)
1041
gchar *media_description;
1043
const gchar *vendor;
1046
const gchar *const *media_compat;
1047
gboolean media_available;
1048
gboolean media_removable;
1049
gboolean rotation_rate;
1054
DriveType desc_type;
1055
gchar *hyphenated_connection_bus;
1056
const gchar *connection_bus;
1057
UDisksBlock *block = NULL;
1059
g_return_if_fail (UDISKS_IS_DRIVE (drive));
1064
media_description = NULL;
1068
vendor = udisks_drive_get_vendor (drive);
1069
model = udisks_drive_get_model (drive);
1070
size = udisks_drive_get_size (drive);
1071
media_removable = udisks_drive_get_media_removable (drive);
1072
media_available = udisks_drive_get_media_available (drive);
1073
rotation_rate = udisks_drive_get_rotation_rate (drive);
1075
size_str = udisks_client_get_size_for_display (client, size, FALSE, FALSE);
1076
media = udisks_drive_get_media (drive);
1077
media_compat = udisks_drive_get_media_compatibility (drive);
1078
connection_bus = udisks_drive_get_connection_bus (drive);
1079
if (strlen (connection_bus) > 0)
1080
hyphenated_connection_bus = g_strdup_printf ("-%s", connection_bus);
1082
hyphenated_connection_bus = g_strdup ("");
1084
/* Name is easy - that's just "$vendor $model" */
1085
if (strlen (vendor) == 0)
1087
if (strlen (model) == 0)
1089
name = g_strdup_printf ("%s%s%s",
1090
vendor != NULL ? vendor : "",
1091
vendor != NULL ? " " : "",
1092
model != NULL ? model : "");
1094
desc_type = DRIVE_TYPE_UNSET;
1095
desc_str = g_string_new (NULL);
1096
for (n = 0; n < G_N_ELEMENTS (media_data) - 1; n++)
1099
if (strv_has (media_compat, media_data[n].id))
1102
icon = g_themed_icon_new_with_default_fallbacks (media_data[n].drive_icon);
1103
if (strstr (desc_str->str, media_data[n].media_family) == NULL)
1105
if (desc_str->len > 0)
1106
g_string_append (desc_str, "/");
1107
g_string_append (desc_str, g_dpgettext2 (GETTEXT_PACKAGE, "media-type", media_data[n].media_family));
1109
desc_type = media_data[n].media_type;
1112
if (media_removable && media_available)
1115
if (g_strcmp0 (media, media_data[n].id) == 0)
1117
if (media_description == NULL)
1119
switch (media_data[n].media_type)
1121
case DRIVE_TYPE_UNSET:
1122
g_assert_not_reached ();
1124
case DRIVE_TYPE_DRIVE:
1125
/* Translators: Used to describe drive without removable media. The %s is the type, e.g. 'Thumb' */
1126
media_description = g_strdup_printf (C_("drive-with-fixed-media", "%s Drive"), g_dpgettext2 (GETTEXT_PACKAGE, "media-type", media_data[n].media_name));
1128
case DRIVE_TYPE_DISK:
1129
/* Translators: Used to describe generic media. The %s is the type, e.g. 'Zip' or 'Floppy' */
1130
media_description = g_strdup_printf (C_("drive-with-generic-media", "%s Disk"), g_dpgettext2 (GETTEXT_PACKAGE, "media-type", media_data[n].media_name));
1132
case DRIVE_TYPE_CARD:
1133
/* Translators: Used to describe flash media. The %s is the type, e.g. 'SD' or 'CompactFlash' */
1134
media_description = g_strdup_printf (C_("flash-media", "%s Card"), g_dpgettext2 (GETTEXT_PACKAGE, "media-type", media_data[n].media_name));
1136
case DRIVE_TYPE_DISC:
1137
/* Translators: Used to describe optical discs. The %s is the type, e.g. 'CD-R' or 'DVD-ROM' */
1138
media_description = g_strdup_printf (C_("optical-media", "%s Disc"), g_dpgettext2 (GETTEXT_PACKAGE, "media-type", media_data[n].media_name));
1142
if (media_icon == NULL)
1143
media_icon = g_themed_icon_new_with_default_fallbacks (media_data[n].media_icon);
1150
case DRIVE_TYPE_UNSET:
1151
if (media_removable)
1153
if (size_str != NULL)
1155
/* Translators: Used to describe a drive. The %s is the size, e.g. '20 GB' */
1156
description = g_strdup_printf (C_("drive-with-size", "%s Drive"), size_str);
1160
/* Translators: Used to describe a drive we know very little about (removable media or size not known) */
1161
description = g_strdup (C_("generic-drive", "Drive"));
1166
if (rotation_rate == 0)
1168
if (size_str != NULL)
1170
/* Translators: Used to describe a non-rotating drive (rotation rate either unknown
1171
* or it's a solid-state drive). The %s is the size, e.g. '20 GB'. */
1172
description = g_strdup_printf (C_("disk-non-rotational", "%s Disk"), size_str);
1176
/* Translators: Used to describe a non-rotating drive (rotation rate either unknown
1177
* or it's a solid-state drive). The drive is either using removable media or its
1178
* size not known. */
1179
description = g_strdup (C_("disk-non-rotational", "Disk"));
1184
if (size_str != NULL)
1186
/* Translators: Used to describe a hard-disk drive (HDD). The %s is the size, e.g. '20 GB'. */
1187
description = g_strdup_printf (C_("disk-hdd", "%s Hard Disk"), size_str);
1191
/* Translators: Used to describe a hard-disk drive (HDD) (removable media or size not known) */
1192
description = g_strdup (C_("disk-hdd", "Hard Disk"));
1198
case DRIVE_TYPE_CARD:
1199
/* Translators: Used to describe a card reader. The %s is the card type e.g. 'CompactFlash'. */
1200
description = g_strdup_printf (C_("drive-card-reader", "%s Card Reader"), desc_str->str);
1203
case DRIVE_TYPE_DRIVE: /* explicit fall-through */
1204
case DRIVE_TYPE_DISK: /* explicit fall-through */
1205
case DRIVE_TYPE_DISC:
1206
if (!media_removable && size_str != NULL)
1208
/* Translators: Used to describe drive. The first %s is the size e.g. '20 GB' and the
1209
* second %s is the drive type e.g. 'Thumb'.
1211
description = g_strdup_printf (C_("drive-with-size-and-type", "%s %s Drive"), size_str, desc_str->str);
1215
/* Translators: Used to describe drive. The first %s is the drive type e.g. 'Thumb'.
1217
description = g_strdup_printf (C_("drive-with-type", "%s Drive"), desc_str->str);
1221
g_string_free (desc_str, TRUE);
1223
/* fallback for icon */
1227
if (media_removable)
1228
s = g_strdup_printf ("drive-removable-media%s", hyphenated_connection_bus);
1230
s = g_strdup_printf ("drive-harddisk%s", hyphenated_connection_bus);
1231
icon = g_themed_icon_new_with_default_fallbacks (s);
1234
/* fallback for media_icon */
1235
if (media_removable && media_available && media_icon == NULL)
1238
if (media_removable)
1239
s = g_strdup_printf ("drive-removable-media%s", hyphenated_connection_bus);
1241
s = g_strdup_printf ("drive-harddisk%s", hyphenated_connection_bus);
1242
media_icon = g_themed_icon_new_with_default_fallbacks (s);
1246
/* prepend a qualifier to the media description, based on the disc state */
1247
if (udisks_drive_get_optical_blank (drive))
1250
/* Translators: String used for a blank disc. The %s is the disc type e.g. "CD-RW Disc" */
1251
s = g_strdup_printf (C_("optical-media", "Blank %s"), media_description);
1252
g_free (media_description);
1253
media_description = s;
1255
else if (udisks_drive_get_optical_num_audio_tracks (drive) > 0 &&
1256
udisks_drive_get_optical_num_data_tracks (drive) > 0)
1259
/* Translators: String used for a mixed disc. The %s is the disc type e.g. "CD-ROM Disc" */
1260
s = g_strdup_printf (C_("optical-media", "Mixed %s"), media_description);
1261
g_free (media_description);
1262
media_description = s;
1264
else if (udisks_drive_get_optical_num_audio_tracks (drive) > 0 &&
1265
udisks_drive_get_optical_num_data_tracks (drive) == 0)
1268
/* Translators: String used for an audio disc. The %s is the disc type e.g. "CD-ROM Disc" */
1269
s = g_strdup_printf (C_("optical-media", "Audio %s"), media_description);
1270
g_free (media_description);
1271
media_description = s;
1274
/* Apply UDISKS_NAME and UDISKS_ICON_NAME hints, if available */
1275
block = udisks_client_get_block_for_drive (client, drive, TRUE);
1280
s = udisks_block_get_hint_name (block);
1281
if (s != NULL && strlen (s) > 0)
1283
g_free (description);
1284
g_free (media_description);
1285
description = g_strdup (s);
1286
media_description = g_strdup (s);
1289
s = udisks_block_get_hint_icon_name (block);
1290
if (s != NULL && strlen (s) > 0)
1292
g_clear_object (&icon);
1293
g_clear_object (&media_icon);
1294
icon = g_themed_icon_new_with_default_fallbacks (s);
1295
media_icon = g_themed_icon_new_with_default_fallbacks (s);
1301
g_print ("mr=%d,ma=%d dd=%s, md=%s and di='%s', mi='%s'\n",
1306
icon == NULL ? "" : g_icon_to_string (icon),
1307
media_icon == NULL ? "" : g_icon_to_string (media_icon));
1310
/* return values to caller */
1311
if (out_name != NULL)
1315
if (out_description != NULL)
1316
*out_description = description;
1318
g_free (description);
1319
if (out_icon != NULL)
1321
else if (icon != NULL)
1322
g_object_unref (icon);
1323
if (out_media_description != NULL)
1324
*out_media_description = media_description;
1326
g_free (media_description);
1327
if (out_media_icon != NULL)
1328
*out_media_icon = media_icon;
1329
else if (media_icon != NULL)
1330
g_object_unref (media_icon);
1332
g_free (hyphenated_connection_bus);
1335
g_clear_object (&block);
1338
/* ---------------------------------------------------------------------------------------------------- */
1341
add_item (gchar **items_str,
1344
gchar *orig = *items_str;
1345
if (*items_str == NULL)
1347
*items_str = g_strdup (item);
1352
*items_str = g_strdup_printf ("%s, %s", orig, item);
1358
* udisks_client_get_partition_info:
1359
* @client: A #UDisksClient.
1360
* @partition: # #UDisksPartition.
1362
* Gets information about @partition that is suitable to present in an
1363
* user interface in a single line of text.
1365
* The returned string is localized and includes things like the
1366
* partition type, flags (if any) and name (if any).
1368
* Returns: (transfer full): A string that should be freed with g_free().
1371
udisks_client_get_partition_info (UDisksClient *client,
1372
UDisksPartition *partition)
1375
const gchar *type_str = NULL;
1376
gchar *flags_str = NULL;
1377
UDisksPartitionTable *table = NULL;
1380
g_return_val_if_fail (UDISKS_IS_CLIENT (client), NULL);
1381
g_return_val_if_fail (UDISKS_IS_PARTITION (partition), NULL);
1383
table = udisks_client_get_partition_table (client, partition);
1387
flags = udisks_partition_get_flags (partition);
1388
if (g_strcmp0 (udisks_partition_table_get_type_ (table), "dos") == 0)
1392
/* Translators: Corresponds to the DOS/Master-Boot-Record "bootable" flag for a partition */
1393
add_item (&flags_str, C_("dos-part-flag", "Bootable"));
1396
else if (g_strcmp0 (udisks_partition_table_get_type_ (table), "gpt") == 0)
1398
if (flags & (1ULL<<0))
1400
/* Translators: Corresponds to the GPT "system" flag for a partition,
1401
* see http://en.wikipedia.org/wiki/GUID_Partition_Table
1403
add_item (&flags_str, C_("gpt-part-flag", "System"));
1405
if (flags & (1ULL<<2))
1407
/* Translators: Corresponds to the GPT "legacy bios bootable" flag for a partition,
1408
* see http://en.wikipedia.org/wiki/GUID_Partition_Table
1410
add_item (&flags_str, C_("gpt-part-flag", "Legacy BIOS Bootable"));
1412
if (flags & (1ULL<<60))
1414
/* Translators: Corresponds to the GPT "read-only" flag for a partition,
1415
* see http://en.wikipedia.org/wiki/GUID_Partition_Table
1417
add_item (&flags_str, C_("gpt-part-flag", "Read-only"));
1419
if (flags & (1ULL<<62))
1421
/* Translators: Corresponds to the GPT "hidden" flag for a partition,
1422
* see http://en.wikipedia.org/wiki/GUID_Partition_Table
1424
add_item (&flags_str, C_("gpt-part-flag", "Hidden"));
1426
if (flags & (1ULL<<63))
1428
/* Translators: Corresponds to the GPT "no automount" flag for a partition,
1429
* see http://en.wikipedia.org/wiki/GUID_Partition_Table
1431
add_item (&flags_str, C_("gpt-part-flag", "No Automount"));
1435
type_str = udisks_client_get_partition_type_for_display (client,
1436
udisks_partition_table_get_type_ (table),
1437
udisks_partition_get_type_ (partition));
1438
if (type_str == NULL)
1439
type_str = udisks_partition_get_type_ (partition);
1441
if (flags_str != NULL)
1443
/* Translators: Partition info. First %s is the type, second %s is a list of flags */
1444
ret = g_strdup_printf (C_("partition-info", "%s (%s)"), type_str, flags_str);
1448
ret = g_strdup (type_str);
1451
if (ret == NULL || strlen (ret) == 0)
1454
/* Translators: The Partition info when unknown */
1455
ret = g_strdup (C_("partition-info", "Unknown"));
1459
g_object_unref (table);
1464
/* ---------------------------------------------------------------------------------------------------- */
1467
* udisks_client_get_cleartext_block:
1468
* @client: A #UDisksClient.
1469
* @block: A #UDisksBlock.
1471
* If @block is an unlocked encrypted device, gets the cleartext device.
1473
* Returns: (transfer full): A #UDisksBlock or %NULL. Free with
1474
* g_object_unref() when done with it.
1477
udisks_client_get_cleartext_block (UDisksClient *client,
1480
UDisksBlock *ret = NULL;
1481
GDBusObject *object;
1482
const gchar *object_path;
1483
GList *objects = NULL;
1486
object = g_dbus_interface_get_object (G_DBUS_INTERFACE (block));
1490
object_path = g_dbus_object_get_object_path (object);
1491
objects = g_dbus_object_manager_get_objects (client->object_manager);
1492
for (l = objects; l != NULL; l = l->next)
1494
UDisksObject *iter_object = UDISKS_OBJECT (l->data);
1495
UDisksBlock *iter_block;
1497
iter_block = udisks_object_peek_block (iter_object);
1498
if (iter_block == NULL)
1501
if (g_strcmp0 (udisks_block_get_crypto_backing_device (iter_block), object_path) == 0)
1503
ret = g_object_ref (iter_block);
1509
g_list_foreach (objects, (GFunc) g_object_unref, NULL);
1510
g_list_free (objects);
1514
/* ---------------------------------------------------------------------------------------------------- */
1517
* udisks_client_get_partitions:
1518
* @client: A #UDisksClient.
1519
* @table: A #UDisksPartitionTable.
1521
* Gets all partitions of @table.
1523
* Returns: (transfer full) (element-type UDisksPartition): A list of #UDisksPartition instances. The
1524
* returned list should be freed with g_list_free() after each
1525
* element has been freed with g_object_unref().
1528
udisks_client_get_partitions (UDisksClient *client,
1529
UDisksPartitionTable *table)
1532
GDBusObject *table_object;
1533
const gchar *table_object_path;
1534
GList *l, *object_proxies = NULL;
1536
g_return_val_if_fail (UDISKS_IS_CLIENT (client), NULL);
1537
g_return_val_if_fail (UDISKS_IS_PARTITION_TABLE (table), NULL);
1539
table_object = g_dbus_interface_get_object (G_DBUS_INTERFACE (table));
1540
if (table_object == NULL)
1542
table_object_path = g_dbus_object_get_object_path (table_object);
1544
object_proxies = g_dbus_object_manager_get_objects (client->object_manager);
1545
for (l = object_proxies; l != NULL; l = l->next)
1547
UDisksObject *object = UDISKS_OBJECT (l->data);
1548
UDisksPartition *partition;
1550
partition = udisks_object_get_partition (object);
1551
if (partition == NULL)
1554
if (g_strcmp0 (udisks_partition_get_table (partition), table_object_path) == 0)
1555
ret = g_list_prepend (ret, g_object_ref (partition));
1557
g_object_unref (partition);
1559
ret = g_list_reverse (ret);
1561
g_list_foreach (object_proxies, (GFunc) g_object_unref, NULL);
1562
g_list_free (object_proxies);
1567
* udisks_client_get_partition_table:
1568
* @client: A #UDisksClient.
1569
* @partition: A #UDisksPartition.
1571
* Gets the #UDisksPartitionTable corresponding to @partition.
1573
* Returns: (transfer full): A #UDisksPartitionTable. Free with g_object_unref().
1575
UDisksPartitionTable *
1576
udisks_client_get_partition_table (UDisksClient *client,
1577
UDisksPartition *partition)
1579
UDisksPartitionTable *ret = NULL;
1580
UDisksObject *object;
1582
g_return_val_if_fail (UDISKS_IS_CLIENT (client), NULL);
1583
g_return_val_if_fail (UDISKS_IS_PARTITION (partition), NULL);
1585
object = udisks_client_get_object (client, udisks_partition_get_table (partition));
1589
ret = udisks_object_get_partition_table (object);
1590
g_object_unref (object);
1597
* udisks_client_get_loop_for_block:
1598
* @client: A #UDisksClient.
1599
* @block: A #UDisksBlock.
1601
* Gets the corresponding loop interface for @block.
1603
* This only works if @block itself is a loop device or a partition of
1606
* Returns: (transfer full): A #UDisksLoop or %NULL. Free with g_object_unref().
1609
udisks_client_get_loop_for_block (UDisksClient *client,
1612
UDisksPartition *partition;
1613
UDisksObject *object = NULL;
1614
UDisksLoop *ret = NULL;
1616
g_return_val_if_fail (UDISKS_IS_CLIENT (client), NULL);
1617
g_return_val_if_fail (UDISKS_IS_BLOCK (block), NULL);
1619
object = (UDisksObject *) g_dbus_interface_dup_object (G_DBUS_INTERFACE (block));
1623
ret = udisks_object_get_loop (object);
1627
/* Could be we're a partition of a loop device */
1628
partition = udisks_object_get_partition (object);
1629
if (partition != NULL)
1631
UDisksPartitionTable *partition_table;
1632
partition_table = udisks_client_get_partition_table (client, partition);
1633
if (partition_table != NULL)
1635
UDisksObject *partition_table_object;
1636
partition_table_object = (UDisksObject *) g_dbus_interface_dup_object (G_DBUS_INTERFACE (partition_table));
1637
if (partition_table_object != NULL)
1639
ret = udisks_object_get_loop (UDISKS_OBJECT (partition_table_object));
1640
g_object_unref (partition_table_object);
1642
g_object_unref (partition_table);
1644
g_object_unref (partition);
1648
g_clear_object (&object);
1652
/* ---------------------------------------------------------------------------------------------------- */
1655
* udisks_client_get_jobs_for_object:
1656
* @client: A #UDisksClient.
1657
* @object: A #UDisksObject.
1659
* Gets all the #UDisksJob instances that reference @object, if any.
1661
* Returns: (transfer full) (element-type UDisksJob): A list of #UDisksJob instances. The
1662
* returned list should be freed with g_list_free() after each
1663
* element has been freed with g_object_unref().
1666
udisks_client_get_jobs_for_object (UDisksClient *client,
1667
UDisksObject *object)
1670
const gchar *object_path;
1671
GList *l, *object_proxies = NULL;
1673
/* TODO: this is probably slow. Can optimize by maintaining a hash-table from object path to UDisksJob* */
1675
g_return_val_if_fail (UDISKS_IS_CLIENT (client), NULL);
1676
g_return_val_if_fail (UDISKS_IS_OBJECT (object), NULL);
1678
object_path = g_dbus_object_get_object_path (G_DBUS_OBJECT (object));
1680
object_proxies = g_dbus_object_manager_get_objects (client->object_manager);
1681
for (l = object_proxies; l != NULL; l = l->next)
1683
UDisksObject *job_object = UDISKS_OBJECT (l->data);
1686
job = udisks_object_get_job (job_object);
1689
const gchar *const *object_paths;
1691
object_paths = udisks_job_get_objects (job);
1692
for (n = 0; object_paths != NULL && object_paths[n] != NULL; n++)
1694
if (g_strcmp0 (object_paths[n], object_path) == 0)
1695
ret = g_list_prepend (ret, g_object_ref (job));
1697
g_object_unref (job);
1700
ret = g_list_reverse (ret);
1702
g_list_foreach (object_proxies, (GFunc) g_object_unref, NULL);
1703
g_list_free (object_proxies);
1707
/* ---------------------------------------------------------------------------------------------------- */
1710
maybe_emit_changed_now (UDisksClient *client)
1712
if (client->changed_timeout_source == NULL)
1715
g_source_destroy (client->changed_timeout_source);
1716
client->changed_timeout_source = NULL;
1718
g_signal_emit (client, signals[CHANGED_SIGNAL], 0);
1726
on_changed_timeout (gpointer user_data)
1728
UDisksClient *client = UDISKS_CLIENT (user_data);
1729
client->changed_timeout_source = NULL;
1730
g_signal_emit (client, signals[CHANGED_SIGNAL], 0);
1731
return FALSE; /* remove source */
1735
queue_changed (UDisksClient *client)
1737
if (client->changed_timeout_source != NULL)
1740
client->changed_timeout_source = g_timeout_source_new (100);
1741
g_source_set_callback (client->changed_timeout_source,
1742
(GSourceFunc) on_changed_timeout,
1744
NULL); /* destroy notify */
1745
g_source_attach (client->changed_timeout_source, client->context);
1746
g_source_unref (client->changed_timeout_source);
1753
on_object_added (GDBusObjectManager *manager,
1754
GDBusObject *object,
1757
UDisksClient *client = UDISKS_CLIENT (user_data);
1758
GList *interfaces, *l;
1760
interfaces = g_dbus_object_get_interfaces (object);
1761
for (l = interfaces; l != NULL; l = l->next)
1763
init_interface_proxy (client, G_DBUS_PROXY (l->data));
1765
g_list_foreach (interfaces, (GFunc) g_object_unref, NULL);
1766
g_list_free (interfaces);
1768
queue_changed (client);
1772
on_object_removed (GDBusObjectManager *manager,
1773
GDBusObject *object,
1776
UDisksClient *client = UDISKS_CLIENT (user_data);
1777
queue_changed (client);
1781
init_interface_proxy (UDisksClient *client,
1784
/* disable method timeouts */
1785
g_dbus_proxy_set_default_timeout (proxy, G_MAXINT);
1789
on_interface_added (GDBusObjectManager *manager,
1790
GDBusObject *object,
1791
GDBusInterface *interface,
1794
UDisksClient *client = UDISKS_CLIENT (user_data);
1796
init_interface_proxy (client, G_DBUS_PROXY (interface));
1798
queue_changed (client);
1802
on_interface_removed (GDBusObjectManager *manager,
1803
GDBusObject *object,
1804
GDBusInterface *interface,
1807
UDisksClient *client = UDISKS_CLIENT (user_data);
1808
queue_changed (client);
1812
on_interface_proxy_properties_changed (GDBusObjectManagerClient *manager,
1813
GDBusObjectProxy *object_proxy,
1814
GDBusProxy *interface_proxy,
1815
GVariant *changed_properties,
1816
const gchar *const *invalidated_properties,
1819
UDisksClient *client = UDISKS_CLIENT (user_data);
1820
queue_changed (client);
1823
/* ---------------------------------------------------------------------------------------------------- */
1825
#define KILOBYTE_FACTOR 1000.0
1826
#define MEGABYTE_FACTOR (1000.0 * 1000.0)
1827
#define GIGABYTE_FACTOR (1000.0 * 1000.0 * 1000.0)
1828
#define TERABYTE_FACTOR (1000.0 * 1000.0 * 1000.0 * 1000.0)
1830
#define KIBIBYTE_FACTOR 1024.0
1831
#define MEBIBYTE_FACTOR (1024.0 * 1024.0)
1832
#define GIBIBYTE_FACTOR (1024.0 * 1024.0 * 1024.0)
1833
#define TEBIBYTE_FACTOR (1024.0 * 1024.0 * 1024.0 * 10242.0)
1836
get_pow2_size (guint64 size)
1839
gdouble displayed_size;
1843
if (size < MEBIBYTE_FACTOR)
1845
displayed_size = (double) size / KIBIBYTE_FACTOR;
1848
else if (size < GIBIBYTE_FACTOR)
1850
displayed_size = (double) size / MEBIBYTE_FACTOR;
1853
else if (size < TEBIBYTE_FACTOR)
1855
displayed_size = (double) size / GIBIBYTE_FACTOR;
1860
displayed_size = (double) size / TEBIBYTE_FACTOR;
1864
if (displayed_size < 10.0)
1869
str = g_strdup_printf ("%.*f %s", digits, displayed_size, unit);
1875
get_pow10_size (guint64 size)
1878
gdouble displayed_size;
1882
if (size < MEGABYTE_FACTOR)
1884
displayed_size = (double) size / KILOBYTE_FACTOR;
1887
else if (size < GIGABYTE_FACTOR)
1889
displayed_size = (double) size / MEGABYTE_FACTOR;
1892
else if (size < TERABYTE_FACTOR)
1894
displayed_size = (double) size / GIGABYTE_FACTOR;
1899
displayed_size = (double) size / TERABYTE_FACTOR;
1903
if (displayed_size < 10.0)
1908
str = g_strdup_printf ("%.*f %s", digits, displayed_size, unit);
1914
* udisks_client_get_size_for_display:
1915
* @client: A #UDisksClient.
1916
* @size: Size in bytes
1917
* @use_pow2: Whether power-of-two units should be used instead of power-of-ten units.
1918
* @long_string: Whether to produce a long string.
1920
* Utility function to get a human-readable string that represents @size.
1922
* Returns: A string that should be freed with g_free().
1925
udisks_client_get_size_for_display (UDisksClient *client,
1928
gboolean long_string)
1935
size_str = g_strdup_printf ("%'" G_GINT64_FORMAT, size);
1939
pow2_str = get_pow2_size (size);
1940
/* Translators: The first %s is the size in power-of-2 units, e.g. '64 KiB'
1941
* the second %s is the size as a number e.g. '65,536' (always > 1)
1943
str = g_strdup_printf (C_("byte-size-pow2", "%s (%s bytes)"), pow2_str, size_str);
1949
pow10_str = get_pow10_size (size);
1950
/* Translators: The first %s is the size in power-of-10 units, e.g. '100 kB'
1951
* the second %s is the size as a number e.g. '100,000' (always > 1)
1953
str = g_strdup_printf (C_("byte-size-pow10", "%s (%s bytes)"), pow10_str, size_str);
1963
str = get_pow2_size (size);
1967
str = get_pow10_size (size);
1973
/* ---------------------------------------------------------------------------------------------------- */
1976
* udisks_client_get_media_compat_for_display:
1977
* @client: A #UDisksClient.
1978
* @media_compat: An array of media types.
1980
* Gets a human-readable string of the media described by
1981
* @media_compat. The returned information is localized.
1983
* Returns: A string that should be freed with g_free() or %NULL if
1987
udisks_client_get_media_compat_for_display (UDisksClient *client,
1988
const gchar* const *media_compat)
1991
gboolean optical_cd;
1992
gboolean optical_dvd;
1993
gboolean optical_bd;
1994
gboolean optical_hddvd;
1998
optical_dvd = FALSE;
2000
optical_hddvd = FALSE;
2002
result = g_string_new (NULL);
2004
for (n = 0; media_compat != NULL && media_compat[n] != NULL; n++)
2006
const gchar *media_name;
2009
media = media_compat[n];
2011
if (g_strcmp0 (media, "flash_cf") == 0)
2013
/* Translators: This word is used to describe the media inserted into a device */
2014
media_name = C_("media", "CompactFlash");
2016
else if (g_strcmp0 (media, "flash_ms") == 0)
2018
/* Translators: This word is used to describe the media inserted into a device */
2019
media_name = C_("media", "MemoryStick");
2021
else if (g_strcmp0 (media, "flash_sm") == 0)
2023
/* Translators: This word is used to describe the media inserted into a device */
2024
media_name = C_("media", "SmartMedia");
2026
else if (g_strcmp0 (media, "flash_sd") == 0)
2028
/* Translators: This word is used to describe the media inserted into a device */
2029
media_name = C_("media", "SecureDigital");
2031
else if (g_strcmp0 (media, "flash_sdhc") == 0)
2033
/* Translators: This word is used to describe the media inserted into a device */
2034
media_name = C_("media", "SD High Capacity");
2036
else if (g_strcmp0 (media, "floppy") == 0)
2038
/* Translators: This word is used to describe the media inserted into a device */
2039
media_name = C_("media", "Floppy");
2041
else if (g_strcmp0 (media, "floppy_zip") == 0)
2043
/* Translators: This word is used to describe the media inserted into a device */
2044
media_name = C_("media", "Zip");
2046
else if (g_strcmp0 (media, "floppy_jaz") == 0)
2048
/* Translators: This word is used to describe the media inserted into a device */
2049
media_name = C_("media", "Jaz");
2051
else if (g_str_has_prefix (media, "flash"))
2053
/* Translators: This word is used to describe the media inserted into a device */
2054
media_name = C_("media", "Flash");
2056
else if (g_str_has_prefix (media, "optical_cd"))
2060
else if (g_str_has_prefix (media, "optical_dvd"))
2064
else if (g_str_has_prefix (media, "optical_bd"))
2068
else if (g_str_has_prefix (media, "optical_hddvd"))
2070
optical_hddvd = TRUE;
2073
if (media_name != NULL)
2075
if (result->len > 0)
2076
g_string_append_c (result, '/');
2077
g_string_append (result, media_name);
2083
if (result->len > 0)
2084
g_string_append_c (result, '/');
2085
/* Translators: This word is used to describe the optical disc type, it may appear
2086
* in a slash-separated list e.g. 'CD/DVD/Blu-Ray'
2088
g_string_append (result, C_("disc-type", "CD"));
2092
if (result->len > 0)
2093
g_string_append_c (result, '/');
2094
/* Translators: This word is used to describe the optical disc type, it may appear
2095
* in a slash-separated list e.g. 'CD/DVD/Blu-Ray'
2097
g_string_append (result, C_("disc-type", "DVD"));
2101
if (result->len > 0)
2102
g_string_append_c (result, '/');
2103
/* Translators: This word is used to describe the optical disc type, it may appear
2104
* in a slash-separated list e.g. 'CD/DVD/Blu-Ray'
2106
g_string_append (result, C_("disc-type", "Blu-Ray"));
2110
if (result->len > 0)
2111
g_string_append_c (result, '/');
2112
/* Translators: This word is used to describe the optical disc type, it may appear
2113
* in a slash-separated list e.g. 'CD/DVD/Blu-Ray'
2115
g_string_append (result, C_("disc-type", "HDDVD"));
2118
if (result->len > 0)
2119
return g_string_free (result, FALSE);
2121
g_string_free (result, TRUE);
2125
/* ---------------------------------------------------------------------------------------------------- */
2131
const gchar *version;
2132
const gchar *long_name;
2133
const gchar *short_name;
2136
{"filesystem", "vfat", "FAT12", NC_("fs-type", "FAT (12-bit version)"), NC_("fs-type", "FAT")},
2137
{"filesystem", "vfat", "FAT16", NC_("fs-type", "FAT (16-bit version)"), NC_("fs-type", "FAT")},
2138
{"filesystem", "vfat", "FAT32", NC_("fs-type", "FAT (32-bit version)"), NC_("fs-type", "FAT")},
2139
{"filesystem", "ntfs", "*", NC_("fs-type", "FAT (version %s)"), NC_("fs-type", "FAT")},
2140
{"filesystem", "vfat", NULL, NC_("fs-type", "FAT"), NC_("fs-type", "FAT")},
2141
{"filesystem", "ntfs", "*", NC_("fs-type", "NTFS (version %s)"), NC_("fs-type", "NTFS")},
2142
{"filesystem", "ntfs", NULL, NC_("fs-type", "NTFS"), NC_("fs-type", "NTFS")},
2143
{"filesystem", "hfs", NULL, NC_("fs-type", "HFS"), NC_("fs-type", "HFS")},
2144
{"filesystem", "hfsplus", NULL, NC_("fs-type", "HFS+"), NC_("fs-type", "HFS+")},
2145
{"filesystem", "ext2", "*", NC_("fs-type", "Ext2 (version %s)"), NC_("fs-type", "Ext2")},
2146
{"filesystem", "ext2", NULL, NC_("fs-type", "Ext2"), NC_("fs-type", "Ext2")},
2147
{"filesystem", "ext3", "*", NC_("fs-type", "Ext3 (version %s)"), NC_("fs-type", "Ext3")},
2148
{"filesystem", "ext3", NULL, NC_("fs-type", "Ext3"), NC_("fs-type", "Ext3")},
2149
{"filesystem", "ext4", "*", NC_("fs-type", "Ext4 (version %s)"), NC_("fs-type", "Ext4")},
2150
{"filesystem", "ext4", NULL, NC_("fs-type", "Ext4"), NC_("fs-type", "Ext4")},
2151
{"filesystem", "jdb", "*", NC_("fs-type", "Journal for Ext (version %s)"), NC_("fs-type", "JDB")},
2152
{"filesystem", "jdb", "*", NC_("fs-type", "Journal for Ext"), NC_("fs-type", "JDB")},
2153
{"filesystem", "xfs", "*", NC_("fs-type", "XFS (version %s)"), NC_("fs-type", "XFS")},
2154
{"filesystem", "xfs", NULL, NC_("fs-type", "XFS"), NC_("fs-type", "XFS")},
2155
/* TODO: No ID_FS_VERSION yet for btrfs... */
2156
{"filesystem", "btrfs", NULL, NC_("fs-type", "Btrfs"), NC_("fs-type", "Btrfs")},
2157
{"filesystem", "iso9660", "*", NC_("fs-type", "ISO 9660 (version %s)"), NC_("fs-type", "ISO9660")},
2158
{"filesystem", "iso9660", NULL, NC_("fs-type", "ISO 9660"), NC_("fs-type", "ISO9660")},
2159
{"filesystem", "udf", "*", NC_("fs-type", "UDF (version %s)"), NC_("fs-type", "UDF")},
2160
{"filesystem", "udf", NULL, NC_("fs-type", "UDF"), NC_("fs-type", "UDF")},
2161
{"other", "swap", "*", NC_("fs-type", "Swap (version %s)"), NC_("fs-type", "Swap")},
2162
{"other", "swap", NULL, NC_("fs-type", "Swap"), NC_("fs-type", "Swap")},
2163
{"raid", "LVM2_member", "*", NC_("fs-type", "LVM2 Physical Volume (%s)"), NC_("fs-type", "LVM2 PV")},
2164
{"raid", "LVM2_member", NULL, NC_("fs-type", "LVM2 Physical Volume"), NC_("fs-type", "LVM2 PV")},
2165
{"raid", "linux_raid_member", "*", NC_("fs-type", "Software RAID Component (version %s)"), NC_("fs-type", "MD Raid")},
2166
{"raid", "linux_raid_member", NULL, NC_("fs-type", "Software RAID Component"), NC_("fs-type", "MD Raid")},
2167
{"raid", "zfs_member", "*", NC_("fs-type", "ZFS Device (ZPool version %s)"), NC_("fs-type", "ZFS (v%s)")},
2168
{"raid", "zfs_member", NULL, NC_("fs-type", "ZFS Device"), NC_("fs-type", "ZFS")},
2169
{"crypto", "crypto_LUKS", "*", NC_("fs-type", "LUKS Encryption (version %s)"), NC_("fs-type", "LUKS")},
2170
{"crypto", "crypto_LUKS", NULL, NC_("fs-type", "LUKS Encryption"), NC_("fs-type", "LUKS")},
2171
{"filesystem", "VMFS", "*", NC_("fs-type", "VMFS (version %s)"), NC_("fs-type", "VMFS (v%s)")},
2172
{"filesystem", "VMFS", NULL, NC_("fs-type", "VMFS"), NC_("fs-type", "VMFS")},
2173
{"raid", "VMFS_volume_member", "*", NC_("fs-type", "VMFS Volume Member (version %s)"), NC_("fs-type", "VMFS Member (v%s)")},
2174
{"raid", "VMFS_volume_member", NULL, NC_("fs-type", "VMFS Volume Member"), NC_("fs-type", "VMFS Member")},
2175
{NULL, NULL, NULL, NULL}
2179
* udisks_client_get_id_for_display:
2180
* @client: A #UDisksClient.
2181
* @usage: Usage id e.g. "filesystem" or "crypto".
2182
* @type: Type e.g. "ext4" or "crypto_LUKS"
2183
* @version: Version.
2184
* @long_string: Whether to produce a long string.
2186
* Gets a human readable localized string for @usage, @type and @version.
2188
* Returns: A string that should be freed with g_free().
2191
udisks_client_get_id_for_display (UDisksClient *client,
2194
const gchar *version,
2195
gboolean long_string)
2202
for (n = 0; id_type[n].usage != NULL; n++)
2204
if (g_strcmp0 (id_type[n].usage, usage) == 0 &&
2205
g_strcmp0 (id_type[n].type, type) == 0)
2207
if ((id_type[n].version == NULL && strlen (version) == 0))
2210
ret = g_strdup (g_dpgettext2 (GETTEXT_PACKAGE, "fs-type", id_type[n].long_name));
2212
ret = g_strdup (g_dpgettext2 (GETTEXT_PACKAGE, "fs-type", id_type[n].short_name));
2215
else if ((g_strcmp0 (id_type[n].version, version) == 0 && strlen (version) > 0) ||
2216
(g_strcmp0 (id_type[n].version, "*") == 0 && strlen (version) > 0))
2218
/* we know better than the compiler here */
2219
#pragma GCC diagnostic push
2220
#pragma GCC diagnostic ignored "-Wformat-nonliteral"
2222
ret = g_strdup_printf (g_dpgettext2 (GETTEXT_PACKAGE, "fs-type", id_type[n].long_name), version);
2224
ret = g_strdup_printf (g_dpgettext2 (GETTEXT_PACKAGE, "fs-type", id_type[n].short_name), version);
2226
#pragma GCC diagnostic pop
2233
if (strlen (version) > 0)
2235
/* Translators: Shown for unknown filesystem types.
2236
* First %s is the raw filesystem type obtained from udev, second %s is version.
2238
ret = g_strdup_printf (C_("fs-type", "Unknown (%s %s)"), type, version);
2242
if (strlen (type) > 0)
2244
/* Translators: Shown for unknown filesystem types.
2245
* First %s is the raw filesystem type obtained from udev.
2247
ret = g_strdup_printf (C_("fs-type", "Unknown (%s)"), type);
2251
/* Translators: Shown for unknown filesystem types.
2253
ret = g_strdup (C_("fs-type", "Unknown"));
2259
if (strlen (type) > 0)
2261
ret = g_strdup (type);
2265
/* Translators: Shown for unknown filesystem types.
2267
ret = g_strdup (C_("fs-type", "Unknown"));
2275
/* ---------------------------------------------------------------------------------------------------- */
2281
} known_partition_table_types[] =
2283
/* Translators: name of partition table format */
2284
{"dos", N_("Master Boot Record")},
2285
/* Translators: name of partition table format */
2286
{"gpt", N_("GUID Partition Table")},
2287
/* Translators: name of partition table format */
2288
{"apm", N_("Apple Partition Map")},
2293
* udisks_client_get_partition_table_type_for_display:
2294
* @client: A #UDisksClient.
2295
* @partition_table_type: A partition table type e.g. 'dos' or 'gpt'.
2297
* Gets a human readable localized string for @partition_table_type.
2299
* Returns: A description of @partition_table_type or %NULL.
2302
udisks_client_get_partition_table_type_for_display (UDisksClient *client,
2303
const gchar *partition_table_type)
2305
const gchar *ret = NULL;
2308
for (n = 0; known_partition_table_types[n].type != NULL; n++)
2310
if (g_strcmp0 (known_partition_table_types[n].type, partition_table_type) == 0)
2312
ret = _(known_partition_table_types[n].name);
2321
/* ---------------------------------------------------------------------------------------------------- */
2326
const gchar *subtype;
2328
} known_partition_table_subtypes[] =
2330
/* Translators: name of partition table format */
2331
{"dos", "generic", NC_("partition-subtype", "Generic")},
2332
{"dos", "linux", NC_("partition-subtype", "Linux")},
2333
{"dos", "microsoft", NC_("partition-subtype", "Windows")},
2334
{"dos", "other", NC_("partition-subtype", "Other")},
2336
{"gpt", "generic", NC_("partition-subtype", "Generic")},
2337
{"gpt", "linux", NC_("partition-subtype", "Linux")},
2338
{"gpt", "microsoft", NC_("partition-subtype", "Windows")},
2339
{"gpt", "apple", NC_("partition-subtype", "Mac OS X")},
2340
{"gpt", "other", NC_("partition-subtype", "Other")},
2342
{"apm", "apple", NC_("partition-subtype", "Mac OS X")},
2343
{"apm", "microsoft", NC_("partition-subtype", "Windows")},
2348
* udisks_client_get_partition_table_subtype_for_display:
2349
* @client: A #UDisksClient.
2350
* @partition_table_type: A partition table type e.g. 'dos' or 'gpt'.
2351
* @partition_table_subtype: A partition table type e.g. 'dos' or 'gpt'.
2353
* Gets a human readable localized string for @partition_table_type and @partition_table_subtype.
2355
* Returns: A description of @partition_table_type and @partition_table_subtype or %NULL.
2358
udisks_client_get_partition_table_subtype_for_display (UDisksClient *client,
2359
const gchar *partition_table_type,
2360
const gchar *partition_table_subtype)
2362
const gchar *ret = NULL;
2365
for (n = 0; known_partition_table_subtypes[n].type != NULL; n++)
2367
if (g_strcmp0 (known_partition_table_subtypes[n].type, partition_table_type) == 0 &&
2368
g_strcmp0 (known_partition_table_subtypes[n].subtype, partition_table_subtype) == 0)
2370
ret = g_dpgettext2 (GETTEXT_PACKAGE, "partition-subtype", known_partition_table_subtypes[n].name);
2380
* udisks_client_get_partition_table_subtypes:
2381
* @client: A #UDisksClient.
2382
* @partition_table_type: A partition table type e.g. 'dos' or 'gpt'.
2384
* Gets all known subtypes for @partition_table_type.
2386
* Returns: (transfer container): A %NULL-terminated array of
2387
* strings. Only the container should be freed with g_free().
2390
udisks_client_get_partition_table_subtypes (UDisksClient *client,
2391
const gchar *partition_table_type)
2396
p = g_ptr_array_new();
2397
for (n = 0; known_partition_table_subtypes[n].type != NULL; n++)
2399
if (g_strcmp0 (known_partition_table_subtypes[n].type, partition_table_type) == 0)
2401
g_ptr_array_add (p, (gpointer) known_partition_table_subtypes[n].subtype);
2404
g_ptr_array_add (p, NULL);
2406
return (const gchar **) g_ptr_array_free (p, FALSE);
2409
/* ---------------------------------------------------------------------------------------------------- */
2412
#define F_SWAP UDISKS_PARTITION_TYPE_INFO_FLAGS_SWAP
2413
#define F_RAID UDISKS_PARTITION_TYPE_INFO_FLAGS_RAID
2414
#define F_HIDDEN UDISKS_PARTITION_TYPE_INFO_FLAGS_HIDDEN
2415
#define F_CONLY UDISKS_PARTITION_TYPE_INFO_FLAGS_CREATE_ONLY
2416
#define F_SYSTEM UDISKS_PARTITION_TYPE_INFO_FLAGS_SYSTEM
2420
const gchar *table_type;
2421
const gchar *table_subtype;
2424
UDisksPartitionTypeInfoFlags flags;
2425
} known_partition_types[] =
2427
/* see http://en.wikipedia.org/wiki/GUID_Partition_Table */
2429
/* Not associated with any OS */
2430
{"gpt", "generic", "024dee41-33e7-11d3-9d69-0008c781f39f", NC_("part-type", "MBR Partition Scheme"), F_SYSTEM},
2431
{"gpt", "generic", "c12a7328-f81f-11d2-ba4b-00a0c93ec93b", NC_("part-type", "EFI System"), F_SYSTEM},
2432
{"gpt", "generic", "21686148-6449-6e6f-744e-656564454649", NC_("part-type", "BIOS Boot"), F_SYSTEM},
2434
{"gpt", "linux", "0fc63daf-8483-4772-8e79-3d69d8477de4", NC_("part-type", "Linux Filesystem"), 0},
2435
{"gpt", "linux", "a19d880f-05fc-4d3b-a006-743f0f84911e", NC_("part-type", "Linux RAID"), F_RAID},
2436
{"gpt", "linux", "0657fd6d-a4ab-43c4-84e5-0933c84b4f4f", NC_("part-type", "Linux Swap"), F_SWAP},
2437
{"gpt", "linux", "e6d6d379-f507-44c2-a23c-238f2a3df928", NC_("part-type", "Linux LVM"), F_RAID},
2438
{"gpt", "linux", "8da63339-0007-60c0-c436-083ac8230908", NC_("part-type", "Linux Reserved"), 0},
2440
{"gpt", "microsoft", "ebd0a0a2-b9e5-4433-87c0-68b6b72699c7", NC_("part-type", "Basic Data"), 0},
2441
{"gpt", "microsoft", "e3c9e316-0b5c-4db8-817d-f92df00215ae", NC_("part-type", "Microsoft Reserved"), 0},
2442
{"gpt", "microsoft", "5808c8aa-7e8f-42e0-85d2-e1e90434cfb3", NC_("part-type", "Microsoft LDM metadata"), 0},
2443
{"gpt", "microsoft", "af9b60a0-1431-4f62-bc68-3311714a69ad", NC_("part-type", "Microsoft LDM data"), 0},
2444
{"gpt", "microsoft", "de94bba4-06d1-4d40-a16a-bfd50179d6ac", NC_("part-type", "Microsoft Windows Recovery Environment"), 0},
2446
{"gpt", "apple", "48465300-0000-11aa-aa11-00306543ecac", NC_("part-type", "Apple HFS/HFS+"), 0},
2447
{"gpt", "apple", "55465300-0000-11aa-aa11-00306543ecac", NC_("part-type", "Apple UFS"), 0},
2448
{"gpt", "apple", "6a898cc3-1dd2-11b2-99a6-080020736631", NC_("part-type", "Apple ZFS"), 0}, /* same as Solaris /usr */
2449
{"gpt", "apple", "52414944-0000-11aa-aa11-00306543ecac", NC_("part-type", "Apple RAID"), F_RAID},
2450
{"gpt", "apple", "52414944-5f4f-11aa-aa11-00306543ecac", NC_("part-type", "Apple RAID (offline)"), F_RAID},
2451
{"gpt", "apple", "426f6f74-0000-11aa-aa11-00306543ecac", NC_("part-type", "Apple Boot"), F_SYSTEM},
2452
{"gpt", "apple", "4c616265-6c00-11aa-aa11-00306543ecac", NC_("part-type", "Apple Label"), 0},
2453
{"gpt", "apple", "5265636f-7665-11aa-aa11-00306543ecac", NC_("part-type", "Apple TV Recovery"), F_SYSTEM},
2454
{"gpt", "apple", "53746f72-6167-11aa-aa11-00306543ecac", NC_("part-type", "Apple Core Storage"), F_RAID},
2456
{"gpt", "other", "75894c1e-3aeb-11d3-b7c1-7b03a0000000", NC_("part-type", "HP-UX Data"), 0},
2457
{"gpt", "other", "e2a1e728-32e3-11d6-a682-7b03a0000000", NC_("part-type", "HP-UX Service"), 0},
2459
{"gpt", "other", "83bd6b9d-7f41-11dc-be0b-001560b84f0f", NC_("part-type", "FreeBSD Boot"), 0},
2460
{"gpt", "other", "516e7cb4-6ecf-11d6-8ff8-00022d09712b", NC_("part-type", "FreeBSD Data"), 0},
2461
{"gpt", "other", "516e7cb5-6ecf-11d6-8ff8-00022d09712b", NC_("part-type", "FreeBSD Swap"), F_SWAP},
2462
{"gpt", "other", "516e7cb6-6ecf-11d6-8ff8-00022d09712b", NC_("part-type", "FreeBSD UFS"), 0},
2463
{"gpt", "other", "516e7cb8-6ecf-11d6-8ff8-00022d09712b", NC_("part-type", "FreeBSD Vinum"), F_RAID},
2464
{"gpt", "other", "516e7cba-6ecf-11d6-8ff8-00022d09712b", NC_("part-type", "FreeBSD ZFS"), 0},
2466
{"gpt", "other", "6a82cb45-1dd2-11b2-99a6-080020736631", NC_("part-type", "Solaris Boot"), 0},
2467
{"gpt", "other", "6a85cf4d-1dd2-11b2-99a6-080020736631", NC_("part-type", "Solaris Root"), 0},
2468
{"gpt", "other", "6a87c46f-1dd2-11b2-99a6-080020736631", NC_("part-type", "Solaris Swap"), F_SWAP},
2469
{"gpt", "other", "6a8b642b-1dd2-11b2-99a6-080020736631", NC_("part-type", "Solaris Backup"), 0},
2470
{"gpt", "other", "6a898cc3-1dd2-11b2-99a6-080020736631", NC_("part-type", "Solaris /usr"), 0}, /* same as Apple ZFS */
2471
{"gpt", "other", "6a8ef2e9-1dd2-11b2-99a6-080020736631", NC_("part-type", "Solaris /var"), 0},
2472
{"gpt", "other", "6a90ba39-1dd2-11b2-99a6-080020736631", NC_("part-type", "Solaris /home"), 0},
2473
{"gpt", "other", "6a9283a5-1dd2-11b2-99a6-080020736631", NC_("part-type", "Solaris Alternate Sector"), 0},
2474
{"gpt", "other", "6a945a3b-1dd2-11b2-99a6-080020736631", NC_("part-type", "Solaris Reserved"), 0},
2475
{"gpt", "other", "6a9630d1-1dd2-11b2-99a6-080020736631", NC_("part-type", "Solaris Reserved (2)"), 0},
2476
{"gpt", "other", "6a980767-1dd2-11b2-99a6-080020736631", NC_("part-type", "Solaris Reserved (3)"), 0},
2477
{"gpt", "other", "6a96237f-1dd2-11b2-99a6-080020736631", NC_("part-type", "Solaris Reserved (4)"), 0},
2478
{"gpt", "other", "6a8d2ac7-1dd2-11b2-99a6-080020736631", NC_("part-type", "Solaris Reserved (5)"), 0},
2480
{"gpt", "other", "49f48d32-b10e-11dc-b99b-0019d1879648", NC_("part-type", "NetBSD Swap"), F_SWAP},
2481
{"gpt", "other", "49f48d5a-b10e-11dc-b99b-0019d1879648", NC_("part-type", "NetBSD FFS"), 0},
2482
{"gpt", "other", "49f48d82-b10e-11dc-b99b-0019d1879648", NC_("part-type", "NetBSD LFS"), 0},
2483
{"gpt", "other", "49f48daa-b10e-11dc-b99b-0019d1879648", NC_("part-type", "NetBSD RAID"), F_RAID},
2484
{"gpt", "other", "2db519c4-b10f-11dc-b99b-0019d1879648", NC_("part-type", "NetBSD Concatenated"), 0},
2485
{"gpt", "other", "2db519ec-b10f-11dc-b99b-0019d1879648", NC_("part-type", "NetBSD Encrypted"), 0},
2486
/* VMWare, see http://blogs.vmware.com/vsphere/2011/08/vsphere-50-storage-features-part-7-gpt.html */
2487
{"gpt", "other", "aa31e02a-400f-11db-9590-000c2911d1b8", NC_("part-type", "VMWare VMFS"), 0},
2488
{"gpt", "other", "9d275380-40ad-11db-bf97-000c2911d1b8", NC_("part-type", "VMWare vmkcore"), 0},
2490
/* see http://developer.apple.com/documentation/mac/devices/devices-126.html
2491
* http://lists.apple.com/archives/Darwin-drivers/2003/May/msg00021.html */
2492
{"apm", "apple", "Apple_Unix_SVR2", NC_("part-type", "Apple UFS"), 0},
2493
{"apm", "apple", "Apple_HFS", NC_("part-type", "Apple HFS/HFS"), 0},
2494
{"apm", "apple", "Apple_partition_map", NC_("part-type", "Apple Partition Map"), 0},
2495
{"apm", "apple", "Apple_Free", NC_("part-type", "Unused"), 0},
2496
{"apm", "apple", "Apple_Scratch", NC_("part-type", "Empty"), 0},
2497
{"apm", "apple", "Apple_Driver", NC_("part-type", "Driver"), 0},
2498
{"apm", "apple", "Apple_Driver43", NC_("part-type", "Driver 4.3"), 0},
2499
{"apm", "apple", "Apple_PRODOS", NC_("part-type", "ProDOS file system"), 0},
2500
{"apm", "microsoft", "DOS_FAT_12", NC_("part-type", "FAT 12"), 0},
2501
{"apm", "microsoft", "DOS_FAT_16", NC_("part-type", "FAT 16"), 0},
2502
{"apm", "microsoft", "DOS_FAT_32", NC_("part-type", "FAT 32"), 0},
2503
{"apm", "microsoft", "Windows_FAT_16", NC_("part-type", "FAT 16 (Windows)"), 0},
2504
{"apm", "microsoft", "Windows_FAT_32", NC_("part-type", "FAT 32 (Windows)"), 0},
2506
/* see http://www.win.tue.nl/~aeb/partitions/partition_types-1.html */
2507
{"dos", "generic", "0x05", NC_("part-type", "Extended"), F_CONLY},
2508
{"dos", "generic", "0xee", NC_("part-type", "EFI GPT"), F_SYSTEM},
2509
{"dos", "generic", "0xef", NC_("part-type", "EFI (FAT-12/16/32)"), F_SYSTEM},
2510
{"dos", "linux", "0x82", NC_("part-type", "Linux swap"), F_SWAP},
2511
{"dos", "linux", "0x83", NC_("part-type", "Linux"), 0},
2512
{"dos", "linux", "0x85", NC_("part-type", "Linux Extended"), F_CONLY},
2513
{"dos", "linux", "0x8e", NC_("part-type", "Linux LVM"), F_RAID},
2514
{"dos", "linux", "0xfd", NC_("part-type", "Linux RAID auto"), F_RAID},
2515
{"dos", "microsoft", "0x01", NC_("part-type", "FAT12"), 0},
2516
{"dos", "microsoft", "0x04", NC_("part-type", "FAT16 <32M"), 0},
2517
{"dos", "microsoft", "0x06", NC_("part-type", "FAT16"), 0},
2518
{"dos", "microsoft", "0x07", NC_("part-type", "HPFS/NTFS"), 0},
2519
{"dos", "microsoft", "0x0b", NC_("part-type", "W95 FAT32"), 0},
2520
{"dos", "microsoft", "0x0c", NC_("part-type", "W95 FAT32 (LBA)"), 0},
2521
{"dos", "microsoft", "0x0e", NC_("part-type", "W95 FAT16 (LBA)"), 0},
2522
{"dos", "microsoft", "0x0f", NC_("part-type", "W95 Ext d (LBA)"), F_CONLY},
2523
{"dos", "microsoft", "0x11", NC_("part-type", "Hidden FAT12"), F_HIDDEN},
2524
{"dos", "microsoft", "0x14", NC_("part-type", "Hidden FAT16 <32M"), F_HIDDEN},
2525
{"dos", "microsoft", "0x16", NC_("part-type", "Hidden FAT16"), F_HIDDEN},
2526
{"dos", "microsoft", "0x17", NC_("part-type", "Hidden HPFS/NTFS"), F_HIDDEN},
2527
{"dos", "microsoft", "0x1b", NC_("part-type", "Hidden W95 FAT32"), F_HIDDEN},
2528
{"dos", "microsoft", "0x1c", NC_("part-type", "Hidden W95 FAT32 (LBA)"), F_HIDDEN},
2529
{"dos", "microsoft", "0x1e", NC_("part-type", "Hidden W95 FAT16 (LBA)"), F_HIDDEN},
2530
{"dos", "other", "0x10", NC_("part-type", "OPUS"), 0},
2531
{"dos", "other", "0x12", NC_("part-type", "Compaq diagnostics"), 0},
2532
{"dos", "other", "0x3c", NC_("part-type", "PartitionMagic"), 0},
2533
{"dos", "other", "0x81", NC_("part-type", "Minix"), 0}, /* cf. http://en.wikipedia.org/wiki/MINIX_file_system */
2534
{"dos", "other", "0x84", NC_("part-type", "Hibernation"), 0},
2535
{"dos", "other", "0xa0", NC_("part-type", "Hibernation"), 0},
2536
{"dos", "other", "0xa5", NC_("part-type", "FreeBSD"), 0},
2537
{"dos", "other", "0xa6", NC_("part-type", "OpenBSD"), 0},
2538
{"dos", "other", "0xa8", NC_("part-type", "Mac OS X"), 0},
2539
{"dos", "other", "0xaf", NC_("part-type", "Mac OS X"), 0},
2540
{"dos", "other", "0xbe", NC_("part-type", "Solaris boot"), 0},
2541
{"dos", "other", "0xbf", NC_("part-type", "Solaris"), 0},
2542
{"dos", "other", "0xeb", NC_("part-type", "BeOS BFS"), 0},
2543
{"dos", "other", "0xec", NC_("part-type", "SkyOS SkyFS"), 0},
2548
* udisks_client_get_partition_type_infos:
2549
* @client: A #UDisksClient.
2550
* @partition_table_type: A partition table type e.g. 'dos' or 'gpt'.
2551
* @partition_table_subtype: (allow-none): A partition table subtype or %NULL to get all known types.
2553
* Gets information about all known partition types for @partition_table_type and @partition_table_subtype.
2555
* Returns: (transfer full) (element-type UDisksPartitionTypeInfo): A list of
2556
* #UDisksPartitionTypeInfo instances. The returned list should be freed
2557
* with g_list_free() after freeing each element with udisks_partition_type_info_free().
2560
udisks_client_get_partition_type_infos (UDisksClient *client,
2561
const gchar *partition_table_type,
2562
const gchar *partition_table_subtype)
2567
for (n = 0; known_partition_types[n].name != NULL; n++)
2569
if (g_strcmp0 (known_partition_types[n].table_type, partition_table_type) == 0 &&
2570
(partition_table_subtype == NULL ||
2571
g_strcmp0 (known_partition_types[n].table_subtype, partition_table_subtype) == 0))
2573
UDisksPartitionTypeInfo *info = udisks_partition_type_info_new ();
2574
info->table_type = known_partition_types[n].table_type;
2575
info->table_subtype = known_partition_types[n].table_subtype;
2576
info->type = known_partition_types[n].type;
2577
info->flags = known_partition_types[n].flags;
2578
ret = g_list_prepend (ret, info);
2581
ret = g_list_reverse (ret);
2586
* udisks_client_get_partition_type_for_display:
2587
* @client: A #UDisksClient.
2588
* @partition_table_type: A partitioning type e.g. 'dos' or 'gpt'.
2589
* @partition_type: A partition type.
2591
* Gets a human readable localized string for @partiton_table_type and @partition_type.
2593
* Returns: A description of @partition_type or %NULL if unknown.
2596
udisks_client_get_partition_type_for_display (UDisksClient *client,
2597
const gchar *partition_table_type,
2598
const gchar *partition_type)
2600
const gchar *ret = NULL;
2603
for (n = 0; known_partition_types[n].name != NULL; n++)
2605
if (g_strcmp0 (known_partition_types[n].table_type, partition_table_type) == 0 &&
2606
g_strcmp0 (known_partition_types[n].type, partition_type) == 0)
2608
ret = g_dpgettext2 (GETTEXT_PACKAGE, "part-type", known_partition_types[n].name);
2617
/* ---------------------------------------------------------------------------------------------------- */
2620
* udisks_client_get_job_description:
2621
* @client: A #UDisksClient.
2622
* @job: A #UDisksJob.
2624
* Gets a human-readable and localized text string describing the
2625
* operation of @job.
2627
* Returns: A string that should be freed with g_free().
2630
udisks_client_get_job_description (UDisksClient *client,
2633
static gsize once = 0;
2634
static GHashTable *hash = NULL;
2637
g_return_val_if_fail (UDISKS_IS_CLIENT (client), NULL);
2639
if (g_once_init_enter (&once))
2641
hash = g_hash_table_new (g_str_hash, g_str_equal);
2642
g_hash_table_insert (hash, (gpointer) "ata-smart-selftest", (gpointer) C_("job", "SMART self-test"));
2643
g_hash_table_insert (hash, (gpointer) "drive-eject", (gpointer) C_("job", "Ejecting Medium"));
2644
g_hash_table_insert (hash, (gpointer) "encrypted-unlock", (gpointer) C_("job", "Unlocking Device"));
2645
g_hash_table_insert (hash, (gpointer) "encrypted-lock", (gpointer) C_("job", "Locking Device"));
2646
g_hash_table_insert (hash, (gpointer) "encrypted-modify", (gpointer) C_("job", "Modifying Encrypted Device"));
2647
g_hash_table_insert (hash, (gpointer) "swapspace-start", (gpointer) C_("job", "Starting Swap Device"));
2648
g_hash_table_insert (hash, (gpointer) "swapspace-stop", (gpointer) C_("job", "Stopping Swap Device"));
2649
g_hash_table_insert (hash, (gpointer) "filesystem-mount", (gpointer) C_("job", "Mounting Filesystem"));
2650
g_hash_table_insert (hash, (gpointer) "filesystem-unmount", (gpointer) C_("job", "Unmounting Filesystem"));
2651
g_hash_table_insert (hash, (gpointer) "filesystem-modify", (gpointer) C_("job", "Modifying Filesystem"));
2652
g_hash_table_insert (hash, (gpointer) "format-erase", (gpointer) C_("job", "Erasing Device"));
2653
g_hash_table_insert (hash, (gpointer) "format-mkfs", (gpointer) C_("job", "Creating Filesystem"));
2654
g_hash_table_insert (hash, (gpointer) "loop-setup", (gpointer) C_("job", "Setting Up Loop Device"));
2655
g_hash_table_insert (hash, (gpointer) "partition-modify", (gpointer) C_("job", "Modifying Partition"));
2656
g_hash_table_insert (hash, (gpointer) "partition-delete", (gpointer) C_("job", "Deleting Partition"));
2657
g_hash_table_insert (hash, (gpointer) "partition-create", (gpointer) C_("job", "Creating Partition"));
2658
g_hash_table_insert (hash, (gpointer) "cleanup", (gpointer) C_("job", "Cleaning Up"));
2659
g_hash_table_insert (hash, (gpointer) "ata-secure-erase", (gpointer) C_("job", "ATA Secure Erase"));
2660
g_hash_table_insert (hash, (gpointer) "ata-enhanced-secure-erase", (gpointer) C_("job", "ATA Enhanced Secure Erase"));
2661
g_once_init_leave (&once, (gsize) 1);
2664
ret = g_strdup (g_hash_table_lookup (hash, udisks_job_get_operation (job)));
2666
ret = g_strdup_printf (C_("unknown-job", "Unknown (%s)"), udisks_job_get_operation (job));
2671
/* ---------------------------------------------------------------------------------------------------- */
2673
static UDisksPartitionTypeInfo *
2674
udisks_partition_type_info_new (void)
2676
UDisksPartitionTypeInfo *ret;
2677
ret = g_slice_new0 (UDisksPartitionTypeInfo);
2681
static UDisksPartitionTypeInfo *
2682
udisks_partition_type_info_copy (UDisksPartitionTypeInfo *info)
2684
UDisksPartitionTypeInfo *ret;
2685
ret = udisks_partition_type_info_new ();
2686
memcpy (ret, info, sizeof (UDisksPartitionTypeInfo));
2691
* udisks_partition_type_info_free:
2692
* @info: A #UDisksPartitionTypeInfo.
2697
udisks_partition_type_info_free (UDisksPartitionTypeInfo *info)
2699
g_slice_free (UDisksPartitionTypeInfo, info);
2702
G_DEFINE_BOXED_TYPE (UDisksPartitionTypeInfo, udisks_partition_type_info, udisks_partition_type_info_copy, udisks_partition_type_info_free);