1 /***************************************************************************
4 * libhal-storage.c : HAL convenience library for storage devices and volumes
6 * Copyright (C) 2004 Red Hat, Inc.
8 * Author: David Zeuthen <davidz@redhat.com>
10 * Licensed under the Academic Free License version 2.1
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
26 **************************************************************************/
35 #include <dbus/dbus.h>
38 #include "libhal-storage.h"
43 # define _(String) dgettext (GETTEXT_PACKAGE, String)
45 # define N_(String) gettext_noop (String)
47 # define N_(String) (String)
50 /* Stubs that do something close enough. */
51 # define textdomain(String) (String)
52 # define gettext(String) (String)
53 # define dgettext(Domain,Message) (Message)
54 # define dcgettext(Domain,Message,Type) (Message)
55 # define bindtextdomain(Domain,Directory) (Domain)
56 # define _(String) (String)
57 # define N_(String) (String)
60 typedef struct IconMappingEntry_s
{
61 LibHalStoragePolicyIcon icon
;
63 struct IconMappingEntry_s
*next
;
66 struct LibHalStoragePolicy_s
{
67 IconMappingEntry
*icon_mappings
;
71 libhal_storage_policy_new ()
73 LibHalStoragePolicy
*p
;
75 p
= malloc (sizeof (LibHalStoragePolicy
));
79 p
->icon_mappings
= NULL
;
85 libhal_storage_policy_free (LibHalStoragePolicy
*policy
)
90 /* free all icon mappings */
91 for (i
= policy
->icon_mappings
; i
!= NULL
; i
= j
) {
101 libhal_storage_policy_set_icon_path (LibHalStoragePolicy
*policy
, LibHalStoragePolicyIcon icon
, const char *path
)
105 /* see if it already exist */
106 for (i
= policy
->icon_mappings
; i
!= NULL
; i
= i
->next
) {
107 if (i
->icon
== icon
) {
109 i
->path
= strdup (path
);
114 i
= malloc (sizeof (IconMappingEntry
));
118 i
->path
= strdup (path
);
119 i
->next
= policy
->icon_mappings
;
120 policy
->icon_mappings
= i
;
127 libhal_storage_policy_set_icon_mapping (LibHalStoragePolicy
*policy
, LibHalStoragePolicyIconPair
*pairs
)
129 LibHalStoragePolicyIconPair
*i
;
131 for (i
= pairs
; i
->icon
!= 0x00; i
++) {
132 libhal_storage_policy_set_icon_path (policy
, i
->icon
, i
->icon_path
);
137 libhal_storage_policy_lookup_icon (LibHalStoragePolicy
*policy
, LibHalStoragePolicyIcon icon
)
143 for (i
= policy
->icon_mappings
; i
!= NULL
; i
= i
->next
) {
144 if (i
->icon
== icon
) {
154 #define MAX_STRING_SZ 256
157 libhal_volume_policy_compute_size_as_string (LibHalVolume
*volume
)
161 char* sizes_str
[] = {"K", "M", "G", "T", NULL
};
162 dbus_uint64_t cur
= 1000L;
163 dbus_uint64_t base
= 10L;
164 dbus_uint64_t step
= 10L*10L*10L;
166 char buf
[MAX_STRING_SZ
];
170 size
= libhal_volume_get_size (volume
);
173 if (sizes_str
[cur_str
+1] == NULL
|| size
< cur
*step
) {
174 /* found the unit, display a comma number if result is a single digit */
175 if (size
< cur
*base
) {
176 snprintf (buf
, MAX_STRING_SZ
, "%.01f%s",
177 ((double)size
)/((double)cur
), sizes_str
[cur_str
]);
178 result
= strdup (buf
);
180 snprintf (buf
, MAX_STRING_SZ
, "%llu%s", (long long unsigned int) size
/ cur
, sizes_str
[cur_str
]);
181 result
= strdup (buf
);
195 fixup_string (char *s
)
197 /* TODO: first strip leading and trailing whitespace */
200 /* TODO: could do nice things on all-upper case strings */
203 /* volume may be NULL (e.g. if drive supports removable media) */
205 libhal_drive_policy_compute_display_name (LibHalDrive
*drive
, LibHalVolume
*volume
, LibHalStoragePolicy
*policy
)
209 char *vendormodel_str
;
212 LibHalDriveType drive_type
;
213 dbus_bool_t drive_is_hotpluggable
;
214 dbus_bool_t drive_is_removable
;
215 LibHalDriveCdromCaps drive_cdrom_caps
;
216 char buf
[MAX_STRING_SZ
];
218 model
= libhal_drive_get_model (drive
);
219 vendor
= libhal_drive_get_vendor (drive
);
220 drive_type
= libhal_drive_get_type (drive
);
221 drive_is_hotpluggable
= libhal_drive_is_hotpluggable (drive
);
222 drive_is_removable
= libhal_drive_uses_removable_media (drive
);
223 drive_cdrom_caps
= libhal_drive_get_cdrom_caps (drive
);
226 size_str
= libhal_volume_policy_compute_size_as_string (volume
);
230 if (vendor
== NULL
|| strlen (vendor
) == 0) {
231 if (model
== NULL
|| strlen (model
) == 0)
232 vendormodel_str
= strdup ("");
234 vendormodel_str
= strdup (model
);
236 if (model
== NULL
|| strlen (model
) == 0)
237 vendormodel_str
= strdup (vendor
);
239 snprintf (buf
, MAX_STRING_SZ
, "%s %s", vendor
, model
);
240 vendormodel_str
= strdup (buf
);
244 fixup_string (vendormodel_str
);
246 if (drive_type
==LIBHAL_DRIVE_TYPE_CDROM
) {
248 /* Optical drive handling */
254 if (drive_cdrom_caps
& LIBHAL_DRIVE_CDROM_CAPS_CDR
)
256 if (drive_cdrom_caps
& LIBHAL_DRIVE_CDROM_CAPS_CDRW
)
260 if (drive_cdrom_caps
& LIBHAL_DRIVE_CDROM_CAPS_DVDROM
)
262 if (drive_cdrom_caps
& LIBHAL_DRIVE_CDROM_CAPS_DVDPLUSR
)
264 if (drive_cdrom_caps
& LIBHAL_DRIVE_CDROM_CAPS_DVDPLUSRW
)
266 if (drive_cdrom_caps
& LIBHAL_DRIVE_CDROM_CAPS_DVDR
)
268 if (drive_cdrom_caps
& LIBHAL_DRIVE_CDROM_CAPS_DVDRW
)
270 if (drive_cdrom_caps
& LIBHAL_DRIVE_CDROM_CAPS_DVDRAM
)
272 if ((drive_cdrom_caps
& LIBHAL_DRIVE_CDROM_CAPS_DVDR
) &&
273 (drive_cdrom_caps
& LIBHAL_DRIVE_CDROM_CAPS_DVDPLUSR
)) {
274 if(drive_cdrom_caps
& LIBHAL_DRIVE_CDROM_CAPS_DVDPLUSRDL
)
275 second
= "/DVD±R DL";
279 if ((drive_cdrom_caps
& LIBHAL_DRIVE_CDROM_CAPS_DVDRW
) &&
280 (drive_cdrom_caps
& LIBHAL_DRIVE_CDROM_CAPS_DVDPLUSRW
)) {
281 if(drive_cdrom_caps
& LIBHAL_DRIVE_CDROM_CAPS_DVDPLUSRDL
||
282 drive_cdrom_caps
& LIBHAL_DRIVE_CDROM_CAPS_DVDPLUSRWDL
)
283 second
= "/DVD±RW DL";
287 if (drive_cdrom_caps
& LIBHAL_DRIVE_CDROM_CAPS_BDROM
)
289 if (drive_cdrom_caps
& LIBHAL_DRIVE_CDROM_CAPS_BDR
)
291 if (drive_cdrom_caps
& LIBHAL_DRIVE_CDROM_CAPS_BDRE
)
293 if (drive_cdrom_caps
& LIBHAL_DRIVE_CDROM_CAPS_HDDVDROM
)
294 second
= "/HD DVD-ROM";
295 if (drive_cdrom_caps
& LIBHAL_DRIVE_CDROM_CAPS_HDDVDR
)
296 second
= "/HD DVD-R";
297 if (drive_cdrom_caps
& LIBHAL_DRIVE_CDROM_CAPS_HDDVDRW
)
298 second
= "/HD DVD-RW";
300 if (drive_is_hotpluggable
) {
301 snprintf (buf
, MAX_STRING_SZ
, _("External %s%s Drive"), first
, second
);
304 snprintf (buf
, MAX_STRING_SZ
, _("%s%s Drive"), first
, second
);
308 } else if (drive_type
==LIBHAL_DRIVE_TYPE_FLOPPY
) {
310 /* Floppy Drive handling */
312 if (drive_is_hotpluggable
)
313 name
= strdup (_("External Floppy Drive"));
315 name
= strdup (_("Floppy Drive"));
316 } else if (drive_type
==LIBHAL_DRIVE_TYPE_DISK
&& !drive_is_removable
) {
320 if (size_str
!= NULL
) {
321 if (drive_is_hotpluggable
) {
322 snprintf (buf
, MAX_STRING_SZ
, _("%s External Hard Drive"), size_str
);
325 snprintf (buf
, MAX_STRING_SZ
, _("%s Hard Drive"), size_str
);
329 if (drive_is_hotpluggable
)
330 name
= strdup (_("External Hard Drive"));
332 name
= strdup (_("Hard Drive"));
336 /* The rest - includes drives with removable Media */
338 if (strlen (vendormodel_str
) > 0)
339 name
= strdup (vendormodel_str
);
341 name
= strdup (_("Drive"));
344 free (vendormodel_str
);
351 libhal_volume_policy_compute_display_name (LibHalDrive
*drive
, LibHalVolume
*volume
, LibHalStoragePolicy
*policy
)
355 const char *volume_label
;
358 LibHalDriveType drive_type
;
359 dbus_bool_t drive_is_hotpluggable
;
360 dbus_bool_t drive_is_removable
;
361 LibHalDriveCdromCaps drive_cdrom_caps
;
362 char buf
[MAX_STRING_SZ
];
364 volume_label
= libhal_volume_get_label (volume
);
365 model
= libhal_drive_get_model (drive
);
366 vendor
= libhal_drive_get_vendor (drive
);
367 drive_type
= libhal_drive_get_type (drive
);
368 drive_is_hotpluggable
= libhal_drive_is_hotpluggable (drive
);
369 drive_is_removable
= libhal_drive_uses_removable_media (drive
);
370 drive_cdrom_caps
= libhal_drive_get_cdrom_caps (drive
);
372 size_str
= libhal_volume_policy_compute_size_as_string (volume
);
374 /* If the volume label is available use that
376 * TODO: If label is a fully-qualified UNIX path don't use that
378 if (volume_label
!= NULL
) {
379 name
= strdup (volume_label
);
383 /* Handle media in optical drives */
384 if (drive_type
==LIBHAL_DRIVE_TYPE_CDROM
) {
385 switch (libhal_volume_get_disc_type (volume
)) {
388 /* explict fallthrough */
389 case LIBHAL_VOLUME_DISC_TYPE_CDROM
:
390 name
= strdup (_("CD-ROM "));
393 case LIBHAL_VOLUME_DISC_TYPE_CDR
:
394 if (libhal_volume_disc_is_blank (volume
))
395 name
= strdup (_("Blank CD-R"));
397 name
= strdup (_("CD-R"));
400 case LIBHAL_VOLUME_DISC_TYPE_CDRW
:
401 if (libhal_volume_disc_is_blank (volume
))
402 name
= strdup (_("Blank CD-RW"));
404 name
= strdup (_("CD-RW"));
407 case LIBHAL_VOLUME_DISC_TYPE_DVDROM
:
408 name
= strdup (_("DVD-ROM"));
411 case LIBHAL_VOLUME_DISC_TYPE_DVDRAM
:
412 if (libhal_volume_disc_is_blank (volume
))
413 name
= strdup (_("Blank DVD-RAM"));
415 name
= strdup (_("DVD-RAM"));
418 case LIBHAL_VOLUME_DISC_TYPE_DVDR
:
419 if (libhal_volume_disc_is_blank (volume
))
420 name
= strdup (_("Blank DVD-R"));
422 name
= strdup (_("DVD-R"));
425 case LIBHAL_VOLUME_DISC_TYPE_DVDRW
:
426 if (libhal_volume_disc_is_blank (volume
))
427 name
= strdup (_("Blank DVD-RW"));
429 name
= strdup (_("DVD-RW"));
432 case LIBHAL_VOLUME_DISC_TYPE_DVDPLUSR
:
433 if (libhal_volume_disc_is_blank (volume
))
434 name
= strdup (_("Blank DVD+R"));
436 name
= strdup (_("DVD+R"));
439 case LIBHAL_VOLUME_DISC_TYPE_DVDPLUSRW
:
440 if (libhal_volume_disc_is_blank (volume
))
441 name
= strdup (_("Blank DVD+RW"));
443 name
= strdup (_("DVD+RW"));
446 case LIBHAL_VOLUME_DISC_TYPE_DVDPLUSR_DL
:
447 if (libhal_volume_disc_is_blank (volume
))
448 name
= strdup (_("Blank DVD+R Dual-Layer"));
450 name
= strdup (_("DVD+R Dual-Layer"));
453 case LIBHAL_VOLUME_DISC_TYPE_BDROM
:
454 name
= strdup (_("BD-ROM"));
457 case LIBHAL_VOLUME_DISC_TYPE_BDR
:
458 if (libhal_volume_disc_is_blank (volume
))
459 name
= strdup (_("Blank BD-R"));
461 name
= strdup (_("BD-R"));
464 case LIBHAL_VOLUME_DISC_TYPE_BDRE
:
465 if (libhal_volume_disc_is_blank (volume
))
466 name
= strdup (_("Blank BD-RE"));
468 name
= strdup (_("BD-RE"));
471 case LIBHAL_VOLUME_DISC_TYPE_HDDVDROM
:
472 name
= strdup (_("HD DVD-ROM"));
475 case LIBHAL_VOLUME_DISC_TYPE_HDDVDR
:
476 if (libhal_volume_disc_is_blank (volume
))
477 name
= strdup (_("Blank HD DVD-R"));
479 name
= strdup (_("HD DVD-R"));
482 case LIBHAL_VOLUME_DISC_TYPE_HDDVDRW
:
483 if (libhal_volume_disc_is_blank (volume
))
484 name
= strdup (_("Blank HD DVD-RW"));
486 name
= strdup (_("HD DVD-RW"));
491 /* Special case for pure audio disc */
492 if (libhal_volume_disc_has_audio (volume
) && !libhal_volume_disc_has_data (volume
)) {
494 name
= strdup (_("Audio CD"));
500 /* Fallback: size of media */
501 if (drive_is_removable
) {
502 snprintf (buf
, MAX_STRING_SZ
, _("%s Removable Media"), size_str
);
505 snprintf (buf
, MAX_STRING_SZ
, _("%s Media"), size_str
);
509 /* Fallback: Use drive name */
510 /*name = libhal_drive_policy_compute_display_name (drive, volume);*/
518 libhal_drive_policy_compute_icon_name (LibHalDrive
*drive
, LibHalVolume
*volume
, LibHalStoragePolicy
*policy
)
522 LibHalDriveType drive_type
;
524 bus
= libhal_drive_get_bus (drive
);
525 drive_type
= libhal_drive_get_type (drive
);
527 /* by design, the enums are laid out so we can do easy computations */
529 switch (drive_type
) {
530 case LIBHAL_DRIVE_TYPE_REMOVABLE_DISK
:
531 case LIBHAL_DRIVE_TYPE_DISK
:
532 case LIBHAL_DRIVE_TYPE_CDROM
:
533 case LIBHAL_DRIVE_TYPE_FLOPPY
:
534 name
= libhal_storage_policy_lookup_icon (policy
, 0x10000 + drive_type
*0x100 + bus
);
538 name
= libhal_storage_policy_lookup_icon (policy
, 0x10000 + drive_type
*0x100);
542 return strdup (name
);
548 libhal_volume_policy_compute_icon_name (LibHalDrive
*drive
, LibHalVolume
*volume
, LibHalStoragePolicy
*policy
)
552 LibHalDriveType drive_type
;
553 LibHalVolumeDiscType disc_type
;
555 /* by design, the enums are laid out so we can do easy computations */
557 if (libhal_volume_is_disc (volume
)) {
558 disc_type
= libhal_volume_get_disc_type (volume
);
559 name
= libhal_storage_policy_lookup_icon (policy
, 0x30000 + disc_type
);
564 name
= libhal_storage_policy_lookup_icon (policy
, LIBHAL_STORAGE_ICON_VOLUME_REMOVABLE_DISK
);
568 bus
= libhal_drive_get_bus (drive
);
569 drive_type
= libhal_drive_get_type (drive
);
571 switch (drive_type
) {
572 case LIBHAL_DRIVE_TYPE_REMOVABLE_DISK
:
573 case LIBHAL_DRIVE_TYPE_DISK
:
574 case LIBHAL_DRIVE_TYPE_CDROM
:
575 case LIBHAL_DRIVE_TYPE_FLOPPY
:
576 name
= libhal_storage_policy_lookup_icon (policy
, 0x20000 + drive_type
*0x100 + bus
);
580 name
= libhal_storage_policy_lookup_icon (policy
, 0x20000 + drive_type
*0x100);
584 return strdup (name
);
589 /** Policy function to determine if a volume should be visible in a desktop
590 * environment. This is useful to hide certain system volumes as bootstrap
591 * partitions, the /usr partition, swap partitions and other volumes that
592 * a unprivileged desktop user shouldn't know even exists.
594 * @param drive Drive that the volume is stemming from
595 * @param volume Volume
596 * @param policy Policy object
597 * @param target_mount_point The mount point that the volume is expected to
598 * be mounted at if not already mounted. This may
599 * e.g. stem from /etc/fstab. If this is NULL the
600 * then mount point isn't taking into account when
601 * evaluating whether the volume should be visible
602 * @return Whether the volume should be shown in a desktop
606 libhal_volume_policy_should_be_visible (LibHalDrive
*drive
, LibHalVolume
*volume
, LibHalStoragePolicy
*policy
,
607 const char *target_mount_point
)
610 dbus_bool_t is_visible
;
612 const char *mount_point
;
614 const char *fhs23_toplevel_mount_points
[] = {
639 /* skip if hal says it's not used as a filesystem */
640 if (libhal_volume_get_fsusage (volume
) != LIBHAL_VOLUME_USAGE_MOUNTABLE_FILESYSTEM
)
643 label
= libhal_volume_get_label (volume
);
644 mount_point
= libhal_volume_get_mount_point (volume
);
645 fstype
= libhal_volume_get_fstype (volume
);
647 /* use target mount point if we're not mounted yet */
648 if (mount_point
== NULL
)
649 mount_point
= target_mount_point
;
651 /* bail out if we don't know the filesystem */
655 /* blacklist fhs2.3 top level mount points */
656 if (mount_point
!= NULL
) {
657 for (i
= 0; fhs23_toplevel_mount_points
[i
] != NULL
; i
++) {
658 if (strcmp (mount_point
, fhs23_toplevel_mount_points
[i
]) == 0)
663 /* blacklist partitions with name 'bootstrap' of type HFS (Apple uses that) */
664 if (label
!= NULL
&& strcmp (label
, "bootstrap") == 0 && strcmp (fstype
, "hfs") == 0)
667 /* only the real lucky mount points will make it this far :-) */
674 /*************************************************************************/
676 #define MOUNT_OPTIONS_SIZE 256
678 struct LibHalDrive_s
{
686 char *vendor
; /* may be "", is never NULL */
687 char *model
; /* may be "", is never NULL */
688 dbus_bool_t is_hotpluggable
;
689 dbus_bool_t is_removable
;
690 dbus_bool_t is_media_detected
;
691 dbus_bool_t requires_eject
;
693 LibHalDriveType type
;
696 char *physical_device
; /* UDI of physical device, e.g. the
697 * IDE, USB, IEEE1394 device */
699 char *dedicated_icon_drive
;
700 char *dedicated_icon_volume
;
703 char *firmware_version
;
704 LibHalDriveCdromCaps cdrom_caps
;
706 char *desired_mount_point
;
707 char *mount_filesystem
;
708 dbus_bool_t should_mount
;
710 dbus_bool_t no_partitions_hint
;
712 dbus_uint64_t drive_size
;
713 dbus_uint64_t drive_media_size
;
714 char *partition_scheme
;
716 LibHalContext
*hal_ctx
;
720 char mount_options
[MOUNT_OPTIONS_SIZE
];
723 struct LibHalVolume_s
{
729 char *volume_label
; /* may be NULL, is never "" */
730 dbus_bool_t is_mounted
;
731 dbus_bool_t is_mounted_read_only
; /* TRUE iff is_mounted and r/o fs */
732 char *mount_point
; /* NULL iff !is_mounted */
733 char *fstype
; /* NULL iff !is_mounted or unknown */
736 char *storage_device
;
738 LibHalVolumeUsage fsusage
;
740 dbus_bool_t is_partition
;
741 unsigned int partition_number
;
742 char *partition_scheme
;
743 char *partition_type
;
744 char *partition_label
;
745 char *partition_uuid
;
746 char **partition_flags
;
748 int msdos_part_table_type
;
749 dbus_uint64_t msdos_part_table_start
;
750 dbus_uint64_t msdos_part_table_size
;
753 LibHalVolumeDiscType disc_type
;
754 dbus_bool_t disc_has_audio
;
755 dbus_bool_t disc_has_data
;
756 dbus_bool_t disc_is_appendable
;
757 dbus_bool_t disc_is_blank
;
758 dbus_bool_t disc_is_rewritable
;
760 unsigned int block_size
;
761 unsigned int num_blocks
;
763 char *desired_mount_point
;
764 char *mount_filesystem
;
765 dbus_bool_t should_mount
;
767 dbus_bool_t ignore_volume
;
769 char *crypto_backing_volume
;
771 char mount_options
[MOUNT_OPTIONS_SIZE
];
773 dbus_uint64_t volume_size
;
774 dbus_uint64_t disc_capacity
;
776 dbus_uint64_t partition_start_offset
;
777 dbus_uint64_t partition_media_size
;
781 libhal_drive_get_dedicated_icon_drive (LibHalDrive
*drive
)
783 return drive
->dedicated_icon_drive
;
787 libhal_drive_get_dedicated_icon_volume (LibHalDrive
*drive
)
789 return drive
->dedicated_icon_volume
;
792 /** Free all resources used by a LibHalDrive object.
794 * @param drive Object to free
797 libhal_drive_free (LibHalDrive
*drive
)
803 libhal_free_string (drive
->device_file
);
804 libhal_free_string (drive
->vendor
);
805 libhal_free_string (drive
->model
);
806 libhal_free_string (drive
->type_textual
);
807 libhal_free_string (drive
->physical_device
);
808 libhal_free_string (drive
->dedicated_icon_drive
);
809 libhal_free_string (drive
->dedicated_icon_volume
);
810 libhal_free_string (drive
->serial
);
811 libhal_free_string (drive
->firmware_version
);
812 libhal_free_string (drive
->desired_mount_point
);
813 libhal_free_string (drive
->mount_filesystem
);
814 libhal_free_string_array (drive
->capabilities
);
815 libhal_free_string (drive
->partition_scheme
);
821 /** Free all resources used by a LibHalVolume object.
823 * @param vol Object to free
826 libhal_volume_free (LibHalVolume
*vol
)
832 libhal_free_string (vol
->device_file
);
833 libhal_free_string (vol
->volume_label
);
834 libhal_free_string (vol
->fstype
);
835 libhal_free_string (vol
->mount_point
);
836 libhal_free_string (vol
->fsversion
);
837 libhal_free_string (vol
->uuid
);
838 libhal_free_string (vol
->desired_mount_point
);
839 libhal_free_string (vol
->mount_filesystem
);
840 libhal_free_string (vol
->crypto_backing_volume
);
841 libhal_free_string (vol
->storage_device
);
843 libhal_free_string (vol
->partition_scheme
);
844 libhal_free_string (vol
->partition_type
);
845 libhal_free_string (vol
->partition_label
);
846 libhal_free_string (vol
->partition_uuid
);
847 libhal_free_string_array (vol
->partition_flags
);
854 my_strvdup (char **strv
)
856 unsigned int num_elems
;
860 for (num_elems
= 0; strv
[num_elems
] != NULL
; num_elems
++)
863 res
= calloc (num_elems
+ 1, sizeof (char*));
867 for (i
= 0; i
< num_elems
; i
++)
868 res
[i
] = strdup (strv
[i
]);
875 /* ok, hey, so this is a bit ugly */
877 #define LIBHAL_PROP_EXTRACT_BEGIN if (FALSE)
878 #define LIBHAL_PROP_EXTRACT_END ;
879 #define LIBHAL_PROP_EXTRACT_INT(_property_, _where_) else if (strcmp (key, _property_) == 0 && type == LIBHAL_PROPERTY_TYPE_INT32) _where_ = libhal_psi_get_int (&it)
880 #define LIBHAL_PROP_EXTRACT_UINT64(_property_, _where_) else if (strcmp (key, _property_) == 0 && type == LIBHAL_PROPERTY_TYPE_UINT64) _where_ = libhal_psi_get_uint64 (&it)
881 #define LIBHAL_PROP_EXTRACT_STRING(_property_, _where_) else if (strcmp (key, _property_) == 0 && type == LIBHAL_PROPERTY_TYPE_STRING) _where_ = (libhal_psi_get_string (&it) != NULL && strlen (libhal_psi_get_string (&it)) > 0) ? strdup (libhal_psi_get_string (&it)) : NULL
882 #define LIBHAL_PROP_EXTRACT_BOOL(_property_, _where_) else if (strcmp (key, _property_) == 0 && type == LIBHAL_PROPERTY_TYPE_BOOLEAN) _where_ = libhal_psi_get_bool (&it)
883 #define LIBHAL_PROP_EXTRACT_BOOL_BITFIELD(_property_, _where_, _field_) else if (strcmp (key, _property_) == 0 && type == LIBHAL_PROPERTY_TYPE_BOOLEAN) _where_ |= libhal_psi_get_bool (&it) ? _field_ : 0
884 #define LIBHAL_PROP_EXTRACT_STRLIST(_property_, _where_) else if (strcmp (key, _property_) == 0 && type == LIBHAL_PROPERTY_TYPE_STRLIST) _where_ = my_strvdup (libhal_psi_get_strlist (&it))
886 /** Given a UDI for a HAL device of capability 'storage', this
887 * function retrieves all the relevant properties into convenient
888 * in-process data structures.
890 * @param hal_ctx libhal context
892 * @return LibHalDrive object or NULL if UDI is invalid
895 libhal_drive_from_udi (LibHalContext
*hal_ctx
, const char *udi
)
899 LibHalPropertySet
*properties
;
900 LibHalPropertySetIterator it
;
904 LIBHAL_CHECK_LIBHALCONTEXT(hal_ctx
, NULL
);
910 dbus_error_init (&error
);
911 if (!libhal_device_query_capability (hal_ctx
, udi
, "storage", &error
))
914 drive
= malloc (sizeof (LibHalDrive
));
917 memset (drive
, 0x00, sizeof (LibHalDrive
));
919 drive
->hal_ctx
= hal_ctx
;
921 drive
->udi
= strdup (udi
);
922 if (drive
->udi
== NULL
)
925 properties
= libhal_device_get_all_properties (hal_ctx
, udi
, &error
);
926 if (properties
== NULL
)
929 /* we can count on hal to give us all these properties */
930 for (libhal_psi_init (&it
, properties
); libhal_psi_has_more (&it
); libhal_psi_next (&it
)) {
934 type
= libhal_psi_get_type (&it
);
935 key
= libhal_psi_get_key (&it
);
937 LIBHAL_PROP_EXTRACT_BEGIN
;
939 LIBHAL_PROP_EXTRACT_INT ("block.minor", drive
->device_minor
);
940 LIBHAL_PROP_EXTRACT_INT ("block.major", drive
->device_major
);
941 LIBHAL_PROP_EXTRACT_STRING ("block.device", drive
->device_file
);
942 LIBHAL_PROP_EXTRACT_STRING ("storage.bus", bus_textual
);
943 LIBHAL_PROP_EXTRACT_STRING ("storage.vendor", drive
->vendor
);
944 LIBHAL_PROP_EXTRACT_STRING ("storage.model", drive
->model
);
945 LIBHAL_PROP_EXTRACT_STRING ("storage.drive_type", drive
->type_textual
);
946 LIBHAL_PROP_EXTRACT_UINT64 ("storage.size", drive
->drive_size
);
948 LIBHAL_PROP_EXTRACT_STRING ("storage.icon.drive", drive
->dedicated_icon_drive
);
949 LIBHAL_PROP_EXTRACT_STRING ("storage.icon.volume", drive
->dedicated_icon_volume
);
951 LIBHAL_PROP_EXTRACT_BOOL ("storage.hotpluggable", drive
->is_hotpluggable
);
952 LIBHAL_PROP_EXTRACT_BOOL ("storage.removable", drive
->is_removable
);
953 LIBHAL_PROP_EXTRACT_BOOL ("storage.removable.media_available", drive
->is_media_detected
);
954 LIBHAL_PROP_EXTRACT_UINT64 ("storage.removable.media_size", drive
->drive_media_size
);
955 LIBHAL_PROP_EXTRACT_BOOL ("storage.requires_eject", drive
->requires_eject
);
957 LIBHAL_PROP_EXTRACT_STRING ("storage.partitioning_scheme", drive
->partition_scheme
);
959 LIBHAL_PROP_EXTRACT_STRING ("storage.physical_device", drive
->physical_device
);
960 LIBHAL_PROP_EXTRACT_STRING ("storage.firmware_version", drive
->firmware_version
);
961 LIBHAL_PROP_EXTRACT_STRING ("storage.serial", drive
->serial
);
963 LIBHAL_PROP_EXTRACT_BOOL_BITFIELD ("storage.cdrom.cdr", drive
->cdrom_caps
, LIBHAL_DRIVE_CDROM_CAPS_CDR
);
964 LIBHAL_PROP_EXTRACT_BOOL_BITFIELD ("storage.cdrom.cdrw", drive
->cdrom_caps
, LIBHAL_DRIVE_CDROM_CAPS_CDRW
);
965 LIBHAL_PROP_EXTRACT_BOOL_BITFIELD ("storage.cdrom.dvd", drive
->cdrom_caps
, LIBHAL_DRIVE_CDROM_CAPS_DVDROM
);
966 LIBHAL_PROP_EXTRACT_BOOL_BITFIELD ("storage.cdrom.dvdplusr", drive
->cdrom_caps
, LIBHAL_DRIVE_CDROM_CAPS_DVDPLUSR
);
967 LIBHAL_PROP_EXTRACT_BOOL_BITFIELD ("storage.cdrom.dvdplusrw", drive
->cdrom_caps
, LIBHAL_DRIVE_CDROM_CAPS_DVDPLUSRW
);
968 LIBHAL_PROP_EXTRACT_BOOL_BITFIELD ("storage.cdrom.dvdplusrwdl", drive
->cdrom_caps
, LIBHAL_DRIVE_CDROM_CAPS_DVDPLUSRWDL
);
969 LIBHAL_PROP_EXTRACT_BOOL_BITFIELD ("storage.cdrom.dvdplusrdl", drive
->cdrom_caps
, LIBHAL_DRIVE_CDROM_CAPS_DVDPLUSRDL
);
970 LIBHAL_PROP_EXTRACT_BOOL_BITFIELD ("storage.cdrom.dvdr", drive
->cdrom_caps
, LIBHAL_DRIVE_CDROM_CAPS_DVDR
);
971 LIBHAL_PROP_EXTRACT_BOOL_BITFIELD ("storage.cdrom.dvdrw", drive
->cdrom_caps
, LIBHAL_DRIVE_CDROM_CAPS_DVDRW
);
972 LIBHAL_PROP_EXTRACT_BOOL_BITFIELD ("storage.cdrom.dvdram", drive
->cdrom_caps
, LIBHAL_DRIVE_CDROM_CAPS_DVDRAM
);
973 LIBHAL_PROP_EXTRACT_BOOL_BITFIELD ("storage.cdrom.bd", drive
->cdrom_caps
, LIBHAL_DRIVE_CDROM_CAPS_BDROM
);
974 LIBHAL_PROP_EXTRACT_BOOL_BITFIELD ("storage.cdrom.bdr", drive
->cdrom_caps
, LIBHAL_DRIVE_CDROM_CAPS_BDR
);
975 LIBHAL_PROP_EXTRACT_BOOL_BITFIELD ("storage.cdrom.bdre", drive
->cdrom_caps
, LIBHAL_DRIVE_CDROM_CAPS_BDRE
);
976 LIBHAL_PROP_EXTRACT_BOOL_BITFIELD ("storage.cdrom.hddvd", drive
->cdrom_caps
, LIBHAL_DRIVE_CDROM_CAPS_HDDVDROM
);
977 LIBHAL_PROP_EXTRACT_BOOL_BITFIELD ("storage.cdrom.hddvdr", drive
->cdrom_caps
, LIBHAL_DRIVE_CDROM_CAPS_HDDVDR
);
978 LIBHAL_PROP_EXTRACT_BOOL_BITFIELD ("storage.cdrom.hddvdrw", drive
->cdrom_caps
, LIBHAL_DRIVE_CDROM_CAPS_HDDVDRW
);
980 LIBHAL_PROP_EXTRACT_BOOL ("storage.policy.should_mount", drive
->should_mount
);
981 LIBHAL_PROP_EXTRACT_STRING ("storage.policy.desired_mount_point", drive
->desired_mount_point
);
982 LIBHAL_PROP_EXTRACT_STRING ("storage.policy.mount_filesystem", drive
->mount_filesystem
);
984 LIBHAL_PROP_EXTRACT_BOOL ("storage.no_partitions_hint", drive
->no_partitions_hint
);
986 LIBHAL_PROP_EXTRACT_STRLIST ("info.capabilities", drive
->capabilities
);
988 LIBHAL_PROP_EXTRACT_END
;
991 if (drive
->type_textual
!= NULL
) {
992 if (strcmp (drive
->type_textual
, "cdrom") == 0) {
993 drive
->cdrom_caps
|= LIBHAL_DRIVE_CDROM_CAPS_CDROM
;
994 drive
->type
= LIBHAL_DRIVE_TYPE_CDROM
;
995 } else if (strcmp (drive
->type_textual
, "floppy") == 0) {
996 drive
->type
= LIBHAL_DRIVE_TYPE_FLOPPY
;
997 } else if (strcmp (drive
->type_textual
, "disk") == 0) {
998 if (drive
->is_removable
)
999 drive
->type
= LIBHAL_DRIVE_TYPE_REMOVABLE_DISK
;
1001 drive
->type
= LIBHAL_DRIVE_TYPE_DISK
;
1002 } else if (strcmp (drive
->type_textual
, "tape") == 0) {
1003 drive
->type
= LIBHAL_DRIVE_TYPE_TAPE
;
1004 } else if (strcmp (drive
->type_textual
, "compact_flash") == 0) {
1005 drive
->type
= LIBHAL_DRIVE_TYPE_COMPACT_FLASH
;
1006 } else if (strcmp (drive
->type_textual
, "memory_stick") == 0) {
1007 drive
->type
= LIBHAL_DRIVE_TYPE_MEMORY_STICK
;
1008 } else if (strcmp (drive
->type_textual
, "smart_media") == 0) {
1009 drive
->type
= LIBHAL_DRIVE_TYPE_SMART_MEDIA
;
1010 } else if (strcmp (drive
->type_textual
, "sd_mmc") == 0) {
1011 drive
->type
= LIBHAL_DRIVE_TYPE_SD_MMC
;
1012 } else if (strcmp (drive
->type_textual
, "zip") == 0) {
1013 drive
->type
= LIBHAL_DRIVE_TYPE_ZIP
;
1014 } else if (strcmp (drive
->type_textual
, "jaz") == 0) {
1015 drive
->type
= LIBHAL_DRIVE_TYPE_JAZ
;
1016 } else if (strcmp (drive
->type_textual
, "flashkey") == 0) {
1017 drive
->type
= LIBHAL_DRIVE_TYPE_FLASHKEY
;
1019 drive
->type
= LIBHAL_DRIVE_TYPE_DISK
;
1024 if (drive
->capabilities
!= NULL
) {
1025 for (i
= 0; drive
->capabilities
[i
] != NULL
; i
++) {
1026 if (strcmp (drive
->capabilities
[i
], "portable_audio_player") == 0) {
1027 drive
->type
= LIBHAL_DRIVE_TYPE_PORTABLE_AUDIO_PLAYER
;
1029 } else if (strcmp (drive
->capabilities
[i
], "camera") == 0) {
1030 drive
->type
= LIBHAL_DRIVE_TYPE_CAMERA
;
1036 if (bus_textual
!= NULL
) {
1037 if (strcmp (bus_textual
, "usb") == 0) {
1038 drive
->bus
= LIBHAL_DRIVE_BUS_USB
;
1039 } else if (strcmp (bus_textual
, "ieee1394") == 0) {
1040 drive
->bus
= LIBHAL_DRIVE_BUS_IEEE1394
;
1041 } else if (strcmp (bus_textual
, "ide") == 0) {
1042 drive
->bus
= LIBHAL_DRIVE_BUS_IDE
;
1043 } else if (strcmp (bus_textual
, "scsi") == 0) {
1044 drive
->bus
= LIBHAL_DRIVE_BUS_SCSI
;
1045 } else if (strcmp (bus_textual
, "ccw") == 0) {
1046 drive
->bus
= LIBHAL_DRIVE_BUS_CCW
;
1050 libhal_free_string (bus_textual
);
1051 libhal_free_property_set (properties
);
1056 LIBHAL_FREE_DBUS_ERROR(&error
);
1057 libhal_free_string (bus_textual
);
1058 libhal_free_property_set (properties
);
1059 libhal_drive_free (drive
);
1064 libhal_volume_get_storage_device_udi (LibHalVolume
*volume
)
1066 return volume
->storage_device
;
1069 const char *libhal_drive_get_physical_device_udi (LibHalDrive
*drive
)
1071 return drive
->physical_device
;
1075 libhal_drive_requires_eject (LibHalDrive
*drive
)
1077 return drive
->requires_eject
;
1080 /** Given a UDI for a LIBHAL device of capability 'volume', this
1081 * function retrieves all the relevant properties into convenient
1082 * in-process data structures.
1084 * @param hal_ctx libhal context
1085 * @param udi HAL UDI
1086 * @return LibHalVolume object or NULL if UDI is invalid
1089 libhal_volume_from_udi (LibHalContext
*hal_ctx
, const char *udi
)
1091 char *disc_type_textual
;
1092 char *vol_fsusage_textual
;
1094 LibHalPropertySet
*properties
;
1095 LibHalPropertySetIterator it
;
1098 LIBHAL_CHECK_LIBHALCONTEXT(hal_ctx
, NULL
);
1102 disc_type_textual
= NULL
;
1103 vol_fsusage_textual
= NULL
;
1105 dbus_error_init (&error
);
1106 if (!libhal_device_query_capability (hal_ctx
, udi
, "volume", &error
))
1109 vol
= malloc (sizeof (LibHalVolume
));
1112 memset (vol
, 0x00, sizeof (LibHalVolume
));
1114 vol
->udi
= strdup (udi
);
1116 properties
= libhal_device_get_all_properties (hal_ctx
, udi
, &error
);
1117 if (properties
== NULL
)
1120 /* we can count on hal to give us all these properties */
1121 for (libhal_psi_init (&it
, properties
); libhal_psi_has_more (&it
); libhal_psi_next (&it
)) {
1125 type
= libhal_psi_get_type (&it
);
1126 key
= libhal_psi_get_key (&it
);
1128 LIBHAL_PROP_EXTRACT_BEGIN
;
1130 LIBHAL_PROP_EXTRACT_BOOL ("volume.is_partition", vol
->is_partition
);
1131 LIBHAL_PROP_EXTRACT_INT ("volume.partition.number", vol
->partition_number
);
1132 LIBHAL_PROP_EXTRACT_STRING ("volume.partition.scheme", vol
->partition_scheme
);
1133 LIBHAL_PROP_EXTRACT_STRING ("volume.partition.type", vol
->partition_type
);
1134 LIBHAL_PROP_EXTRACT_STRING ("volume.partition.label", vol
->partition_label
);
1135 LIBHAL_PROP_EXTRACT_STRING ("volume.partition.uuid", vol
->partition_uuid
);
1136 LIBHAL_PROP_EXTRACT_STRLIST ("volume.partition.flags", vol
->partition_flags
);
1138 LIBHAL_PROP_EXTRACT_UINT64 ("volume.partition.start", vol
->partition_start_offset
);
1139 LIBHAL_PROP_EXTRACT_UINT64 ("volume.partition.media_size", vol
->partition_media_size
);
1140 LIBHAL_PROP_EXTRACT_INT ("volume.partition.msdos_part_table_type", vol
->msdos_part_table_type
);
1141 LIBHAL_PROP_EXTRACT_UINT64 ("volume.partition.msdos_part_table_start", vol
->msdos_part_table_start
);
1142 LIBHAL_PROP_EXTRACT_UINT64 ("volume.partition.msdos_part_table_size", vol
->msdos_part_table_size
);
1144 LIBHAL_PROP_EXTRACT_INT ("block.minor", vol
->device_minor
);
1145 LIBHAL_PROP_EXTRACT_INT ("block.major", vol
->device_major
);
1146 LIBHAL_PROP_EXTRACT_STRING ("block.device", vol
->device_file
);
1148 LIBHAL_PROP_EXTRACT_STRING ("block.storage_device", vol
->storage_device
);
1150 LIBHAL_PROP_EXTRACT_STRING ("volume.crypto_luks.clear.backing_volume", vol
->crypto_backing_volume
);
1152 LIBHAL_PROP_EXTRACT_INT ("volume.block_size", vol
->block_size
);
1153 LIBHAL_PROP_EXTRACT_INT ("volume.num_blocks", vol
->num_blocks
);
1154 LIBHAL_PROP_EXTRACT_UINT64 ("volume.size", vol
->volume_size
);
1155 LIBHAL_PROP_EXTRACT_STRING ("volume.label", vol
->volume_label
);
1156 LIBHAL_PROP_EXTRACT_STRING ("volume.mount_point", vol
->mount_point
);
1157 LIBHAL_PROP_EXTRACT_STRING ("volume.fstype", vol
->fstype
);
1158 LIBHAL_PROP_EXTRACT_STRING ("volume.fsversion", vol
->fsversion
);
1159 LIBHAL_PROP_EXTRACT_BOOL ("volume.is_mounted", vol
->is_mounted
);
1160 LIBHAL_PROP_EXTRACT_BOOL ("volume.is_mounted_read_only", vol
->is_mounted_read_only
);
1161 LIBHAL_PROP_EXTRACT_STRING ("volume.fsusage", vol_fsusage_textual
);
1162 LIBHAL_PROP_EXTRACT_STRING ("volume.uuid", vol
->uuid
);
1164 LIBHAL_PROP_EXTRACT_BOOL ("volume.ignore", vol
->ignore_volume
);
1166 LIBHAL_PROP_EXTRACT_BOOL ("volume.is_disc", vol
->is_disc
);
1167 LIBHAL_PROP_EXTRACT_STRING ("volume.disc.type", disc_type_textual
);
1168 LIBHAL_PROP_EXTRACT_BOOL ("volume.disc.has_audio", vol
->disc_has_audio
);
1169 LIBHAL_PROP_EXTRACT_BOOL ("volume.disc.has_data", vol
->disc_has_data
);
1170 LIBHAL_PROP_EXTRACT_BOOL ("volume.disc.is_appendable", vol
->disc_is_appendable
);
1171 LIBHAL_PROP_EXTRACT_BOOL ("volume.disc.is_blank", vol
->disc_is_blank
);
1172 LIBHAL_PROP_EXTRACT_BOOL ("volume.disc.is_rewritable", vol
->disc_is_rewritable
);
1173 LIBHAL_PROP_EXTRACT_UINT64 ("volume.disc.capacity", vol
->disc_capacity
);
1175 LIBHAL_PROP_EXTRACT_BOOL ("volume.policy.should_mount", vol
->should_mount
);
1176 LIBHAL_PROP_EXTRACT_STRING ("volume.policy.desired_mount_point", vol
->desired_mount_point
);
1177 LIBHAL_PROP_EXTRACT_STRING ("volume.policy.mount_filesystem", vol
->mount_filesystem
);
1179 LIBHAL_PROP_EXTRACT_END
;
1182 if (disc_type_textual
!= NULL
) {
1183 if (strcmp (disc_type_textual
, "cd_rom") == 0) {
1184 vol
->disc_type
= LIBHAL_VOLUME_DISC_TYPE_CDROM
;
1185 } else if (strcmp (disc_type_textual
, "cd_r") == 0) {
1186 vol
->disc_type
= LIBHAL_VOLUME_DISC_TYPE_CDR
;
1187 } else if (strcmp (disc_type_textual
, "cd_rw") == 0) {
1188 vol
->disc_type
= LIBHAL_VOLUME_DISC_TYPE_CDRW
;
1189 } else if (strcmp (disc_type_textual
, "dvd_rom") == 0) {
1190 vol
->disc_type
= LIBHAL_VOLUME_DISC_TYPE_DVDROM
;
1191 } else if (strcmp (disc_type_textual
, "dvd_ram") == 0) {
1192 vol
->disc_type
= LIBHAL_VOLUME_DISC_TYPE_DVDRAM
;
1193 } else if (strcmp (disc_type_textual
, "dvd_r") == 0) {
1194 vol
->disc_type
= LIBHAL_VOLUME_DISC_TYPE_DVDR
;
1195 } else if (strcmp (disc_type_textual
, "dvd_rw") == 0) {
1196 vol
->disc_type
= LIBHAL_VOLUME_DISC_TYPE_DVDRW
;
1197 } else if (strcmp (disc_type_textual
, "dvd_plus_r") == 0) {
1198 vol
->disc_type
= LIBHAL_VOLUME_DISC_TYPE_DVDPLUSR
;
1199 } else if (strcmp (disc_type_textual
, "dvd_plus_rw") == 0) {
1200 vol
->disc_type
= LIBHAL_VOLUME_DISC_TYPE_DVDPLUSRW
;
1201 } else if (strcmp (disc_type_textual
, "dvd_plus_r_dl") == 0) {
1202 vol
->disc_type
= LIBHAL_VOLUME_DISC_TYPE_DVDPLUSR_DL
;
1203 } else if (strcmp (disc_type_textual
, "bd_rom") == 0) {
1204 vol
->disc_type
= LIBHAL_VOLUME_DISC_TYPE_BDROM
;
1205 } else if (strcmp (disc_type_textual
, "bd_r") == 0) {
1206 vol
->disc_type
= LIBHAL_VOLUME_DISC_TYPE_BDR
;
1207 } else if (strcmp (disc_type_textual
, "bd_re") == 0) {
1208 vol
->disc_type
= LIBHAL_VOLUME_DISC_TYPE_BDRE
;
1209 } else if (strcmp (disc_type_textual
, "hddvd_rom") == 0) {
1210 vol
->disc_type
= LIBHAL_VOLUME_DISC_TYPE_HDDVDROM
;
1211 } else if (strcmp (disc_type_textual
, "hddvd_r") == 0) {
1212 vol
->disc_type
= LIBHAL_VOLUME_DISC_TYPE_HDDVDR
;
1213 } else if (strcmp (disc_type_textual
, "hddvd_rw") == 0) {
1214 vol
->disc_type
= LIBHAL_VOLUME_DISC_TYPE_HDDVDRW
;
1218 vol
->fsusage
= LIBHAL_VOLUME_USAGE_UNKNOWN
;
1219 if (vol_fsusage_textual
!= NULL
) {
1220 if (strcmp (vol_fsusage_textual
, "filesystem") == 0) {
1221 vol
->fsusage
= LIBHAL_VOLUME_USAGE_MOUNTABLE_FILESYSTEM
;
1222 } else if (strcmp (vol_fsusage_textual
, "partitiontable") == 0) {
1223 vol
->fsusage
= LIBHAL_VOLUME_USAGE_PARTITION_TABLE
;
1224 } else if (strcmp (vol_fsusage_textual
, "raid") == 0) {
1225 vol
->fsusage
= LIBHAL_VOLUME_USAGE_RAID_MEMBER
;
1226 } else if (strcmp (vol_fsusage_textual
, "crypto") == 0) {
1227 vol
->fsusage
= LIBHAL_VOLUME_USAGE_CRYPTO
;
1228 } else if (strcmp (vol_fsusage_textual
, "other") == 0) {
1229 vol
->fsusage
= LIBHAL_VOLUME_USAGE_OTHER
;
1231 vol
->fsusage
= LIBHAL_VOLUME_USAGE_UNKNOWN
;
1235 libhal_free_string (vol_fsusage_textual
);
1236 libhal_free_string (disc_type_textual
);
1237 libhal_free_property_set (properties
);
1240 if (dbus_error_is_set (&error
)) {
1241 dbus_error_free (&error
);
1243 libhal_free_string (vol_fsusage_textual
);
1244 libhal_free_string (disc_type_textual
);
1245 libhal_free_property_set (properties
);
1246 libhal_volume_free (vol
);
1251 /** If the volume is on a drive with a MSDOS style partition table, return
1252 * the partition table id.
1254 * @param volume Volume object
1255 * @return The partition type or -1 if volume is not
1256 * a partition or the media the volume stems from
1257 * isn't partition with a MS DOS style table
1260 libhal_volume_get_msdos_part_table_type (LibHalVolume
*volume
)
1262 return volume
->msdos_part_table_type
;
1265 /** If the volume is on a drive with a MSDOS style partition table, return
1266 * the partition start offset according to the partition table.
1268 * @param volume Volume object
1269 * @return The partition start offset or -1 if volume isnt
1270 * a partition or the media the volume stems from
1271 * isn't partition with a MS DOS style table
1274 libhal_volume_get_msdos_part_table_start (LibHalVolume
*volume
)
1276 return volume
->msdos_part_table_start
;
1279 /** If the volume is on a drive with a MSDOS style partition table, return
1280 * the partition size according to the partition table.
1282 * @param volume Volume object
1283 * @return The partition size or -1 if volume is not
1284 * a partition or the media the volume stems from
1285 * isn't partition with a MS DOS style table
1288 libhal_volume_get_msdos_part_table_size (LibHalVolume
*volume
)
1290 return volume
->msdos_part_table_size
;
1293 /***********************************************************************/
1295 /** Get the drive object that either is (when given e.g. /dev/sdb) or contains
1296 * (when given e.g. /dev/sdb1) the given device file.
1298 * @param hal_ctx libhal context to use
1299 * @param device_file Name of special device file, e.g. '/dev/hdc'
1300 * @return LibHalDrive object or NULL if it doesn't exist
1303 libhal_drive_from_device_file (LibHalContext
*hal_ctx
, const char *device_file
)
1308 LibHalDrive
*result
;
1312 LIBHAL_CHECK_LIBHALCONTEXT(hal_ctx
, NULL
);
1317 dbus_error_init (&error
);
1318 if ((hal_udis
= libhal_manager_find_device_string_match (hal_ctx
, "block.device",
1319 device_file
, &num_hal_udis
, &error
)) == NULL
) {
1320 LIBHAL_FREE_DBUS_ERROR(&error
);
1324 for (i
= 0; i
< num_hal_udis
; i
++) {
1331 dbus_error_init (&err1
);
1332 dbus_error_init (&err2
);
1333 if (libhal_device_query_capability (hal_ctx
, udi
, "volume", &err1
)) {
1335 storage_udi
= libhal_device_get_property_string (hal_ctx
, udi
, "block.storage_device", &err1
);
1336 if (storage_udi
== NULL
)
1338 found_udi
= strdup (storage_udi
);
1339 libhal_free_string (storage_udi
);
1341 } else if (libhal_device_query_capability (hal_ctx
, udi
, "storage", &err2
)) {
1342 found_udi
= strdup (udi
);
1344 LIBHAL_FREE_DBUS_ERROR(&err1
);
1345 LIBHAL_FREE_DBUS_ERROR(&err2
);
1348 libhal_free_string_array (hal_udis
);
1350 if (found_udi
!= NULL
)
1351 result
= libhal_drive_from_udi (hal_ctx
, found_udi
);
1359 /** Get the volume object for a given device file.
1361 * @param hal_ctx libhal context to use
1362 * @param device_file Name of special device file, e.g. '/dev/hda5'
1363 * @return LibHalVolume object or NULL if it doesn't exist
1366 libhal_volume_from_device_file (LibHalContext
*hal_ctx
, const char *device_file
)
1371 LibHalVolume
*result
;
1375 LIBHAL_CHECK_LIBHALCONTEXT(hal_ctx
, NULL
);
1380 dbus_error_init (&error
);
1381 if ((hal_udis
= libhal_manager_find_device_string_match (hal_ctx
, "block.device",
1382 device_file
, &num_hal_udis
, &error
)) == NULL
)
1385 for (i
= 0; i
< num_hal_udis
; i
++) {
1388 if (libhal_device_query_capability (hal_ctx
, udi
, "volume", &error
)) {
1389 found_udi
= strdup (udi
);
1394 libhal_free_string_array (hal_udis
);
1396 if (found_udi
!= NULL
)
1397 result
= libhal_volume_from_udi (hal_ctx
, found_udi
);
1401 LIBHAL_FREE_DBUS_ERROR(&error
);
1406 libhal_volume_get_size (LibHalVolume
*volume
)
1408 if (volume
->volume_size
> 0)
1409 return volume
->volume_size
;
1411 return ((dbus_uint64_t
)volume
->block_size
) * ((dbus_uint64_t
)volume
->num_blocks
);
1415 libhal_volume_get_disc_capacity (LibHalVolume
*volume
)
1417 return volume
->disc_capacity
;
1422 libhal_drive_is_hotpluggable (LibHalDrive
*drive
)
1424 return drive
->is_hotpluggable
;
1428 libhal_drive_uses_removable_media (LibHalDrive
*drive
)
1430 return drive
->is_removable
;
1434 libhal_drive_is_media_detected (LibHalDrive
*drive
)
1436 return drive
->is_media_detected
;
1440 libhal_drive_get_size (LibHalDrive
*drive
)
1442 return drive
->drive_size
;
1446 libhal_drive_get_media_size (LibHalDrive
*drive
)
1448 return drive
->drive_media_size
;
1452 libhal_drive_get_partition_scheme (LibHalDrive
*drive
)
1454 return drive
->partition_scheme
;
1459 libhal_drive_get_type (LibHalDrive
*drive
)
1465 libhal_drive_get_bus (LibHalDrive
*drive
)
1470 LibHalDriveCdromCaps
1471 libhal_drive_get_cdrom_caps (LibHalDrive
*drive
)
1473 return drive
->cdrom_caps
;
1477 libhal_drive_get_device_major (LibHalDrive
*drive
)
1479 return drive
->device_major
;
1483 libhal_drive_get_device_minor (LibHalDrive
*drive
)
1485 return drive
->device_minor
;
1489 libhal_drive_get_type_textual (LibHalDrive
*drive
)
1491 return drive
->type_textual
;
1495 libhal_drive_get_device_file (LibHalDrive
*drive
)
1497 return drive
->device_file
;
1501 libhal_drive_get_udi (LibHalDrive
*drive
)
1507 libhal_drive_get_serial (LibHalDrive
*drive
)
1509 return drive
->serial
;
1513 libhal_drive_get_firmware_version (LibHalDrive
*drive
)
1515 return drive
->firmware_version
;
1519 libhal_drive_get_model (LibHalDrive
*drive
)
1521 return drive
->model
;
1525 libhal_drive_get_vendor (LibHalDrive
*drive
)
1527 return drive
->vendor
;
1530 /*****************************************************************************/
1533 libhal_volume_get_udi (LibHalVolume
*volume
)
1539 libhal_volume_get_device_file (LibHalVolume
*volume
)
1541 return volume
->device_file
;
1544 unsigned int libhal_volume_get_device_major (LibHalVolume
*volume
)
1546 return volume
->device_major
;
1549 unsigned int libhal_volume_get_device_minor (LibHalVolume
*volume
)
1551 return volume
->device_minor
;
1555 libhal_volume_get_fstype (LibHalVolume
*volume
)
1557 return volume
->fstype
;
1561 libhal_volume_get_fsversion (LibHalVolume
*volume
)
1563 return volume
->fsversion
;
1567 libhal_volume_get_fsusage (LibHalVolume
*volume
)
1569 return volume
->fsusage
;
1573 libhal_volume_is_mounted (LibHalVolume
*volume
)
1575 return volume
->is_mounted
;
1579 libhal_volume_is_mounted_read_only (LibHalVolume
*volume
)
1581 return volume
->is_mounted_read_only
;
1585 libhal_volume_is_partition (LibHalVolume
*volume
)
1587 return volume
->is_partition
;
1591 libhal_volume_is_disc (LibHalVolume
*volume
)
1593 return volume
->is_disc
;
1597 libhal_volume_get_partition_number (LibHalVolume
*volume
)
1599 return volume
->partition_number
;
1603 libhal_volume_get_partition_scheme (LibHalVolume
*volume
)
1605 return volume
->partition_scheme
;
1609 libhal_volume_get_partition_type (LibHalVolume
*volume
)
1611 return volume
->partition_type
;
1615 libhal_volume_get_partition_label (LibHalVolume
*volume
)
1617 return volume
->partition_label
;
1621 libhal_volume_get_partition_uuid (LibHalVolume
*volume
)
1623 return volume
->partition_uuid
;
1627 libhal_volume_get_partition_flags (LibHalVolume
*volume
)
1629 return (const char **) volume
->partition_flags
;
1634 libhal_volume_get_partition_start_offset (LibHalVolume
*volume
)
1636 return volume
->partition_start_offset
;
1640 libhal_volume_get_partition_media_size (LibHalVolume
*volume
)
1642 return volume
->partition_media_size
;
1646 libhal_volume_get_label (LibHalVolume
*volume
)
1648 return volume
->volume_label
;
1652 libhal_volume_get_mount_point (LibHalVolume
*volume
)
1654 return volume
->mount_point
;
1658 libhal_volume_get_uuid (LibHalVolume
*volume
)
1660 return volume
->uuid
;
1664 libhal_volume_disc_has_audio (LibHalVolume
*volume
)
1666 return volume
->disc_has_audio
;
1670 libhal_volume_disc_has_data (LibHalVolume
*volume
)
1672 return volume
->disc_has_data
;
1676 libhal_volume_disc_is_blank (LibHalVolume
*volume
)
1678 return volume
->disc_is_blank
;
1682 libhal_volume_disc_is_rewritable (LibHalVolume
*volume
)
1684 return volume
->disc_is_rewritable
;
1688 libhal_volume_disc_is_appendable (LibHalVolume
*volume
)
1690 return volume
->disc_is_appendable
;
1693 LibHalVolumeDiscType
1694 libhal_volume_get_disc_type (LibHalVolume
*volume
)
1696 return volume
->disc_type
;
1700 libhal_volume_should_ignore (LibHalVolume
*volume
)
1702 return volume
->ignore_volume
;
1706 libhal_drive_find_all_volumes (LibHalContext
*hal_ctx
, LibHalDrive
*drive
, int *num_volumes
)
1711 const char *drive_udi
;
1715 LIBHAL_CHECK_LIBHALCONTEXT(hal_ctx
, NULL
);
1721 drive_udi
= libhal_drive_get_udi (drive
);
1722 if (drive_udi
== NULL
)
1725 /* get initial list... */
1726 dbus_error_init (&error
);
1727 if ((udis
= libhal_manager_find_device_string_match (hal_ctx
, "block.storage_device",
1728 drive_udi
, &num_udis
, &error
)) == NULL
) {
1729 LIBHAL_FREE_DBUS_ERROR(&error
);
1733 result
= malloc (sizeof (char *) * (num_udis
+ 1));
1737 /* ...and filter out the single UDI that is the drive itself */
1738 for (i
= 0; i
< num_udis
; i
++) {
1739 if (strcmp (udis
[i
], drive_udi
) == 0)
1741 result
[*num_volumes
] = strdup (udis
[i
]);
1742 *num_volumes
= (*num_volumes
) + 1;
1744 /* set last element (above removed UDI) to NULL for libhal_free_string_array()*/
1745 result
[*num_volumes
] = NULL
;
1748 libhal_free_string_array (udis
);
1753 libhal_volume_crypto_get_backing_volume_udi (LibHalVolume
*volume
)
1755 return volume
->crypto_backing_volume
;
1759 libhal_volume_crypto_get_clear_volume_udi (LibHalContext
*hal_ctx
, LibHalVolume
*volume
)
1762 char **clear_devices
;
1763 int num_clear_devices
;
1768 LIBHAL_CHECK_LIBHALCONTEXT (hal_ctx
, NULL
);
1770 dbus_error_init (&error
);
1771 clear_devices
= libhal_manager_find_device_string_match (hal_ctx
,
1772 "volume.crypto_luks.clear.backing_volume",
1776 if (clear_devices
!= NULL
) {
1778 if (num_clear_devices
>= 1) {
1779 result
= strdup (clear_devices
[0]);
1781 libhal_free_string_array (clear_devices
);
1788 /*************************************************************************/
1791 libhal_drive_policy_default_get_mount_root (LibHalContext
*hal_ctx
)
1796 LIBHAL_CHECK_LIBHALCONTEXT(hal_ctx
, NULL
);
1798 dbus_error_init (&error
);
1799 if ((result
= libhal_device_get_property_string (hal_ctx
, "/org/freedesktop/Hal/devices/computer",
1800 "storage.policy.default.mount_root", &error
)) == NULL
)
1801 LIBHAL_FREE_DBUS_ERROR(&error
);
1807 libhal_drive_policy_default_use_managed_keyword (LibHalContext
*hal_ctx
)
1812 LIBHAL_CHECK_LIBHALCONTEXT(hal_ctx
, FALSE
);
1814 dbus_error_init (&error
);
1815 if ((result
= libhal_device_get_property_bool (hal_ctx
, "/org/freedesktop/Hal/devices/computer",
1816 "storage.policy.default.use_managed_keyword", &error
)) == FALSE
)
1817 LIBHAL_FREE_DBUS_ERROR(&error
);
1823 libhal_drive_policy_default_get_managed_keyword_primary (LibHalContext
*hal_ctx
)
1828 LIBHAL_CHECK_LIBHALCONTEXT(hal_ctx
, NULL
);
1830 dbus_error_init (&error
);
1831 if ((result
= libhal_device_get_property_string (hal_ctx
, "/org/freedesktop/Hal/devices/computer",
1832 "storage.policy.default.managed_keyword.primary", &error
)) == NULL
)
1833 LIBHAL_FREE_DBUS_ERROR(&error
);
1839 libhal_drive_policy_default_get_managed_keyword_secondary (LibHalContext
*hal_ctx
)
1844 LIBHAL_CHECK_LIBHALCONTEXT(hal_ctx
, NULL
);
1846 dbus_error_init (&error
);
1847 if ((result
= libhal_device_get_property_string (hal_ctx
, "/org/freedesktop/Hal/devices/computer",
1848 "storage.policy.default.managed_keyword.secondary", &error
)) == NULL
)
1849 LIBHAL_FREE_DBUS_ERROR(&error
);
1854 /*************************************************************************/
1857 libhal_drive_policy_is_mountable (LibHalDrive
*drive
, LibHalStoragePolicy
*policy
)
1859 printf ("should_mount=%d, no_partitions_hint=%d\n", drive
->should_mount
, drive
->no_partitions_hint
);
1861 return drive
->should_mount
&& drive
->no_partitions_hint
;
1865 libhal_drive_policy_get_desired_mount_point (LibHalDrive
*drive
, LibHalStoragePolicy
*policy
)
1867 return drive
->desired_mount_point
;
1870 /* safely strcat() at most the remaining space in 'dst' */
1871 #define strcat_len(dst, src, dstmaxlen) do { \
1872 dst[dstmaxlen - 1] = '\0'; \
1873 strncat (dst, src, dstmaxlen - strlen (dst) - 1); \
1878 mopts_collect (LibHalContext
*hal_ctx
, const char *namespace, int namespace_len
,
1879 const char *udi
, char *options_string
, size_t options_max_len
, dbus_bool_t only_collect_imply_opts
)
1881 LibHalPropertySet
*properties
;
1882 LibHalPropertySetIterator it
;
1886 fprintf (stderr
,"%s %d : LibHalContext *ctx is NULL\n",__FILE__
, __LINE__
);
1890 dbus_error_init (&error
);
1892 /* first collect from root computer device */
1893 properties
= libhal_device_get_all_properties (hal_ctx
, udi
, &error
);
1894 if (properties
== NULL
) {
1895 LIBHAL_FREE_DBUS_ERROR(&error
);
1899 for (libhal_psi_init (&it
, properties
); libhal_psi_has_more (&it
); libhal_psi_next (&it
)) {
1903 type
= libhal_psi_get_type (&it
);
1904 key
= libhal_psi_get_key (&it
);
1905 if (libhal_psi_get_type (&it
) == LIBHAL_PROPERTY_TYPE_BOOLEAN
&&
1906 strncmp (key
, namespace, namespace_len
- 1) == 0) {
1907 const char *option
= key
+ namespace_len
- 1;
1909 dbus_bool_t is_imply_opt
;
1911 is_imply_opt
= FALSE
;
1912 if (strcmp (option
, "user") == 0 ||
1913 strcmp (option
, "users") == 0 ||
1914 strcmp (option
, "defaults") == 0 ||
1915 strcmp (option
, "pamconsole") == 0)
1916 is_imply_opt
= TRUE
;
1919 if (only_collect_imply_opts
) {
1927 if (libhal_psi_get_bool (&it
)) {
1928 /* see if option is already there */
1929 location
= strstr (options_string
, option
);
1930 if (location
== NULL
) {
1931 if (strlen (options_string
) > 0)
1932 strcat_len (options_string
, ",", options_max_len
);
1933 strcat_len (options_string
, option
, options_max_len
);
1936 /* remove option if already there */
1937 location
= strstr (options_string
, option
);
1938 if (location
!= NULL
) {
1941 end
= strchr (location
, ',');
1945 strcpy (location
, end
+ 1); /* skip the extra comma */
1953 libhal_free_property_set (properties
);
1958 libhal_drive_policy_get_mount_options (LibHalDrive
*drive
, LibHalStoragePolicy
*policy
)
1961 char stor_mount_option_default_begin
[] = "storage.policy.default.mount_option.";
1962 char stor_mount_option_begin
[] = "storage.policy.mount_option.";
1965 drive
->mount_options
[0] = '\0';
1967 /* collect options != ('pamconsole', 'user', 'users', 'defaults' options that imply other options) */
1968 mopts_collect (drive
->hal_ctx
, stor_mount_option_default_begin
, sizeof (stor_mount_option_default_begin
),
1969 "/org/freedesktop/Hal/devices/computer", drive
->mount_options
, MOUNT_OPTIONS_SIZE
, TRUE
);
1970 mopts_collect (drive
->hal_ctx
, stor_mount_option_begin
, sizeof (stor_mount_option_begin
),
1971 drive
->udi
, drive
->mount_options
, MOUNT_OPTIONS_SIZE
, TRUE
);
1972 /* ensure ('pamconsole', 'user', 'users', 'defaults' options that imply other options), are first */
1973 mopts_collect (drive
->hal_ctx
, stor_mount_option_default_begin
, sizeof (stor_mount_option_default_begin
),
1974 "/org/freedesktop/Hal/devices/computer", drive
->mount_options
, MOUNT_OPTIONS_SIZE
, FALSE
);
1975 mopts_collect (drive
->hal_ctx
, stor_mount_option_begin
, sizeof (stor_mount_option_begin
),
1976 drive
->udi
, drive
->mount_options
, MOUNT_OPTIONS_SIZE
, FALSE
);
1978 result
= drive
->mount_options
;
1984 libhal_drive_policy_get_mount_fs (LibHalDrive
*drive
, LibHalStoragePolicy
*policy
)
1986 return drive
->mount_filesystem
;
1991 libhal_volume_policy_is_mountable (LibHalDrive
*drive
, LibHalVolume
*volume
, LibHalStoragePolicy
*policy
)
1993 return drive
->should_mount
&& volume
->should_mount
;
1996 const char *libhal_volume_policy_get_desired_mount_point (LibHalDrive
*drive
, LibHalVolume
*volume
, LibHalStoragePolicy
*policy
)
1998 return volume
->desired_mount_point
;
2001 const char *libhal_volume_policy_get_mount_options (LibHalDrive
*drive
, LibHalVolume
*volume
, LibHalStoragePolicy
*policy
)
2004 char stor_mount_option_default_begin
[] = "storage.policy.default.mount_option.";
2005 char vol_mount_option_begin
[] = "volume.policy.mount_option.";
2008 volume
->mount_options
[0] = '\0';
2010 /* ensure ('pamconsole', 'user', 'users', 'defaults' options that imply other options), are first */
2011 mopts_collect (drive
->hal_ctx
, stor_mount_option_default_begin
, sizeof (stor_mount_option_default_begin
),
2012 "/org/freedesktop/Hal/devices/computer", volume
->mount_options
, MOUNT_OPTIONS_SIZE
, TRUE
);
2013 mopts_collect (drive
->hal_ctx
, vol_mount_option_begin
, sizeof (vol_mount_option_begin
),
2014 volume
->udi
, volume
->mount_options
, MOUNT_OPTIONS_SIZE
, TRUE
);
2015 /* collect options != ('pamconsole', 'user', 'users', 'defaults' options that imply other options) */
2016 mopts_collect (drive
->hal_ctx
, stor_mount_option_default_begin
, sizeof (stor_mount_option_default_begin
),
2017 "/org/freedesktop/Hal/devices/computer", volume
->mount_options
, MOUNT_OPTIONS_SIZE
, FALSE
);
2018 mopts_collect (drive
->hal_ctx
, vol_mount_option_begin
, sizeof (vol_mount_option_begin
),
2019 volume
->udi
, volume
->mount_options
, MOUNT_OPTIONS_SIZE
, FALSE
);
2021 result
= volume
->mount_options
;
2026 const char *libhal_volume_policy_get_mount_fs (LibHalDrive
*drive
, LibHalVolume
*volume
, LibHalStoragePolicy
*policy
)
2028 return volume
->mount_filesystem
;
2032 libhal_drive_no_partitions_hint (LibHalDrive
*drive
)
2034 return drive
->no_partitions_hint
;