1 /*************************************************************************** 2 * CVSID: $Id$ 3 * 4 * libhal-storage.c : HAL convenience library for storage devices and volumes 5 * 6 * Copyright (C) 2004 Red Hat, Inc. 7 * 8 * Author: David Zeuthen <davidz@redhat.com> 9 * 10 * Licensed under the Academic Free License version 2.1 11 * 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. 16 * 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. 21 * 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 25 * 26 **************************************************************************/ 27 28 #ifdef HAVE_CONFIG_H 29 # include <config.h> 30 #endif 31 32 #include <stdio.h> 33 #include <stdlib.h> 34 #include <string.h> 35 #include <dbus/dbus.h> 36 37 #include <libhal.h> 38 #include "libhal-storage.h" 39 40 41 #ifdef ENABLE_NLS 42 # include <libintl.h> 43 # define _(String) dgettext (GETTEXT_PACKAGE, String) 44 # ifdef gettext_noop 45 # define N_(String) gettext_noop (String) 46 # else 47 # define N_(String) (String) 48 # endif 49 #else 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) 58 #endif 59 60 typedef struct IconMappingEntry_s { 61 LibHalStoragePolicyIcon icon; 62 char *path; 63 struct IconMappingEntry_s *next; 64 } IconMappingEntry; 65 66 struct LibHalStoragePolicy_s { 67 IconMappingEntry *icon_mappings; 68 }; 69 70 LibHalStoragePolicy * 71 libhal_storage_policy_new () 72 { 73 LibHalStoragePolicy *p; 74 75 p = malloc (sizeof (LibHalStoragePolicy)); 76 if (p == NULL) 77 goto out; 78 79 p->icon_mappings = NULL; 80 out: 81 return p; 82 } 83 84 void 85 libhal_storage_policy_free (LibHalStoragePolicy *policy) 86 { 87 IconMappingEntry *i; 88 IconMappingEntry *j; 89 90 /* free all icon mappings */ 91 for (i = policy->icon_mappings; i != NULL; i = j) { 92 j = i->next; 93 free (i->path); 94 free (i); 95 } 96 97 free (policy); 98 } 99 100 void 101 libhal_storage_policy_set_icon_path (LibHalStoragePolicy *policy, LibHalStoragePolicyIcon icon, const char *path) 102 { 103 IconMappingEntry *i; 104 105 /* see if it already exist */ 106 for (i = policy->icon_mappings; i != NULL; i = i->next) { 107 if (i->icon == icon) { 108 free (i->path); 109 i->path = strdup (path); 110 goto out; 111 } 112 } 113 114 i = malloc (sizeof (IconMappingEntry)); 115 if (i == NULL) 116 goto out; 117 i->icon = icon; 118 i->path = strdup (path); 119 i->next = policy->icon_mappings; 120 policy->icon_mappings = i; 121 122 out: 123 return; 124 } 125 126 void 127 libhal_storage_policy_set_icon_mapping (LibHalStoragePolicy *policy, LibHalStoragePolicyIconPair *pairs) 128 { 129 LibHalStoragePolicyIconPair *i; 130 131 for (i = pairs; i->icon != 0x00; i++) { 132 libhal_storage_policy_set_icon_path (policy, i->icon, i->icon_path); 133 } 134 } 135 136 const char * 137 libhal_storage_policy_lookup_icon (LibHalStoragePolicy *policy, LibHalStoragePolicyIcon icon) 138 { 139 IconMappingEntry *i; 140 const char *path; 141 142 path = NULL; 143 for (i = policy->icon_mappings; i != NULL; i = i->next) { 144 if (i->icon == icon) { 145 path = i->path; 146 goto out; 147 } 148 } 149 out: 150 return path; 151 } 152 153 154 #define MAX_STRING_SZ 256 155 156 char * 157 libhal_volume_policy_compute_size_as_string (LibHalVolume *volume) 158 { 159 dbus_uint64_t size; 160 char *result; 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; 165 int cur_str = 0; 166 char buf[MAX_STRING_SZ]; 167 168 result = NULL; 169 170 size = libhal_volume_get_size (volume); 171 172 do { 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); 179 } else { 180 snprintf (buf, MAX_STRING_SZ, "%llu%s", (long long unsigned int) size / cur, sizes_str[cur_str]); 181 result = strdup (buf); 182 } 183 goto out; 184 } 185 186 cur *= step; 187 cur_str++; 188 } while (1); 189 190 out: 191 return result; 192 } 193 194 static void 195 fixup_string (char *s) 196 { 197 /* TODO: first strip leading and trailing whitespace */ 198 /*g_strstrip (s);*/ 199 200 /* TODO: could do nice things on all-upper case strings */ 201 } 202 203 /* volume may be NULL (e.g. if drive supports removable media) */ 204 char * 205 libhal_drive_policy_compute_display_name (LibHalDrive *drive, LibHalVolume *volume, LibHalStoragePolicy *policy) 206 { 207 char *name; 208 char *size_str; 209 char *vendormodel_str; 210 const char *model; 211 const char *vendor; 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]; 217 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); 224 225 if (volume != NULL) 226 size_str = libhal_volume_policy_compute_size_as_string (volume); 227 else 228 size_str = NULL; 229 230 if (vendor == NULL || strlen (vendor) == 0) { 231 if (model == NULL || strlen (model) == 0) 232 vendormodel_str = strdup (""); 233 else 234 vendormodel_str = strdup (model); 235 } else { 236 if (model == NULL || strlen (model) == 0) 237 vendormodel_str = strdup (vendor); 238 else { 239 snprintf (buf, MAX_STRING_SZ, "%s %s", vendor, model); 240 vendormodel_str = strdup (buf); 241 } 242 } 243 244 fixup_string (vendormodel_str); 245 246 if (drive_type==LIBHAL_DRIVE_TYPE_CDROM) { 247 248 /* Optical drive handling */ 249 char *first; 250 char *second; 251 252 253 first = "CD-ROM"; 254 if (drive_cdrom_caps & LIBHAL_DRIVE_CDROM_CAPS_CDR) 255 first = "CD-R"; 256 if (drive_cdrom_caps & LIBHAL_DRIVE_CDROM_CAPS_CDRW) 257 first = "CD-RW"; 258 259 second = ""; 260 if (drive_cdrom_caps & LIBHAL_DRIVE_CDROM_CAPS_DVDROM) 261 second = "/DVD-ROM"; 262 if (drive_cdrom_caps & LIBHAL_DRIVE_CDROM_CAPS_DVDPLUSR) 263 second = "/DVD+R"; 264 if (drive_cdrom_caps & LIBHAL_DRIVE_CDROM_CAPS_DVDPLUSRW) 265 second = "/DVD+RW"; 266 if (drive_cdrom_caps & LIBHAL_DRIVE_CDROM_CAPS_DVDR) 267 second = "/DVD-R"; 268 if (drive_cdrom_caps & LIBHAL_DRIVE_CDROM_CAPS_DVDRW) 269 second = "/DVD-RW"; 270 if (drive_cdrom_caps & LIBHAL_DRIVE_CDROM_CAPS_DVDRAM) 271 second = "/DVD-RAM"; 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"; 276 else 277 second = "/DVD±R"; 278 } 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"; 284 else 285 second = "/DVD±RW"; 286 } 287 if (drive_cdrom_caps & LIBHAL_DRIVE_CDROM_CAPS_BDROM) 288 second = "/BD-ROM"; 289 if (drive_cdrom_caps & LIBHAL_DRIVE_CDROM_CAPS_BDR) 290 second = "/BD-R"; 291 if (drive_cdrom_caps & LIBHAL_DRIVE_CDROM_CAPS_BDRE) 292 second = "/BD-RE"; 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"; 299 300 if (drive_is_hotpluggable) { 301 snprintf (buf, MAX_STRING_SZ, _("External %s%s Drive"), first, second); 302 name = strdup (buf); 303 } else { 304 snprintf (buf, MAX_STRING_SZ, _("%s%s Drive"), first, second); 305 name = strdup (buf); 306 } 307 308 } else if (drive_type==LIBHAL_DRIVE_TYPE_FLOPPY) { 309 310 /* Floppy Drive handling */ 311 312 if (drive_is_hotpluggable) 313 name = strdup (_("External Floppy Drive")); 314 else 315 name = strdup (_("Floppy Drive")); 316 } else if (drive_type==LIBHAL_DRIVE_TYPE_DISK && !drive_is_removable) { 317 318 /* Harddisks */ 319 320 if (size_str != NULL) { 321 if (drive_is_hotpluggable) { 322 snprintf (buf, MAX_STRING_SZ, _("%s External Hard Drive"), size_str); 323 name = strdup (buf); 324 } else { 325 snprintf (buf, MAX_STRING_SZ, _("%s Hard Drive"), size_str); 326 name = strdup (buf); 327 } 328 } else { 329 if (drive_is_hotpluggable) 330 name = strdup (_("External Hard Drive")); 331 else 332 name = strdup (_("Hard Drive")); 333 } 334 } else { 335 336 /* The rest - includes drives with removable Media */ 337 338 if (strlen (vendormodel_str) > 0) 339 name = strdup (vendormodel_str); 340 else 341 name = strdup (_("Drive")); 342 } 343 344 free (vendormodel_str); 345 free (size_str); 346 347 return name; 348 } 349 350 char * 351 libhal_volume_policy_compute_display_name (LibHalDrive *drive, LibHalVolume *volume, LibHalStoragePolicy *policy) 352 { 353 char *name; 354 char *size_str; 355 const char *volume_label; 356 LibHalDriveType drive_type; 357 dbus_bool_t drive_is_removable; 358 char buf[MAX_STRING_SZ]; 359 360 volume_label = libhal_volume_get_label (volume); 361 drive_type = libhal_drive_get_type (drive); 362 drive_is_removable = libhal_drive_uses_removable_media (drive); 363 364 size_str = libhal_volume_policy_compute_size_as_string (volume); 365 366 /* If the volume label is available use that 367 * 368 * TODO: If label is a fully-qualified UNIX path don't use that 369 */ 370 if (volume_label != NULL) { 371 name = strdup (volume_label); 372 goto out; 373 } 374 375 /* Handle media in optical drives */ 376 if (drive_type==LIBHAL_DRIVE_TYPE_CDROM) { 377 switch (libhal_volume_get_disc_type (volume)) { 378 379 default: 380 /* explict fallthrough */ 381 case LIBHAL_VOLUME_DISC_TYPE_CDROM: 382 name = strdup (_("CD-ROM ")); 383 break; 384 385 case LIBHAL_VOLUME_DISC_TYPE_CDR: 386 if (libhal_volume_disc_is_blank (volume)) 387 name = strdup (_("Blank CD-R")); 388 else 389 name = strdup (_("CD-R")); 390 break; 391 392 case LIBHAL_VOLUME_DISC_TYPE_CDRW: 393 if (libhal_volume_disc_is_blank (volume)) 394 name = strdup (_("Blank CD-RW")); 395 else 396 name = strdup (_("CD-RW")); 397 break; 398 399 case LIBHAL_VOLUME_DISC_TYPE_DVDROM: 400 name = strdup (_("DVD-ROM")); 401 break; 402 403 case LIBHAL_VOLUME_DISC_TYPE_DVDRAM: 404 if (libhal_volume_disc_is_blank (volume)) 405 name = strdup (_("Blank DVD-RAM")); 406 else 407 name = strdup (_("DVD-RAM")); 408 break; 409 410 case LIBHAL_VOLUME_DISC_TYPE_DVDR: 411 if (libhal_volume_disc_is_blank (volume)) 412 name = strdup (_("Blank DVD-R")); 413 else 414 name = strdup (_("DVD-R")); 415 break; 416 417 case LIBHAL_VOLUME_DISC_TYPE_DVDRW: 418 if (libhal_volume_disc_is_blank (volume)) 419 name = strdup (_("Blank DVD-RW")); 420 else 421 name = strdup (_("DVD-RW")); 422 break; 423 424 case LIBHAL_VOLUME_DISC_TYPE_DVDPLUSR: 425 if (libhal_volume_disc_is_blank (volume)) 426 name = strdup (_("Blank DVD+R")); 427 else 428 name = strdup (_("DVD+R")); 429 break; 430 431 case LIBHAL_VOLUME_DISC_TYPE_DVDPLUSRW: 432 if (libhal_volume_disc_is_blank (volume)) 433 name = strdup (_("Blank DVD+RW")); 434 else 435 name = strdup (_("DVD+RW")); 436 break; 437 438 case LIBHAL_VOLUME_DISC_TYPE_DVDPLUSR_DL: 439 if (libhal_volume_disc_is_blank (volume)) 440 name = strdup (_("Blank DVD+R Dual-Layer")); 441 else 442 name = strdup (_("DVD+R Dual-Layer")); 443 break; 444 445 case LIBHAL_VOLUME_DISC_TYPE_BDROM: 446 name = strdup (_("BD-ROM")); 447 break; 448 449 case LIBHAL_VOLUME_DISC_TYPE_BDR: 450 if (libhal_volume_disc_is_blank (volume)) 451 name = strdup (_("Blank BD-R")); 452 else 453 name = strdup (_("BD-R")); 454 break; 455 456 case LIBHAL_VOLUME_DISC_TYPE_BDRE: 457 if (libhal_volume_disc_is_blank (volume)) 458 name = strdup (_("Blank BD-RE")); 459 else 460 name = strdup (_("BD-RE")); 461 break; 462 463 case LIBHAL_VOLUME_DISC_TYPE_HDDVDROM: 464 name = strdup (_("HD DVD-ROM")); 465 break; 466 467 case LIBHAL_VOLUME_DISC_TYPE_HDDVDR: 468 if (libhal_volume_disc_is_blank (volume)) 469 name = strdup (_("Blank HD DVD-R")); 470 else 471 name = strdup (_("HD DVD-R")); 472 break; 473 474 case LIBHAL_VOLUME_DISC_TYPE_HDDVDRW: 475 if (libhal_volume_disc_is_blank (volume)) 476 name = strdup (_("Blank HD DVD-RW")); 477 else 478 name = strdup (_("HD DVD-RW")); 479 break; 480 481 } 482 483 /* Special case for pure audio disc */ 484 if (libhal_volume_disc_has_audio (volume) && !libhal_volume_disc_has_data (volume)) { 485 free (name); 486 name = strdup (_("Audio CD")); 487 } 488 489 goto out; 490 } 491 492 /* Fallback: size of media */ 493 if (drive_is_removable) { 494 snprintf (buf, MAX_STRING_SZ, _("%s Removable Media"), size_str); 495 name = strdup (buf); 496 } else { 497 snprintf (buf, MAX_STRING_SZ, _("%s Media"), size_str); 498 name = strdup (buf); 499 } 500 501 /* Fallback: Use drive name */ 502 /*name = libhal_drive_policy_compute_display_name (drive, volume);*/ 503 504 out: 505 free (size_str); 506 return name; 507 } 508 509 char * 510 libhal_drive_policy_compute_icon_name (LibHalDrive *drive, LibHalVolume *volume, LibHalStoragePolicy *policy) 511 { 512 const char *name; 513 LibHalDriveBus bus; 514 LibHalDriveType drive_type; 515 516 bus = libhal_drive_get_bus (drive); 517 drive_type = libhal_drive_get_type (drive); 518 519 /* by design, the enums are laid out so we can do easy computations */ 520 521 switch (drive_type) { 522 case LIBHAL_DRIVE_TYPE_REMOVABLE_DISK: 523 case LIBHAL_DRIVE_TYPE_DISK: 524 case LIBHAL_DRIVE_TYPE_CDROM: 525 case LIBHAL_DRIVE_TYPE_FLOPPY: 526 name = libhal_storage_policy_lookup_icon (policy, 0x10000 + drive_type*0x100 + bus); 527 break; 528 529 default: 530 name = libhal_storage_policy_lookup_icon (policy, 0x10000 + drive_type*0x100); 531 } 532 533 if (name != NULL) 534 return strdup (name); 535 else 536 return NULL; 537 } 538 539 char * 540 libhal_volume_policy_compute_icon_name (LibHalDrive *drive, LibHalVolume *volume, LibHalStoragePolicy *policy) 541 { 542 const char *name; 543 LibHalDriveBus bus; 544 LibHalDriveType drive_type; 545 LibHalVolumeDiscType disc_type; 546 547 /* by design, the enums are laid out so we can do easy computations */ 548 549 if (libhal_volume_is_disc (volume)) { 550 disc_type = libhal_volume_get_disc_type (volume); 551 name = libhal_storage_policy_lookup_icon (policy, 0x30000 + disc_type); 552 goto out; 553 } 554 555 if (drive == NULL) { 556 name = libhal_storage_policy_lookup_icon (policy, LIBHAL_STORAGE_ICON_VOLUME_REMOVABLE_DISK); 557 goto out; 558 } 559 560 bus = libhal_drive_get_bus (drive); 561 drive_type = libhal_drive_get_type (drive); 562 563 switch (drive_type) { 564 case LIBHAL_DRIVE_TYPE_REMOVABLE_DISK: 565 case LIBHAL_DRIVE_TYPE_DISK: 566 case LIBHAL_DRIVE_TYPE_CDROM: 567 case LIBHAL_DRIVE_TYPE_FLOPPY: 568 name = libhal_storage_policy_lookup_icon (policy, 0x20000 + drive_type*0x100 + bus); 569 break; 570 571 default: 572 name = libhal_storage_policy_lookup_icon (policy, 0x20000 + drive_type*0x100); 573 } 574 out: 575 if (name != NULL) 576 return strdup (name); 577 else 578 return NULL; 579 } 580 581 /** Policy function to determine if a volume should be visible in a desktop 582 * environment. This is useful to hide certain system volumes as bootstrap 583 * partitions, the /usr partition, swap partitions and other volumes that 584 * a unprivileged desktop user shouldn't know even exists. 585 * 586 * @param drive Drive that the volume is stemming from 587 * @param volume Volume 588 * @param policy Policy object 589 * @param target_mount_point The mount point that the volume is expected to 590 * be mounted at if not already mounted. This may 591 * e.g. stem from /etc/fstab. If this is NULL the 592 * then mount point isn't taking into account when 593 * evaluating whether the volume should be visible 594 * @return Whether the volume should be shown in a desktop 595 * environment. 596 */ 597 dbus_bool_t 598 libhal_volume_policy_should_be_visible (LibHalDrive *drive, LibHalVolume *volume, LibHalStoragePolicy *policy, 599 const char *target_mount_point) 600 { 601 unsigned int i; 602 dbus_bool_t is_visible; 603 const char *label; 604 const char *mount_point; 605 const char *fstype; 606 const char *fhs23_toplevel_mount_points[] = { 607 "/", 608 "/bin", 609 "/boot", 610 "/dev", 611 "/etc", 612 "/home", 613 "/lib", 614 "/lib64", 615 "/media", 616 "/mnt", 617 "/opt", 618 "/root", 619 "/sbin", 620 "/srv", 621 "/tmp", 622 "/usr", 623 "/var", 624 "/proc", 625 "/sbin", 626 NULL 627 }; 628 629 is_visible = FALSE; 630 631 /* skip if hal says it's not used as a filesystem */ 632 if (libhal_volume_get_fsusage (volume) != LIBHAL_VOLUME_USAGE_MOUNTABLE_FILESYSTEM) 633 goto out; 634 635 label = libhal_volume_get_label (volume); 636 mount_point = libhal_volume_get_mount_point (volume); 637 fstype = libhal_volume_get_fstype (volume); 638 639 /* use target mount point if we're not mounted yet */ 640 if (mount_point == NULL) 641 mount_point = target_mount_point; 642 643 /* bail out if we don't know the filesystem */ 644 if (fstype == NULL) 645 goto out; 646 647 /* blacklist fhs2.3 top level mount points */ 648 if (mount_point != NULL) { 649 for (i = 0; fhs23_toplevel_mount_points[i] != NULL; i++) { 650 if (strcmp (mount_point, fhs23_toplevel_mount_points[i]) == 0) 651 goto out; 652 } 653 } 654 655 /* blacklist partitions with name 'bootstrap' of type HFS (Apple uses that) */ 656 if (label != NULL && strcmp (label, "bootstrap") == 0 && strcmp (fstype, "hfs") == 0) 657 goto out; 658 659 /* only the real lucky mount points will make it this far :-) */ 660 is_visible = TRUE; 661 662 out: 663 return is_visible; 664 } 665 666 /*************************************************************************/ 667 668 #define MOUNT_OPTIONS_SIZE 256 669 670 struct LibHalDrive_s { 671 char *udi; 672 673 int device_major; 674 int device_minor; 675 char *device_file; 676 677 LibHalDriveBus bus; 678 char *vendor; /* may be "", is never NULL */ 679 char *model; /* may be "", is never NULL */ 680 dbus_bool_t is_hotpluggable; 681 dbus_bool_t is_removable; 682 dbus_bool_t is_media_detected; 683 dbus_bool_t requires_eject; 684 685 LibHalDriveType type; 686 char *type_textual; 687 688 char *physical_device; /* UDI of physical device, e.g. the 689 * IDE, USB, IEEE1394 device */ 690 691 char *dedicated_icon_drive; 692 char *dedicated_icon_volume; 693 694 char *serial; 695 char *firmware_version; 696 LibHalDriveCdromCaps cdrom_caps; 697 698 char *desired_mount_point; 699 char *mount_filesystem; 700 dbus_bool_t should_mount; 701 702 dbus_bool_t no_partitions_hint; 703 704 dbus_uint64_t drive_size; 705 dbus_uint64_t drive_media_size; 706 char *partition_scheme; 707 708 LibHalContext *hal_ctx; 709 710 char **capabilities; 711 712 char mount_options[MOUNT_OPTIONS_SIZE]; 713 }; 714 715 struct LibHalVolume_s { 716 char *udi; 717 718 int device_major; 719 int device_minor; 720 char *device_file; 721 char *volume_label; /* may be NULL, is never "" */ 722 dbus_bool_t is_mounted; 723 dbus_bool_t is_mounted_read_only; /* TRUE iff is_mounted and r/o fs */ 724 char *mount_point; /* NULL iff !is_mounted */ 725 char *fstype; /* NULL iff !is_mounted or unknown */ 726 char *fsversion; 727 char *uuid; 728 char *storage_device; 729 730 LibHalVolumeUsage fsusage; 731 732 dbus_bool_t is_partition; 733 unsigned int partition_number; 734 char *partition_scheme; 735 char *partition_type; 736 char *partition_label; 737 char *partition_uuid; 738 char **partition_flags; 739 740 int msdos_part_table_type; 741 dbus_uint64_t msdos_part_table_start; 742 dbus_uint64_t msdos_part_table_size; 743 744 dbus_bool_t is_disc; 745 LibHalVolumeDiscType disc_type; 746 dbus_bool_t disc_has_audio; 747 dbus_bool_t disc_has_data; 748 dbus_bool_t disc_is_appendable; 749 dbus_bool_t disc_is_blank; 750 dbus_bool_t disc_is_rewritable; 751 752 unsigned int block_size; 753 unsigned int num_blocks; 754 755 char *desired_mount_point; 756 char *mount_filesystem; 757 dbus_bool_t should_mount; 758 759 dbus_bool_t ignore_volume; 760 761 char *crypto_backing_volume; 762 763 char mount_options[MOUNT_OPTIONS_SIZE]; 764 765 dbus_uint64_t volume_size; 766 dbus_uint64_t disc_capacity; 767 768 dbus_uint64_t partition_start_offset; 769 dbus_uint64_t partition_media_size; 770 }; 771 772 const char * 773 libhal_drive_get_dedicated_icon_drive (LibHalDrive *drive) 774 { 775 return drive->dedicated_icon_drive; 776 } 777 778 const char * 779 libhal_drive_get_dedicated_icon_volume (LibHalDrive *drive) 780 { 781 return drive->dedicated_icon_volume; 782 } 783 784 /** Free all resources used by a LibHalDrive object. 785 * 786 * @param drive Object to free 787 */ 788 void 789 libhal_drive_free (LibHalDrive *drive) 790 { 791 if (drive == NULL ) 792 return; 793 794 free (drive->udi); 795 libhal_free_string (drive->device_file); 796 libhal_free_string (drive->vendor); 797 libhal_free_string (drive->model); 798 libhal_free_string (drive->type_textual); 799 libhal_free_string (drive->physical_device); 800 libhal_free_string (drive->dedicated_icon_drive); 801 libhal_free_string (drive->dedicated_icon_volume); 802 libhal_free_string (drive->serial); 803 libhal_free_string (drive->firmware_version); 804 libhal_free_string (drive->desired_mount_point); 805 libhal_free_string (drive->mount_filesystem); 806 libhal_free_string_array (drive->capabilities); 807 libhal_free_string (drive->partition_scheme); 808 809 free (drive); 810 } 811 812 813 /** Free all resources used by a LibHalVolume object. 814 * 815 * @param vol Object to free 816 */ 817 void 818 libhal_volume_free (LibHalVolume *vol) 819 { 820 if (vol == NULL ) 821 return; 822 823 free (vol->udi); 824 libhal_free_string (vol->device_file); 825 libhal_free_string (vol->volume_label); 826 libhal_free_string (vol->fstype); 827 libhal_free_string (vol->mount_point); 828 libhal_free_string (vol->fsversion); 829 libhal_free_string (vol->uuid); 830 libhal_free_string (vol->desired_mount_point); 831 libhal_free_string (vol->mount_filesystem); 832 libhal_free_string (vol->crypto_backing_volume); 833 libhal_free_string (vol->storage_device); 834 835 libhal_free_string (vol->partition_scheme); 836 libhal_free_string (vol->partition_type); 837 libhal_free_string (vol->partition_label); 838 libhal_free_string (vol->partition_uuid); 839 libhal_free_string_array (vol->partition_flags); 840 841 free (vol); 842 } 843 844 845 static char ** 846 my_strvdup (char **strv) 847 { 848 unsigned int num_elems; 849 unsigned int i; 850 char **res; 851 852 for (num_elems = 0; strv[num_elems] != NULL; num_elems++) 853 ; 854 855 res = calloc (num_elems + 1, sizeof (char*)); 856 if (res == NULL) 857 goto out; 858 859 for (i = 0; i < num_elems; i++) 860 res[i] = strdup (strv[i]); 861 res[i] = NULL; 862 863 out: 864 return res; 865 } 866 867 /* ok, hey, so this is a bit ugly */ 868 869 #define LIBHAL_PROP_EXTRACT_BEGIN if (FALSE) 870 #define LIBHAL_PROP_EXTRACT_END ; 871 #define LIBHAL_PROP_EXTRACT_INT(_property_, _where_) else if (strcmp (key, _property_) == 0 && type == LIBHAL_PROPERTY_TYPE_INT32) _where_ = libhal_psi_get_int (&it) 872 #define LIBHAL_PROP_EXTRACT_UINT64(_property_, _where_) else if (strcmp (key, _property_) == 0 && type == LIBHAL_PROPERTY_TYPE_UINT64) _where_ = libhal_psi_get_uint64 (&it) 873 #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 874 #define LIBHAL_PROP_EXTRACT_BOOL(_property_, _where_) else if (strcmp (key, _property_) == 0 && type == LIBHAL_PROPERTY_TYPE_BOOLEAN) _where_ = libhal_psi_get_bool (&it) 875 #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 876 #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)) 877 878 /** Given a UDI for a HAL device of capability 'storage', this 879 * function retrieves all the relevant properties into convenient 880 * in-process data structures. 881 * 882 * @param hal_ctx libhal context 883 * @param udi HAL UDI 884 * @return LibHalDrive object or NULL if UDI is invalid 885 */ 886 LibHalDrive * 887 libhal_drive_from_udi (LibHalContext *hal_ctx, const char *udi) 888 { 889 char *bus_textual; 890 LibHalDrive *drive; 891 LibHalPropertySet *properties; 892 LibHalPropertySetIterator it; 893 DBusError error; 894 unsigned int i; 895 896 LIBHAL_CHECK_LIBHALCONTEXT(hal_ctx, NULL); 897 898 drive = NULL; 899 properties = NULL; 900 bus_textual = NULL; 901 902 dbus_error_init (&error); 903 if (!libhal_device_query_capability (hal_ctx, udi, "storage", &error)) 904 goto error; 905 906 drive = malloc (sizeof (LibHalDrive)); 907 if (drive == NULL) 908 goto error; 909 memset (drive, 0x00, sizeof (LibHalDrive)); 910 911 drive->hal_ctx = hal_ctx; 912 913 drive->udi = strdup (udi); 914 if (drive->udi == NULL) 915 goto error; 916 917 properties = libhal_device_get_all_properties (hal_ctx, udi, &error); 918 if (properties == NULL) 919 goto error; 920 921 /* we can count on hal to give us all these properties */ 922 for (libhal_psi_init (&it, properties); libhal_psi_has_more (&it); libhal_psi_next (&it)) { 923 int type; 924 char *key; 925 926 type = libhal_psi_get_type (&it); 927 key = libhal_psi_get_key (&it); 928 929 LIBHAL_PROP_EXTRACT_BEGIN; 930 931 LIBHAL_PROP_EXTRACT_INT ("block.minor", drive->device_minor); 932 LIBHAL_PROP_EXTRACT_INT ("block.major", drive->device_major); 933 LIBHAL_PROP_EXTRACT_STRING ("block.device", drive->device_file); 934 LIBHAL_PROP_EXTRACT_STRING ("storage.bus", bus_textual); 935 LIBHAL_PROP_EXTRACT_STRING ("storage.vendor", drive->vendor); 936 LIBHAL_PROP_EXTRACT_STRING ("storage.model", drive->model); 937 LIBHAL_PROP_EXTRACT_STRING ("storage.drive_type", drive->type_textual); 938 LIBHAL_PROP_EXTRACT_UINT64 ("storage.size", drive->drive_size); 939 940 LIBHAL_PROP_EXTRACT_STRING ("storage.icon.drive", drive->dedicated_icon_drive); 941 LIBHAL_PROP_EXTRACT_STRING ("storage.icon.volume", drive->dedicated_icon_volume); 942 943 LIBHAL_PROP_EXTRACT_BOOL ("storage.hotpluggable", drive->is_hotpluggable); 944 LIBHAL_PROP_EXTRACT_BOOL ("storage.removable", drive->is_removable); 945 LIBHAL_PROP_EXTRACT_BOOL ("storage.removable.media_available", drive->is_media_detected); 946 LIBHAL_PROP_EXTRACT_UINT64 ("storage.removable.media_size", drive->drive_media_size); 947 LIBHAL_PROP_EXTRACT_BOOL ("storage.requires_eject", drive->requires_eject); 948 949 LIBHAL_PROP_EXTRACT_STRING ("storage.partitioning_scheme", drive->partition_scheme); 950 951 LIBHAL_PROP_EXTRACT_STRING ("storage.physical_device", drive->physical_device); 952 LIBHAL_PROP_EXTRACT_STRING ("storage.firmware_version", drive->firmware_version); 953 LIBHAL_PROP_EXTRACT_STRING ("storage.serial", drive->serial); 954 955 LIBHAL_PROP_EXTRACT_BOOL_BITFIELD ("storage.cdrom.cdr", drive->cdrom_caps, LIBHAL_DRIVE_CDROM_CAPS_CDR); 956 LIBHAL_PROP_EXTRACT_BOOL_BITFIELD ("storage.cdrom.cdrw", drive->cdrom_caps, LIBHAL_DRIVE_CDROM_CAPS_CDRW); 957 LIBHAL_PROP_EXTRACT_BOOL_BITFIELD ("storage.cdrom.dvd", drive->cdrom_caps, LIBHAL_DRIVE_CDROM_CAPS_DVDROM); 958 LIBHAL_PROP_EXTRACT_BOOL_BITFIELD ("storage.cdrom.dvdplusr", drive->cdrom_caps, LIBHAL_DRIVE_CDROM_CAPS_DVDPLUSR); 959 LIBHAL_PROP_EXTRACT_BOOL_BITFIELD ("storage.cdrom.dvdplusrw", drive->cdrom_caps, LIBHAL_DRIVE_CDROM_CAPS_DVDPLUSRW); 960 LIBHAL_PROP_EXTRACT_BOOL_BITFIELD ("storage.cdrom.dvdplusrwdl", drive->cdrom_caps, LIBHAL_DRIVE_CDROM_CAPS_DVDPLUSRWDL); 961 LIBHAL_PROP_EXTRACT_BOOL_BITFIELD ("storage.cdrom.dvdplusrdl", drive->cdrom_caps, LIBHAL_DRIVE_CDROM_CAPS_DVDPLUSRDL); 962 LIBHAL_PROP_EXTRACT_BOOL_BITFIELD ("storage.cdrom.dvdr", drive->cdrom_caps, LIBHAL_DRIVE_CDROM_CAPS_DVDR); 963 LIBHAL_PROP_EXTRACT_BOOL_BITFIELD ("storage.cdrom.dvdrw", drive->cdrom_caps, LIBHAL_DRIVE_CDROM_CAPS_DVDRW); 964 LIBHAL_PROP_EXTRACT_BOOL_BITFIELD ("storage.cdrom.dvdram", drive->cdrom_caps, LIBHAL_DRIVE_CDROM_CAPS_DVDRAM); 965 LIBHAL_PROP_EXTRACT_BOOL_BITFIELD ("storage.cdrom.bd", drive->cdrom_caps, LIBHAL_DRIVE_CDROM_CAPS_BDROM); 966 LIBHAL_PROP_EXTRACT_BOOL_BITFIELD ("storage.cdrom.bdr", drive->cdrom_caps, LIBHAL_DRIVE_CDROM_CAPS_BDR); 967 LIBHAL_PROP_EXTRACT_BOOL_BITFIELD ("storage.cdrom.bdre", drive->cdrom_caps, LIBHAL_DRIVE_CDROM_CAPS_BDRE); 968 LIBHAL_PROP_EXTRACT_BOOL_BITFIELD ("storage.cdrom.hddvd", drive->cdrom_caps, LIBHAL_DRIVE_CDROM_CAPS_HDDVDROM); 969 LIBHAL_PROP_EXTRACT_BOOL_BITFIELD ("storage.cdrom.hddvdr", drive->cdrom_caps, LIBHAL_DRIVE_CDROM_CAPS_HDDVDR); 970 LIBHAL_PROP_EXTRACT_BOOL_BITFIELD ("storage.cdrom.hddvdrw", drive->cdrom_caps, LIBHAL_DRIVE_CDROM_CAPS_HDDVDRW); 971 972 LIBHAL_PROP_EXTRACT_BOOL ("storage.policy.should_mount", drive->should_mount); 973 LIBHAL_PROP_EXTRACT_STRING ("storage.policy.desired_mount_point", drive->desired_mount_point); 974 LIBHAL_PROP_EXTRACT_STRING ("storage.policy.mount_filesystem", drive->mount_filesystem); 975 976 LIBHAL_PROP_EXTRACT_BOOL ("storage.no_partitions_hint", drive->no_partitions_hint); 977 978 LIBHAL_PROP_EXTRACT_STRLIST ("info.capabilities", drive->capabilities); 979 980 LIBHAL_PROP_EXTRACT_END; 981 } 982 983 if (drive->type_textual != NULL) { 984 if (strcmp (drive->type_textual, "cdrom") == 0) { 985 drive->cdrom_caps |= LIBHAL_DRIVE_CDROM_CAPS_CDROM; 986 drive->type = LIBHAL_DRIVE_TYPE_CDROM; 987 } else if (strcmp (drive->type_textual, "floppy") == 0) { 988 drive->type = LIBHAL_DRIVE_TYPE_FLOPPY; 989 } else if (strcmp (drive->type_textual, "disk") == 0) { 990 if (drive->is_removable) 991 drive->type = LIBHAL_DRIVE_TYPE_REMOVABLE_DISK; 992 else 993 drive->type = LIBHAL_DRIVE_TYPE_DISK; 994 } else if (strcmp (drive->type_textual, "tape") == 0) { 995 drive->type = LIBHAL_DRIVE_TYPE_TAPE; 996 } else if (strcmp (drive->type_textual, "compact_flash") == 0) { 997 drive->type = LIBHAL_DRIVE_TYPE_COMPACT_FLASH; 998 } else if (strcmp (drive->type_textual, "memory_stick") == 0) { 999 drive->type = LIBHAL_DRIVE_TYPE_MEMORY_STICK; 1000 } else if (strcmp (drive->type_textual, "smart_media") == 0) { 1001 drive->type = LIBHAL_DRIVE_TYPE_SMART_MEDIA; 1002 } else if (strcmp (drive->type_textual, "sd_mmc") == 0) { 1003 drive->type = LIBHAL_DRIVE_TYPE_SD_MMC; 1004 } else if (strcmp (drive->type_textual, "zip") == 0) { 1005 drive->type = LIBHAL_DRIVE_TYPE_ZIP; 1006 } else if (strcmp (drive->type_textual, "jaz") == 0) { 1007 drive->type = LIBHAL_DRIVE_TYPE_JAZ; 1008 } else if (strcmp (drive->type_textual, "flashkey") == 0) { 1009 drive->type = LIBHAL_DRIVE_TYPE_FLASHKEY; 1010 } else { 1011 drive->type = LIBHAL_DRIVE_TYPE_DISK; 1012 } 1013 1014 } 1015 1016 if (drive->capabilities != NULL) { 1017 for (i = 0; drive->capabilities[i] != NULL; i++) { 1018 if (strcmp (drive->capabilities[i], "portable_audio_player") == 0) { 1019 drive->type = LIBHAL_DRIVE_TYPE_PORTABLE_AUDIO_PLAYER; 1020 break; 1021 } else if (strcmp (drive->capabilities[i], "camera") == 0) { 1022 drive->type = LIBHAL_DRIVE_TYPE_CAMERA; 1023 break; 1024 } 1025 } 1026 } 1027 1028 if (bus_textual != NULL) { 1029 if (strcmp (bus_textual, "usb") == 0) { 1030 drive->bus = LIBHAL_DRIVE_BUS_USB; 1031 } else if (strcmp (bus_textual, "ieee1394") == 0) { 1032 drive->bus = LIBHAL_DRIVE_BUS_IEEE1394; 1033 } else if (strcmp (bus_textual, "ide") == 0) { 1034 drive->bus = LIBHAL_DRIVE_BUS_IDE; 1035 } else if (strcmp (bus_textual, "scsi") == 0) { 1036 drive->bus = LIBHAL_DRIVE_BUS_SCSI; 1037 } else if (strcmp (bus_textual, "ccw") == 0) { 1038 drive->bus = LIBHAL_DRIVE_BUS_CCW; 1039 } 1040 } 1041 1042 libhal_free_string (bus_textual); 1043 libhal_free_property_set (properties); 1044 1045 return drive; 1046 1047 error: 1048 LIBHAL_FREE_DBUS_ERROR(&error); 1049 libhal_free_string (bus_textual); 1050 libhal_free_property_set (properties); 1051 libhal_drive_free (drive); 1052 return NULL; 1053 } 1054 1055 const char * 1056 libhal_volume_get_storage_device_udi (LibHalVolume *volume) 1057 { 1058 return volume->storage_device; 1059 } 1060 1061 const char *libhal_drive_get_physical_device_udi (LibHalDrive *drive) 1062 { 1063 return drive->physical_device; 1064 } 1065 1066 dbus_bool_t 1067 libhal_drive_requires_eject (LibHalDrive *drive) 1068 { 1069 return drive->requires_eject; 1070 } 1071 1072 /** Given a UDI for a LIBHAL device of capability 'volume', this 1073 * function retrieves all the relevant properties into convenient 1074 * in-process data structures. 1075 * 1076 * @param hal_ctx libhal context 1077 * @param udi HAL UDI 1078 * @return LibHalVolume object or NULL if UDI is invalid 1079 */ 1080 LibHalVolume * 1081 libhal_volume_from_udi (LibHalContext *hal_ctx, const char *udi) 1082 { 1083 char *disc_type_textual; 1084 char *vol_fsusage_textual; 1085 LibHalVolume *vol; 1086 LibHalPropertySet *properties; 1087 LibHalPropertySetIterator it; 1088 DBusError error; 1089 1090 LIBHAL_CHECK_LIBHALCONTEXT(hal_ctx, NULL); 1091 1092 vol = NULL; 1093 properties = NULL; 1094 disc_type_textual = NULL; 1095 vol_fsusage_textual = NULL; 1096 1097 dbus_error_init (&error); 1098 if (!libhal_device_query_capability (hal_ctx, udi, "volume", &error)) 1099 goto error; 1100 1101 vol = malloc (sizeof (LibHalVolume)); 1102 if (vol == NULL) 1103 goto error; 1104 memset (vol, 0x00, sizeof (LibHalVolume)); 1105 1106 vol->udi = strdup (udi); 1107 1108 properties = libhal_device_get_all_properties (hal_ctx, udi, &error); 1109 if (properties == NULL) 1110 goto error; 1111 1112 /* we can count on hal to give us all these properties */ 1113 for (libhal_psi_init (&it, properties); libhal_psi_has_more (&it); libhal_psi_next (&it)) { 1114 int type; 1115 char *key; 1116 1117 type = libhal_psi_get_type (&it); 1118 key = libhal_psi_get_key (&it); 1119 1120 LIBHAL_PROP_EXTRACT_BEGIN; 1121 1122 LIBHAL_PROP_EXTRACT_BOOL ("volume.is_partition", vol->is_partition); 1123 LIBHAL_PROP_EXTRACT_INT ("volume.partition.number", vol->partition_number); 1124 LIBHAL_PROP_EXTRACT_STRING ("volume.partition.scheme", vol->partition_scheme); 1125 LIBHAL_PROP_EXTRACT_STRING ("volume.partition.type", vol->partition_type); 1126 LIBHAL_PROP_EXTRACT_STRING ("volume.partition.label", vol->partition_label); 1127 LIBHAL_PROP_EXTRACT_STRING ("volume.partition.uuid", vol->partition_uuid); 1128 LIBHAL_PROP_EXTRACT_STRLIST ("volume.partition.flags", vol->partition_flags); 1129 1130 LIBHAL_PROP_EXTRACT_UINT64 ("volume.partition.start", vol->partition_start_offset); 1131 LIBHAL_PROP_EXTRACT_UINT64 ("volume.partition.media_size", vol->partition_media_size); 1132 LIBHAL_PROP_EXTRACT_INT ("volume.partition.msdos_part_table_type", vol->msdos_part_table_type); 1133 LIBHAL_PROP_EXTRACT_UINT64 ("volume.partition.msdos_part_table_start", vol->msdos_part_table_start); 1134 LIBHAL_PROP_EXTRACT_UINT64 ("volume.partition.msdos_part_table_size", vol->msdos_part_table_size); 1135 1136 LIBHAL_PROP_EXTRACT_INT ("block.minor", vol->device_minor); 1137 LIBHAL_PROP_EXTRACT_INT ("block.major", vol->device_major); 1138 LIBHAL_PROP_EXTRACT_STRING ("block.device", vol->device_file); 1139 1140 LIBHAL_PROP_EXTRACT_STRING ("block.storage_device", vol->storage_device); 1141 1142 LIBHAL_PROP_EXTRACT_STRING ("volume.crypto_luks.clear.backing_volume", vol->crypto_backing_volume); 1143 1144 LIBHAL_PROP_EXTRACT_INT ("volume.block_size", vol->block_size); 1145 LIBHAL_PROP_EXTRACT_INT ("volume.num_blocks", vol->num_blocks); 1146 LIBHAL_PROP_EXTRACT_UINT64 ("volume.size", vol->volume_size); 1147 LIBHAL_PROP_EXTRACT_STRING ("volume.label", vol->volume_label); 1148 LIBHAL_PROP_EXTRACT_STRING ("volume.mount_point", vol->mount_point); 1149 LIBHAL_PROP_EXTRACT_STRING ("volume.fstype", vol->fstype); 1150 LIBHAL_PROP_EXTRACT_STRING ("volume.fsversion", vol->fsversion); 1151 LIBHAL_PROP_EXTRACT_BOOL ("volume.is_mounted", vol->is_mounted); 1152 LIBHAL_PROP_EXTRACT_BOOL ("volume.is_mounted_read_only", vol->is_mounted_read_only); 1153 LIBHAL_PROP_EXTRACT_STRING ("volume.fsusage", vol_fsusage_textual); 1154 LIBHAL_PROP_EXTRACT_STRING ("volume.uuid", vol->uuid); 1155 1156 LIBHAL_PROP_EXTRACT_BOOL ("volume.ignore", vol->ignore_volume); 1157 1158 LIBHAL_PROP_EXTRACT_BOOL ("volume.is_disc", vol->is_disc); 1159 LIBHAL_PROP_EXTRACT_STRING ("volume.disc.type", disc_type_textual); 1160 LIBHAL_PROP_EXTRACT_BOOL ("volume.disc.has_audio", vol->disc_has_audio); 1161 LIBHAL_PROP_EXTRACT_BOOL ("volume.disc.has_data", vol->disc_has_data); 1162 LIBHAL_PROP_EXTRACT_BOOL ("volume.disc.is_appendable", vol->disc_is_appendable); 1163 LIBHAL_PROP_EXTRACT_BOOL ("volume.disc.is_blank", vol->disc_is_blank); 1164 LIBHAL_PROP_EXTRACT_BOOL ("volume.disc.is_rewritable", vol->disc_is_rewritable); 1165 LIBHAL_PROP_EXTRACT_UINT64 ("volume.disc.capacity", vol->disc_capacity); 1166 1167 LIBHAL_PROP_EXTRACT_BOOL ("volume.policy.should_mount", vol->should_mount); 1168 LIBHAL_PROP_EXTRACT_STRING ("volume.policy.desired_mount_point", vol->desired_mount_point); 1169 LIBHAL_PROP_EXTRACT_STRING ("volume.policy.mount_filesystem", vol->mount_filesystem); 1170 1171 LIBHAL_PROP_EXTRACT_END; 1172 } 1173 1174 if (disc_type_textual != NULL) { 1175 if (strcmp (disc_type_textual, "cd_rom") == 0) { 1176 vol->disc_type = LIBHAL_VOLUME_DISC_TYPE_CDROM; 1177 } else if (strcmp (disc_type_textual, "cd_r") == 0) { 1178 vol->disc_type = LIBHAL_VOLUME_DISC_TYPE_CDR; 1179 } else if (strcmp (disc_type_textual, "cd_rw") == 0) { 1180 vol->disc_type = LIBHAL_VOLUME_DISC_TYPE_CDRW; 1181 } else if (strcmp (disc_type_textual, "dvd_rom") == 0) { 1182 vol->disc_type = LIBHAL_VOLUME_DISC_TYPE_DVDROM; 1183 } else if (strcmp (disc_type_textual, "dvd_ram") == 0) { 1184 vol->disc_type = LIBHAL_VOLUME_DISC_TYPE_DVDRAM; 1185 } else if (strcmp (disc_type_textual, "dvd_r") == 0) { 1186 vol->disc_type = LIBHAL_VOLUME_DISC_TYPE_DVDR; 1187 } else if (strcmp (disc_type_textual, "dvd_rw") == 0) { 1188 vol->disc_type = LIBHAL_VOLUME_DISC_TYPE_DVDRW; 1189 } else if (strcmp (disc_type_textual, "dvd_plus_r") == 0) { 1190 vol->disc_type = LIBHAL_VOLUME_DISC_TYPE_DVDPLUSR; 1191 } else if (strcmp (disc_type_textual, "dvd_plus_rw") == 0) { 1192 vol->disc_type = LIBHAL_VOLUME_DISC_TYPE_DVDPLUSRW; 1193 } else if (strcmp (disc_type_textual, "dvd_plus_r_dl") == 0) { 1194 vol->disc_type = LIBHAL_VOLUME_DISC_TYPE_DVDPLUSR_DL; 1195 } else if (strcmp (disc_type_textual, "bd_rom") == 0) { 1196 vol->disc_type = LIBHAL_VOLUME_DISC_TYPE_BDROM; 1197 } else if (strcmp (disc_type_textual, "bd_r") == 0) { 1198 vol->disc_type = LIBHAL_VOLUME_DISC_TYPE_BDR; 1199 } else if (strcmp (disc_type_textual, "bd_re") == 0) { 1200 vol->disc_type = LIBHAL_VOLUME_DISC_TYPE_BDRE; 1201 } else if (strcmp (disc_type_textual, "hddvd_rom") == 0) { 1202 vol->disc_type = LIBHAL_VOLUME_DISC_TYPE_HDDVDROM; 1203 } else if (strcmp (disc_type_textual, "hddvd_r") == 0) { 1204 vol->disc_type = LIBHAL_VOLUME_DISC_TYPE_HDDVDR; 1205 } else if (strcmp (disc_type_textual, "hddvd_rw") == 0) { 1206 vol->disc_type = LIBHAL_VOLUME_DISC_TYPE_HDDVDRW; 1207 } 1208 } 1209 1210 vol->fsusage = LIBHAL_VOLUME_USAGE_UNKNOWN; 1211 if (vol_fsusage_textual != NULL) { 1212 if (strcmp (vol_fsusage_textual, "filesystem") == 0) { 1213 vol->fsusage = LIBHAL_VOLUME_USAGE_MOUNTABLE_FILESYSTEM; 1214 } else if (strcmp (vol_fsusage_textual, "partitiontable") == 0) { 1215 vol->fsusage = LIBHAL_VOLUME_USAGE_PARTITION_TABLE; 1216 } else if (strcmp (vol_fsusage_textual, "raid") == 0) { 1217 vol->fsusage = LIBHAL_VOLUME_USAGE_RAID_MEMBER; 1218 } else if (strcmp (vol_fsusage_textual, "crypto") == 0) { 1219 vol->fsusage = LIBHAL_VOLUME_USAGE_CRYPTO; 1220 } else if (strcmp (vol_fsusage_textual, "other") == 0) { 1221 vol->fsusage = LIBHAL_VOLUME_USAGE_OTHER; 1222 } else { 1223 vol->fsusage = LIBHAL_VOLUME_USAGE_UNKNOWN; 1224 } 1225 } 1226 1227 libhal_free_string (vol_fsusage_textual); 1228 libhal_free_string (disc_type_textual); 1229 libhal_free_property_set (properties); 1230 return vol; 1231 error: 1232 if (dbus_error_is_set (&error)) { 1233 dbus_error_free (&error); 1234 } 1235 libhal_free_string (vol_fsusage_textual); 1236 libhal_free_string (disc_type_textual); 1237 libhal_free_property_set (properties); 1238 libhal_volume_free (vol); 1239 return NULL; 1240 } 1241 1242 1243 /** If the volume is on a drive with a MSDOS style partition table, return 1244 * the partition table id. 1245 * 1246 * @param volume Volume object 1247 * @return The partition type or -1 if volume is not 1248 * a partition or the media the volume stems from 1249 * isn't partition with a MS DOS style table 1250 */ 1251 int 1252 libhal_volume_get_msdos_part_table_type (LibHalVolume *volume) 1253 { 1254 return volume->msdos_part_table_type; 1255 } 1256 1257 /** If the volume is on a drive with a MSDOS style partition table, return 1258 * the partition start offset according to the partition table. 1259 * 1260 * @param volume Volume object 1261 * @return The partition start offset or -1 if volume isnt 1262 * a partition or the media the volume stems from 1263 * isn't partition with a MS DOS style table 1264 */ 1265 dbus_uint64_t 1266 libhal_volume_get_msdos_part_table_start (LibHalVolume *volume) 1267 { 1268 return volume->msdos_part_table_start; 1269 } 1270 1271 /** If the volume is on a drive with a MSDOS style partition table, return 1272 * the partition size according to the partition table. 1273 * 1274 * @param volume Volume object 1275 * @return The partition size or -1 if volume is not 1276 * a partition or the media the volume stems from 1277 * isn't partition with a MS DOS style table 1278 */ 1279 dbus_uint64_t 1280 libhal_volume_get_msdos_part_table_size (LibHalVolume *volume) 1281 { 1282 return volume->msdos_part_table_size; 1283 } 1284 1285 /***********************************************************************/ 1286 1287 /** Get the drive object that either is (when given e.g. /dev/sdb) or contains 1288 * (when given e.g. /dev/sdb1) the given device file. 1289 * 1290 * @param hal_ctx libhal context to use 1291 * @param device_file Name of special device file, e.g. '/dev/hdc' 1292 * @return LibHalDrive object or NULL if it doesn't exist 1293 */ 1294 LibHalDrive * 1295 libhal_drive_from_device_file (LibHalContext *hal_ctx, const char *device_file) 1296 { 1297 int i; 1298 char **hal_udis; 1299 int num_hal_udis; 1300 LibHalDrive *result; 1301 char *found_udi; 1302 DBusError error; 1303 1304 LIBHAL_CHECK_LIBHALCONTEXT(hal_ctx, NULL); 1305 1306 result = NULL; 1307 found_udi = NULL; 1308 1309 dbus_error_init (&error); 1310 if ((hal_udis = libhal_manager_find_device_string_match (hal_ctx, "block.device", 1311 device_file, &num_hal_udis, &error)) == NULL) { 1312 LIBHAL_FREE_DBUS_ERROR(&error); 1313 goto out; 1314 } 1315 1316 for (i = 0; i < num_hal_udis; i++) { 1317 char *udi; 1318 char *storage_udi; 1319 DBusError err1; 1320 DBusError err2; 1321 udi = hal_udis[i]; 1322 1323 dbus_error_init (&err1); 1324 dbus_error_init (&err2); 1325 if (libhal_device_query_capability (hal_ctx, udi, "volume", &err1)) { 1326 1327 storage_udi = libhal_device_get_property_string (hal_ctx, udi, "block.storage_device", &err1); 1328 if (storage_udi == NULL) 1329 continue; 1330 found_udi = strdup (storage_udi); 1331 libhal_free_string (storage_udi); 1332 break; 1333 } else if (libhal_device_query_capability (hal_ctx, udi, "storage", &err2)) { 1334 found_udi = strdup (udi); 1335 } 1336 LIBHAL_FREE_DBUS_ERROR(&err1); 1337 LIBHAL_FREE_DBUS_ERROR(&err2); 1338 } 1339 1340 libhal_free_string_array (hal_udis); 1341 1342 if (found_udi != NULL) 1343 result = libhal_drive_from_udi (hal_ctx, found_udi); 1344 1345 free (found_udi); 1346 out: 1347 return result; 1348 } 1349 1350 1351 /** Get the volume object for a given device file. 1352 * 1353 * @param hal_ctx libhal context to use 1354 * @param device_file Name of special device file, e.g. '/dev/hda5' 1355 * @return LibHalVolume object or NULL if it doesn't exist 1356 */ 1357 LibHalVolume * 1358 libhal_volume_from_device_file (LibHalContext *hal_ctx, const char *device_file) 1359 { 1360 int i; 1361 char **hal_udis; 1362 int num_hal_udis; 1363 LibHalVolume *result; 1364 char *found_udi; 1365 DBusError error; 1366 1367 LIBHAL_CHECK_LIBHALCONTEXT(hal_ctx, NULL); 1368 1369 result = NULL; 1370 found_udi = NULL; 1371 1372 dbus_error_init (&error); 1373 if ((hal_udis = libhal_manager_find_device_string_match (hal_ctx, "block.device", 1374 device_file, &num_hal_udis, &error)) == NULL) 1375 goto out; 1376 1377 for (i = 0; i < num_hal_udis; i++) { 1378 char *udi; 1379 udi = hal_udis[i]; 1380 if (libhal_device_query_capability (hal_ctx, udi, "volume", &error)) { 1381 found_udi = strdup (udi); 1382 break; 1383 } 1384 } 1385 1386 libhal_free_string_array (hal_udis); 1387 1388 if (found_udi != NULL) 1389 result = libhal_volume_from_udi (hal_ctx, found_udi); 1390 1391 free (found_udi); 1392 out: 1393 LIBHAL_FREE_DBUS_ERROR(&error); 1394 return result; 1395 } 1396 1397 dbus_uint64_t 1398 libhal_volume_get_size (LibHalVolume *volume) 1399 { 1400 if (volume->volume_size > 0) 1401 return volume->volume_size; 1402 else 1403 return ((dbus_uint64_t)volume->block_size) * ((dbus_uint64_t)volume->num_blocks); 1404 } 1405 1406 dbus_uint64_t 1407 libhal_volume_get_disc_capacity (LibHalVolume *volume) 1408 { 1409 return volume->disc_capacity; 1410 } 1411 1412 1413 dbus_bool_t 1414 libhal_drive_is_hotpluggable (LibHalDrive *drive) 1415 { 1416 return drive->is_hotpluggable; 1417 } 1418 1419 dbus_bool_t 1420 libhal_drive_uses_removable_media (LibHalDrive *drive) 1421 { 1422 return drive->is_removable; 1423 } 1424 1425 dbus_bool_t 1426 libhal_drive_is_media_detected (LibHalDrive *drive) 1427 { 1428 return drive->is_media_detected; 1429 } 1430 1431 dbus_uint64_t 1432 libhal_drive_get_size (LibHalDrive *drive) 1433 { 1434 return drive->drive_size; 1435 } 1436 1437 dbus_uint64_t 1438 libhal_drive_get_media_size (LibHalDrive *drive) 1439 { 1440 return drive->drive_media_size; 1441 } 1442 1443 const char * 1444 libhal_drive_get_partition_scheme (LibHalDrive *drive) 1445 { 1446 return drive->partition_scheme; 1447 } 1448 1449 1450 LibHalDriveType 1451 libhal_drive_get_type (LibHalDrive *drive) 1452 { 1453 return drive->type; 1454 } 1455 1456 LibHalDriveBus 1457 libhal_drive_get_bus (LibHalDrive *drive) 1458 { 1459 return drive->bus; 1460 } 1461 1462 LibHalDriveCdromCaps 1463 libhal_drive_get_cdrom_caps (LibHalDrive *drive) 1464 { 1465 return drive->cdrom_caps; 1466 } 1467 1468 unsigned int 1469 libhal_drive_get_device_major (LibHalDrive *drive) 1470 { 1471 return drive->device_major; 1472 } 1473 1474 unsigned int 1475 libhal_drive_get_device_minor (LibHalDrive *drive) 1476 { 1477 return drive->device_minor; 1478 } 1479 1480 const char * 1481 libhal_drive_get_type_textual (LibHalDrive *drive) 1482 { 1483 return drive->type_textual; 1484 } 1485 1486 const char * 1487 libhal_drive_get_device_file (LibHalDrive *drive) 1488 { 1489 return drive->device_file; 1490 } 1491 1492 const char * 1493 libhal_drive_get_udi (LibHalDrive *drive) 1494 { 1495 return drive->udi; 1496 } 1497 1498 const char * 1499 libhal_drive_get_serial (LibHalDrive *drive) 1500 { 1501 return drive->serial; 1502 } 1503 1504 const char * 1505 libhal_drive_get_firmware_version (LibHalDrive *drive) 1506 { 1507 return drive->firmware_version; 1508 } 1509 1510 const char * 1511 libhal_drive_get_model (LibHalDrive *drive) 1512 { 1513 return drive->model; 1514 } 1515 1516 const char * 1517 libhal_drive_get_vendor (LibHalDrive *drive) 1518 { 1519 return drive->vendor; 1520 } 1521 1522 /*****************************************************************************/ 1523 1524 const char * 1525 libhal_volume_get_udi (LibHalVolume *volume) 1526 { 1527 return volume->udi; 1528 } 1529 1530 const char * 1531 libhal_volume_get_device_file (LibHalVolume *volume) 1532 { 1533 return volume->device_file; 1534 } 1535 1536 unsigned int libhal_volume_get_device_major (LibHalVolume *volume) 1537 { 1538 return volume->device_major; 1539 } 1540 1541 unsigned int libhal_volume_get_device_minor (LibHalVolume *volume) 1542 { 1543 return volume->device_minor; 1544 } 1545 1546 const char * 1547 libhal_volume_get_fstype (LibHalVolume *volume) 1548 { 1549 return volume->fstype; 1550 } 1551 1552 const char * 1553 libhal_volume_get_fsversion (LibHalVolume *volume) 1554 { 1555 return volume->fsversion; 1556 } 1557 1558 LibHalVolumeUsage 1559 libhal_volume_get_fsusage (LibHalVolume *volume) 1560 { 1561 return volume->fsusage; 1562 } 1563 1564 dbus_bool_t 1565 libhal_volume_is_mounted (LibHalVolume *volume) 1566 { 1567 return volume->is_mounted; 1568 } 1569 1570 dbus_bool_t 1571 libhal_volume_is_mounted_read_only (LibHalVolume *volume) 1572 { 1573 return volume->is_mounted_read_only; 1574 } 1575 1576 dbus_bool_t 1577 libhal_volume_is_partition (LibHalVolume *volume) 1578 { 1579 return volume->is_partition; 1580 } 1581 1582 dbus_bool_t 1583 libhal_volume_is_disc (LibHalVolume *volume) 1584 { 1585 return volume->is_disc; 1586 } 1587 1588 unsigned int 1589 libhal_volume_get_partition_number (LibHalVolume *volume) 1590 { 1591 return volume->partition_number; 1592 } 1593 1594 const char * 1595 libhal_volume_get_partition_scheme (LibHalVolume *volume) 1596 { 1597 return volume->partition_scheme; 1598 } 1599 1600 const char * 1601 libhal_volume_get_partition_type (LibHalVolume *volume) 1602 { 1603 return volume->partition_type; 1604 } 1605 1606 const char * 1607 libhal_volume_get_partition_label (LibHalVolume *volume) 1608 { 1609 return volume->partition_label; 1610 } 1611 1612 const char * 1613 libhal_volume_get_partition_uuid (LibHalVolume *volume) 1614 { 1615 return volume->partition_uuid; 1616 } 1617 1618 const char ** 1619 libhal_volume_get_partition_flags (LibHalVolume *volume) 1620 { 1621 return (const char **) volume->partition_flags; 1622 } 1623 1624 1625 dbus_uint64_t 1626 libhal_volume_get_partition_start_offset (LibHalVolume *volume) 1627 { 1628 return volume->partition_start_offset; 1629 } 1630 1631 dbus_uint64_t 1632 libhal_volume_get_partition_media_size (LibHalVolume *volume) 1633 { 1634 return volume->partition_media_size; 1635 } 1636 1637 const char * 1638 libhal_volume_get_label (LibHalVolume *volume) 1639 { 1640 return volume->volume_label; 1641 } 1642 1643 const char * 1644 libhal_volume_get_mount_point (LibHalVolume *volume) 1645 { 1646 return volume->mount_point; 1647 } 1648 1649 const char * 1650 libhal_volume_get_uuid (LibHalVolume *volume) 1651 { 1652 return volume->uuid; 1653 } 1654 1655 dbus_bool_t 1656 libhal_volume_disc_has_audio (LibHalVolume *volume) 1657 { 1658 return volume->disc_has_audio; 1659 } 1660 1661 dbus_bool_t 1662 libhal_volume_disc_has_data (LibHalVolume *volume) 1663 { 1664 return volume->disc_has_data; 1665 } 1666 1667 dbus_bool_t 1668 libhal_volume_disc_is_blank (LibHalVolume *volume) 1669 { 1670 return volume->disc_is_blank; 1671 } 1672 1673 dbus_bool_t 1674 libhal_volume_disc_is_rewritable (LibHalVolume *volume) 1675 { 1676 return volume->disc_is_rewritable; 1677 } 1678 1679 dbus_bool_t 1680 libhal_volume_disc_is_appendable (LibHalVolume *volume) 1681 { 1682 return volume->disc_is_appendable; 1683 } 1684 1685 LibHalVolumeDiscType 1686 libhal_volume_get_disc_type (LibHalVolume *volume) 1687 { 1688 return volume->disc_type; 1689 } 1690 1691 dbus_bool_t 1692 libhal_volume_should_ignore (LibHalVolume *volume) 1693 { 1694 return volume->ignore_volume; 1695 } 1696 1697 char ** 1698 libhal_drive_find_all_volumes (LibHalContext *hal_ctx, LibHalDrive *drive, int *num_volumes) 1699 { 1700 int i; 1701 char **udis; 1702 int num_udis; 1703 const char *drive_udi; 1704 char **result; 1705 DBusError error; 1706 1707 LIBHAL_CHECK_LIBHALCONTEXT(hal_ctx, NULL); 1708 1709 udis = NULL; 1710 result = NULL; 1711 *num_volumes = 0; 1712 1713 drive_udi = libhal_drive_get_udi (drive); 1714 if (drive_udi == NULL) 1715 goto out; 1716 1717 /* get initial list... */ 1718 dbus_error_init (&error); 1719 if ((udis = libhal_manager_find_device_string_match (hal_ctx, "block.storage_device", 1720 drive_udi, &num_udis, &error)) == NULL) { 1721 LIBHAL_FREE_DBUS_ERROR(&error); 1722 goto out; 1723 } 1724 1725 result = malloc (sizeof (char *) * (num_udis + 1)); 1726 if (result == NULL) 1727 goto out; 1728 1729 /* ...and filter out the single UDI that is the drive itself */ 1730 for (i = 0; i < num_udis; i++) { 1731 if (strcmp (udis[i], drive_udi) == 0) 1732 continue; 1733 result[*num_volumes] = strdup (udis[i]); 1734 *num_volumes = (*num_volumes) + 1; 1735 } 1736 /* set last element (above removed UDI) to NULL for libhal_free_string_array()*/ 1737 result[*num_volumes] = NULL; 1738 1739 out: 1740 libhal_free_string_array (udis); 1741 return result; 1742 } 1743 1744 const char * 1745 libhal_volume_crypto_get_backing_volume_udi (LibHalVolume *volume) 1746 { 1747 return volume->crypto_backing_volume; 1748 } 1749 1750 char * 1751 libhal_volume_crypto_get_clear_volume_udi (LibHalContext *hal_ctx, LibHalVolume *volume) 1752 { 1753 DBusError error; 1754 char **clear_devices; 1755 int num_clear_devices; 1756 char *result; 1757 1758 result = NULL; 1759 1760 LIBHAL_CHECK_LIBHALCONTEXT (hal_ctx, NULL); 1761 1762 dbus_error_init (&error); 1763 clear_devices = libhal_manager_find_device_string_match (hal_ctx, 1764 "volume.crypto_luks.clear.backing_volume", 1765 volume->udi, 1766 &num_clear_devices, 1767 &error); 1768 if (clear_devices != NULL) { 1769 1770 if (num_clear_devices >= 1) { 1771 result = strdup (clear_devices[0]); 1772 } 1773 libhal_free_string_array (clear_devices); 1774 } 1775 1776 return result; 1777 } 1778 1779 1780 /*************************************************************************/ 1781 1782 char * 1783 libhal_drive_policy_default_get_mount_root (LibHalContext *hal_ctx) 1784 { 1785 char *result; 1786 DBusError error; 1787 1788 LIBHAL_CHECK_LIBHALCONTEXT(hal_ctx, NULL); 1789 1790 dbus_error_init (&error); 1791 if ((result = libhal_device_get_property_string (hal_ctx, "/org/freedesktop/Hal/devices/computer", 1792 "storage.policy.default.mount_root", &error)) == NULL) 1793 LIBHAL_FREE_DBUS_ERROR(&error); 1794 1795 return result; 1796 } 1797 1798 dbus_bool_t 1799 libhal_drive_policy_default_use_managed_keyword (LibHalContext *hal_ctx) 1800 { 1801 dbus_bool_t result; 1802 DBusError error; 1803 1804 LIBHAL_CHECK_LIBHALCONTEXT(hal_ctx, FALSE); 1805 1806 dbus_error_init (&error); 1807 if ((result = libhal_device_get_property_bool (hal_ctx, "/org/freedesktop/Hal/devices/computer", 1808 "storage.policy.default.use_managed_keyword", &error)) == FALSE) 1809 LIBHAL_FREE_DBUS_ERROR(&error); 1810 1811 return result; 1812 } 1813 1814 char * 1815 libhal_drive_policy_default_get_managed_keyword_primary (LibHalContext *hal_ctx) 1816 { 1817 char *result; 1818 DBusError error; 1819 1820 LIBHAL_CHECK_LIBHALCONTEXT(hal_ctx, NULL); 1821 1822 dbus_error_init (&error); 1823 if ((result = libhal_device_get_property_string (hal_ctx, "/org/freedesktop/Hal/devices/computer", 1824 "storage.policy.default.managed_keyword.primary", &error)) == NULL) 1825 LIBHAL_FREE_DBUS_ERROR(&error); 1826 1827 return result; 1828 } 1829 1830 char * 1831 libhal_drive_policy_default_get_managed_keyword_secondary (LibHalContext *hal_ctx) 1832 { 1833 char *result; 1834 DBusError error; 1835 1836 LIBHAL_CHECK_LIBHALCONTEXT(hal_ctx, NULL); 1837 1838 dbus_error_init (&error); 1839 if ((result = libhal_device_get_property_string (hal_ctx, "/org/freedesktop/Hal/devices/computer", 1840 "storage.policy.default.managed_keyword.secondary", &error)) == NULL) 1841 LIBHAL_FREE_DBUS_ERROR(&error); 1842 1843 return result; 1844 } 1845 1846 /*************************************************************************/ 1847 1848 dbus_bool_t 1849 libhal_drive_policy_is_mountable (LibHalDrive *drive, LibHalStoragePolicy *policy) 1850 { 1851 printf ("should_mount=%d, no_partitions_hint=%d\n", drive->should_mount, drive->no_partitions_hint); 1852 1853 return drive->should_mount && drive->no_partitions_hint; 1854 } 1855 1856 const char * 1857 libhal_drive_policy_get_desired_mount_point (LibHalDrive *drive, LibHalStoragePolicy *policy) 1858 { 1859 return drive->desired_mount_point; 1860 } 1861 1862 /* safely strcat() at most the remaining space in 'dst' */ 1863 #define strcat_len(dst, src, dstmaxlen) do { \ 1864 dst[dstmaxlen - 1] = '\0'; \ 1865 strncat (dst, src, dstmaxlen - strlen (dst) - 1); \ 1866 } while(0) 1867 1868 1869 static void 1870 mopts_collect (LibHalContext *hal_ctx, const char *namespace, int namespace_len, 1871 const char *udi, char *options_string, size_t options_max_len, dbus_bool_t only_collect_imply_opts) 1872 { 1873 LibHalPropertySet *properties; 1874 LibHalPropertySetIterator it; 1875 DBusError error; 1876 1877 if(hal_ctx == 0) { 1878 fprintf (stderr,"%s %d : LibHalContext *ctx is NULL\n",__FILE__, __LINE__); 1879 return; 1880 } 1881 1882 dbus_error_init (&error); 1883 1884 /* first collect from root computer device */ 1885 properties = libhal_device_get_all_properties (hal_ctx, udi, &error); 1886 if (properties == NULL ) { 1887 LIBHAL_FREE_DBUS_ERROR(&error); 1888 return; 1889 } 1890 1891 for (libhal_psi_init (&it, properties); libhal_psi_has_more (&it); libhal_psi_next (&it)) { 1892 int type; 1893 char *key; 1894 1895 type = libhal_psi_get_type (&it); 1896 key = libhal_psi_get_key (&it); 1897 if (type == LIBHAL_PROPERTY_TYPE_BOOLEAN && 1898 strncmp (key, namespace, namespace_len - 1) == 0) { 1899 const char *option = key + namespace_len - 1; 1900 char *location; 1901 dbus_bool_t is_imply_opt; 1902 1903 is_imply_opt = FALSE; 1904 if (strcmp (option, "user") == 0 || 1905 strcmp (option, "users") == 0 || 1906 strcmp (option, "defaults") == 0 || 1907 strcmp (option, "pamconsole") == 0) 1908 is_imply_opt = TRUE; 1909 1910 1911 if (only_collect_imply_opts) { 1912 if (!is_imply_opt) 1913 continue; 1914 } else { 1915 if (is_imply_opt) 1916 continue; 1917 } 1918 1919 if (libhal_psi_get_bool (&it)) { 1920 /* see if option is already there */ 1921 location = strstr (options_string, option); 1922 if (location == NULL) { 1923 if (strlen (options_string) > 0) 1924 strcat_len (options_string, ",", options_max_len); 1925 strcat_len (options_string, option, options_max_len); 1926 } 1927 } else { 1928 /* remove option if already there */ 1929 location = strstr (options_string, option); 1930 if (location != NULL) { 1931 char *end; 1932 1933 end = strchr (location, ','); 1934 if (end == NULL) { 1935 location[0] = '\0'; 1936 } else { 1937 strcpy (location, end + 1); /* skip the extra comma */ 1938 } 1939 } 1940 1941 } 1942 } 1943 } 1944 1945 libhal_free_property_set (properties); 1946 } 1947 1948 1949 const char * 1950 libhal_drive_policy_get_mount_options (LibHalDrive *drive, LibHalStoragePolicy *policy) 1951 { 1952 const char *result; 1953 char stor_mount_option_default_begin[] = "storage.policy.default.mount_option."; 1954 char stor_mount_option_begin[] = "storage.policy.mount_option."; 1955 1956 result = NULL; 1957 drive->mount_options[0] = '\0'; 1958 1959 /* collect options != ('pamconsole', 'user', 'users', 'defaults' options that imply other options) */ 1960 mopts_collect (drive->hal_ctx, stor_mount_option_default_begin, sizeof (stor_mount_option_default_begin), 1961 "/org/freedesktop/Hal/devices/computer", drive->mount_options, MOUNT_OPTIONS_SIZE, TRUE); 1962 mopts_collect (drive->hal_ctx, stor_mount_option_begin, sizeof (stor_mount_option_begin), 1963 drive->udi, drive->mount_options, MOUNT_OPTIONS_SIZE, TRUE); 1964 /* ensure ('pamconsole', 'user', 'users', 'defaults' options that imply other options), are first */ 1965 mopts_collect (drive->hal_ctx, stor_mount_option_default_begin, sizeof (stor_mount_option_default_begin), 1966 "/org/freedesktop/Hal/devices/computer", drive->mount_options, MOUNT_OPTIONS_SIZE, FALSE); 1967 mopts_collect (drive->hal_ctx, stor_mount_option_begin, sizeof (stor_mount_option_begin), 1968 drive->udi, drive->mount_options, MOUNT_OPTIONS_SIZE, FALSE); 1969 1970 result = drive->mount_options; 1971 1972 return result; 1973 } 1974 1975 const char * 1976 libhal_drive_policy_get_mount_fs (LibHalDrive *drive, LibHalStoragePolicy *policy) 1977 { 1978 return drive->mount_filesystem; 1979 } 1980 1981 1982 dbus_bool_t 1983 libhal_volume_policy_is_mountable (LibHalDrive *drive, LibHalVolume *volume, LibHalStoragePolicy *policy) 1984 { 1985 return drive->should_mount && volume->should_mount; 1986 } 1987 1988 const char *libhal_volume_policy_get_desired_mount_point (LibHalDrive *drive, LibHalVolume *volume, LibHalStoragePolicy *policy) 1989 { 1990 return volume->desired_mount_point; 1991 } 1992 1993 const char *libhal_volume_policy_get_mount_options (LibHalDrive *drive, LibHalVolume *volume, LibHalStoragePolicy *policy) 1994 { 1995 const char *result; 1996 char stor_mount_option_default_begin[] = "storage.policy.default.mount_option."; 1997 char vol_mount_option_begin[] = "volume.policy.mount_option."; 1998 1999 result = NULL; 2000 volume->mount_options[0] = '\0'; 2001 2002 /* ensure ('pamconsole', 'user', 'users', 'defaults' options that imply other options), are first */ 2003 mopts_collect (drive->hal_ctx, stor_mount_option_default_begin, sizeof (stor_mount_option_default_begin), 2004 "/org/freedesktop/Hal/devices/computer", volume->mount_options, MOUNT_OPTIONS_SIZE, TRUE); 2005 mopts_collect (drive->hal_ctx, vol_mount_option_begin, sizeof (vol_mount_option_begin), 2006 volume->udi, volume->mount_options, MOUNT_OPTIONS_SIZE, TRUE); 2007 /* collect options != ('pamconsole', 'user', 'users', 'defaults' options that imply other options) */ 2008 mopts_collect (drive->hal_ctx, stor_mount_option_default_begin, sizeof (stor_mount_option_default_begin), 2009 "/org/freedesktop/Hal/devices/computer", volume->mount_options, MOUNT_OPTIONS_SIZE, FALSE); 2010 mopts_collect (drive->hal_ctx, vol_mount_option_begin, sizeof (vol_mount_option_begin), 2011 volume->udi, volume->mount_options, MOUNT_OPTIONS_SIZE, FALSE); 2012 2013 result = volume->mount_options; 2014 2015 return result; 2016 } 2017 2018 const char *libhal_volume_policy_get_mount_fs (LibHalDrive *drive, LibHalVolume *volume, LibHalStoragePolicy *policy) 2019 { 2020 return volume->mount_filesystem; 2021 } 2022 2023 dbus_bool_t 2024 libhal_drive_no_partitions_hint (LibHalDrive *drive) 2025 { 2026 return drive->no_partitions_hint; 2027 } 2028 2029 /** @} */ 2030