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 const char *model; 357 const char *vendor; 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]; 363 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); 371 372 size_str = libhal_volume_policy_compute_size_as_string (volume); 373 374 /* If the volume label is available use that 375 * 376 * TODO: If label is a fully-qualified UNIX path don't use that 377 */ 378 if (volume_label != NULL) { 379 name = strdup (volume_label); 380 goto out; 381 } 382 383 /* Handle media in optical drives */ 384 if (drive_type==LIBHAL_DRIVE_TYPE_CDROM) { 385 switch (libhal_volume_get_disc_type (volume)) { 386 387 default: 388 /* explict fallthrough */ 389 case LIBHAL_VOLUME_DISC_TYPE_CDROM: 390 name = strdup (_("CD-ROM ")); 391 break; 392 393 case LIBHAL_VOLUME_DISC_TYPE_CDR: 394 if (libhal_volume_disc_is_blank (volume)) 395 name = strdup (_("Blank CD-R")); 396 else 397 name = strdup (_("CD-R")); 398 break; 399 400 case LIBHAL_VOLUME_DISC_TYPE_CDRW: 401 if (libhal_volume_disc_is_blank (volume)) 402 name = strdup (_("Blank CD-RW")); 403 else 404 name = strdup (_("CD-RW")); 405 break; 406 407 case LIBHAL_VOLUME_DISC_TYPE_DVDROM: 408 name = strdup (_("DVD-ROM")); 409 break; 410 411 case LIBHAL_VOLUME_DISC_TYPE_DVDRAM: 412 if (libhal_volume_disc_is_blank (volume)) 413 name = strdup (_("Blank DVD-RAM")); 414 else 415 name = strdup (_("DVD-RAM")); 416 break; 417 418 case LIBHAL_VOLUME_DISC_TYPE_DVDR: 419 if (libhal_volume_disc_is_blank (volume)) 420 name = strdup (_("Blank DVD-R")); 421 else 422 name = strdup (_("DVD-R")); 423 break; 424 425 case LIBHAL_VOLUME_DISC_TYPE_DVDRW: 426 if (libhal_volume_disc_is_blank (volume)) 427 name = strdup (_("Blank DVD-RW")); 428 else 429 name = strdup (_("DVD-RW")); 430 break; 431 432 case LIBHAL_VOLUME_DISC_TYPE_DVDPLUSR: 433 if (libhal_volume_disc_is_blank (volume)) 434 name = strdup (_("Blank DVD+R")); 435 else 436 name = strdup (_("DVD+R")); 437 break; 438 439 case LIBHAL_VOLUME_DISC_TYPE_DVDPLUSRW: 440 if (libhal_volume_disc_is_blank (volume)) 441 name = strdup (_("Blank DVD+RW")); 442 else 443 name = strdup (_("DVD+RW")); 444 break; 445 446 case LIBHAL_VOLUME_DISC_TYPE_DVDPLUSR_DL: 447 if (libhal_volume_disc_is_blank (volume)) 448 name = strdup (_("Blank DVD+R Dual-Layer")); 449 else 450 name = strdup (_("DVD+R Dual-Layer")); 451 break; 452 453 case LIBHAL_VOLUME_DISC_TYPE_BDROM: 454 name = strdup (_("BD-ROM")); 455 break; 456 457 case LIBHAL_VOLUME_DISC_TYPE_BDR: 458 if (libhal_volume_disc_is_blank (volume)) 459 name = strdup (_("Blank BD-R")); 460 else 461 name = strdup (_("BD-R")); 462 break; 463 464 case LIBHAL_VOLUME_DISC_TYPE_BDRE: 465 if (libhal_volume_disc_is_blank (volume)) 466 name = strdup (_("Blank BD-RE")); 467 else 468 name = strdup (_("BD-RE")); 469 break; 470 471 case LIBHAL_VOLUME_DISC_TYPE_HDDVDROM: 472 name = strdup (_("HD DVD-ROM")); 473 break; 474 475 case LIBHAL_VOLUME_DISC_TYPE_HDDVDR: 476 if (libhal_volume_disc_is_blank (volume)) 477 name = strdup (_("Blank HD DVD-R")); 478 else 479 name = strdup (_("HD DVD-R")); 480 break; 481 482 case LIBHAL_VOLUME_DISC_TYPE_HDDVDRW: 483 if (libhal_volume_disc_is_blank (volume)) 484 name = strdup (_("Blank HD DVD-RW")); 485 else 486 name = strdup (_("HD DVD-RW")); 487 break; 488 489 } 490 491 /* Special case for pure audio disc */ 492 if (libhal_volume_disc_has_audio (volume) && !libhal_volume_disc_has_data (volume)) { 493 free (name); 494 name = strdup (_("Audio CD")); 495 } 496 497 goto out; 498 } 499 500 /* Fallback: size of media */ 501 if (drive_is_removable) { 502 snprintf (buf, MAX_STRING_SZ, _("%s Removable Media"), size_str); 503 name = strdup (buf); 504 } else { 505 snprintf (buf, MAX_STRING_SZ, _("%s Media"), size_str); 506 name = strdup (buf); 507 } 508 509 /* Fallback: Use drive name */ 510 /*name = libhal_drive_policy_compute_display_name (drive, volume);*/ 511 512 out: 513 free (size_str); 514 return name; 515 } 516 517 char * 518 libhal_drive_policy_compute_icon_name (LibHalDrive *drive, LibHalVolume *volume, LibHalStoragePolicy *policy) 519 { 520 const char *name; 521 LibHalDriveBus bus; 522 LibHalDriveType drive_type; 523 524 bus = libhal_drive_get_bus (drive); 525 drive_type = libhal_drive_get_type (drive); 526 527 /* by design, the enums are laid out so we can do easy computations */ 528 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); 535 break; 536 537 default: 538 name = libhal_storage_policy_lookup_icon (policy, 0x10000 + drive_type*0x100); 539 } 540 541 if (name != NULL) 542 return strdup (name); 543 else 544 return NULL; 545 } 546 547 char * 548 libhal_volume_policy_compute_icon_name (LibHalDrive *drive, LibHalVolume *volume, LibHalStoragePolicy *policy) 549 { 550 const char *name; 551 LibHalDriveBus bus; 552 LibHalDriveType drive_type; 553 LibHalVolumeDiscType disc_type; 554 555 /* by design, the enums are laid out so we can do easy computations */ 556 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); 560 goto out; 561 } 562 563 if (drive == NULL) { 564 name = libhal_storage_policy_lookup_icon (policy, LIBHAL_STORAGE_ICON_VOLUME_REMOVABLE_DISK); 565 goto out; 566 } 567 568 bus = libhal_drive_get_bus (drive); 569 drive_type = libhal_drive_get_type (drive); 570 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); 577 break; 578 579 default: 580 name = libhal_storage_policy_lookup_icon (policy, 0x20000 + drive_type*0x100); 581 } 582 out: 583 if (name != NULL) 584 return strdup (name); 585 else 586 return NULL; 587 } 588 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. 593 * 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 603 * environment. 604 */ 605 dbus_bool_t 606 libhal_volume_policy_should_be_visible (LibHalDrive *drive, LibHalVolume *volume, LibHalStoragePolicy *policy, 607 const char *target_mount_point) 608 { 609 unsigned int i; 610 dbus_bool_t is_visible; 611 const char *label; 612 const char *mount_point; 613 const char *fstype; 614 const char *fhs23_toplevel_mount_points[] = { 615 "/", 616 "/bin", 617 "/boot", 618 "/dev", 619 "/etc", 620 "/home", 621 "/lib", 622 "/lib64", 623 "/media", 624 "/mnt", 625 "/opt", 626 "/root", 627 "/sbin", 628 "/srv", 629 "/tmp", 630 "/usr", 631 "/var", 632 "/proc", 633 "/sbin", 634 NULL 635 }; 636 637 is_visible = FALSE; 638 639 /* skip if hal says it's not used as a filesystem */ 640 if (libhal_volume_get_fsusage (volume) != LIBHAL_VOLUME_USAGE_MOUNTABLE_FILESYSTEM) 641 goto out; 642 643 label = libhal_volume_get_label (volume); 644 mount_point = libhal_volume_get_mount_point (volume); 645 fstype = libhal_volume_get_fstype (volume); 646 647 /* use target mount point if we're not mounted yet */ 648 if (mount_point == NULL) 649 mount_point = target_mount_point; 650 651 /* bail out if we don't know the filesystem */ 652 if (fstype == NULL) 653 goto out; 654 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) 659 goto out; 660 } 661 } 662 663 /* blacklist partitions with name 'bootstrap' of type HFS (Apple uses that) */ 664 if (label != NULL && strcmp (label, "bootstrap") == 0 && strcmp (fstype, "hfs") == 0) 665 goto out; 666 667 /* only the real lucky mount points will make it this far :-) */ 668 is_visible = TRUE; 669 670 out: 671 return is_visible; 672 } 673 674 /*************************************************************************/ 675 676 #define MOUNT_OPTIONS_SIZE 256 677 678 struct LibHalDrive_s { 679 char *udi; 680 681 int device_major; 682 int device_minor; 683 char *device_file; 684 685 LibHalDriveBus bus; 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; 692 693 LibHalDriveType type; 694 char *type_textual; 695 696 char *physical_device; /* UDI of physical device, e.g. the 697 * IDE, USB, IEEE1394 device */ 698 699 char *dedicated_icon_drive; 700 char *dedicated_icon_volume; 701 702 char *serial; 703 char *firmware_version; 704 LibHalDriveCdromCaps cdrom_caps; 705 706 char *desired_mount_point; 707 char *mount_filesystem; 708 dbus_bool_t should_mount; 709 710 dbus_bool_t no_partitions_hint; 711 712 dbus_uint64_t drive_size; 713 dbus_uint64_t drive_media_size; 714 char *partition_scheme; 715 716 LibHalContext *hal_ctx; 717 718 char **capabilities; 719 720 char mount_options[MOUNT_OPTIONS_SIZE]; 721 }; 722 723 struct LibHalVolume_s { 724 char *udi; 725 726 int device_major; 727 int device_minor; 728 char *device_file; 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 */ 734 char *fsversion; 735 char *uuid; 736 char *storage_device; 737 738 LibHalVolumeUsage fsusage; 739 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; 747 748 int msdos_part_table_type; 749 dbus_uint64_t msdos_part_table_start; 750 dbus_uint64_t msdos_part_table_size; 751 752 dbus_bool_t is_disc; 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; 759 760 unsigned int block_size; 761 unsigned int num_blocks; 762 763 char *desired_mount_point; 764 char *mount_filesystem; 765 dbus_bool_t should_mount; 766 767 dbus_bool_t ignore_volume; 768 769 char *crypto_backing_volume; 770 771 char mount_options[MOUNT_OPTIONS_SIZE]; 772 773 dbus_uint64_t volume_size; 774 dbus_uint64_t disc_capacity; 775 776 dbus_uint64_t partition_start_offset; 777 dbus_uint64_t partition_media_size; 778 }; 779 780 const char * 781 libhal_drive_get_dedicated_icon_drive (LibHalDrive *drive) 782 { 783 return drive->dedicated_icon_drive; 784 } 785 786 const char * 787 libhal_drive_get_dedicated_icon_volume (LibHalDrive *drive) 788 { 789 return drive->dedicated_icon_volume; 790 } 791 792 /** Free all resources used by a LibHalDrive object. 793 * 794 * @param drive Object to free 795 */ 796 void 797 libhal_drive_free (LibHalDrive *drive) 798 { 799 if (drive == NULL ) 800 return; 801 802 free (drive->udi); 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); 816 817 free (drive); 818 } 819 820 821 /** Free all resources used by a LibHalVolume object. 822 * 823 * @param vol Object to free 824 */ 825 void 826 libhal_volume_free (LibHalVolume *vol) 827 { 828 if (vol == NULL ) 829 return; 830 831 free (vol->udi); 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); 842 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); 848 849 free (vol); 850 } 851 852 853 static char ** 854 my_strvdup (char **strv) 855 { 856 unsigned int num_elems; 857 unsigned int i; 858 char **res; 859 860 for (num_elems = 0; strv[num_elems] != NULL; num_elems++) 861 ; 862 863 res = calloc (num_elems + 1, sizeof (char*)); 864 if (res == NULL) 865 goto out; 866 867 for (i = 0; i < num_elems; i++) 868 res[i] = strdup (strv[i]); 869 res[i] = NULL; 870 871 out: 872 return res; 873 } 874 875 /* ok, hey, so this is a bit ugly */ 876 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)) 885 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. 889 * 890 * @param hal_ctx libhal context 891 * @param udi HAL UDI 892 * @return LibHalDrive object or NULL if UDI is invalid 893 */ 894 LibHalDrive * 895 libhal_drive_from_udi (LibHalContext *hal_ctx, const char *udi) 896 { 897 char *bus_textual; 898 LibHalDrive *drive; 899 LibHalPropertySet *properties; 900 LibHalPropertySetIterator it; 901 DBusError error; 902 unsigned int i; 903 904 LIBHAL_CHECK_LIBHALCONTEXT(hal_ctx, NULL); 905 906 drive = NULL; 907 properties = NULL; 908 bus_textual = NULL; 909 910 dbus_error_init (&error); 911 if (!libhal_device_query_capability (hal_ctx, udi, "storage", &error)) 912 goto error; 913 914 drive = malloc (sizeof (LibHalDrive)); 915 if (drive == NULL) 916 goto error; 917 memset (drive, 0x00, sizeof (LibHalDrive)); 918 919 drive->hal_ctx = hal_ctx; 920 921 drive->udi = strdup (udi); 922 if (drive->udi == NULL) 923 goto error; 924 925 properties = libhal_device_get_all_properties (hal_ctx, udi, &error); 926 if (properties == NULL) 927 goto error; 928 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)) { 931 int type; 932 char *key; 933 934 type = libhal_psi_get_type (&it); 935 key = libhal_psi_get_key (&it); 936 937 LIBHAL_PROP_EXTRACT_BEGIN; 938 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); 947 948 LIBHAL_PROP_EXTRACT_STRING ("storage.icon.drive", drive->dedicated_icon_drive); 949 LIBHAL_PROP_EXTRACT_STRING ("storage.icon.volume", drive->dedicated_icon_volume); 950 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); 956 957 LIBHAL_PROP_EXTRACT_STRING ("storage.partitioning_scheme", drive->partition_scheme); 958 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); 962 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); 979 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); 983 984 LIBHAL_PROP_EXTRACT_BOOL ("storage.no_partitions_hint", drive->no_partitions_hint); 985 986 LIBHAL_PROP_EXTRACT_STRLIST ("info.capabilities", drive->capabilities); 987 988 LIBHAL_PROP_EXTRACT_END; 989 } 990 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; 1000 else 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; 1018 } else { 1019 drive->type = LIBHAL_DRIVE_TYPE_DISK; 1020 } 1021 1022 } 1023 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; 1028 break; 1029 } else if (strcmp (drive->capabilities[i], "camera") == 0) { 1030 drive->type = LIBHAL_DRIVE_TYPE_CAMERA; 1031 break; 1032 } 1033 } 1034 } 1035 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; 1047 } 1048 } 1049 1050 libhal_free_string (bus_textual); 1051 libhal_free_property_set (properties); 1052 1053 return drive; 1054 1055 error: 1056 LIBHAL_FREE_DBUS_ERROR(&error); 1057 libhal_free_string (bus_textual); 1058 libhal_free_property_set (properties); 1059 libhal_drive_free (drive); 1060 return NULL; 1061 } 1062 1063 const char * 1064 libhal_volume_get_storage_device_udi (LibHalVolume *volume) 1065 { 1066 return volume->storage_device; 1067 } 1068 1069 const char *libhal_drive_get_physical_device_udi (LibHalDrive *drive) 1070 { 1071 return drive->physical_device; 1072 } 1073 1074 dbus_bool_t 1075 libhal_drive_requires_eject (LibHalDrive *drive) 1076 { 1077 return drive->requires_eject; 1078 } 1079 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. 1083 * 1084 * @param hal_ctx libhal context 1085 * @param udi HAL UDI 1086 * @return LibHalVolume object or NULL if UDI is invalid 1087 */ 1088 LibHalVolume * 1089 libhal_volume_from_udi (LibHalContext *hal_ctx, const char *udi) 1090 { 1091 char *disc_type_textual; 1092 char *vol_fsusage_textual; 1093 LibHalVolume *vol; 1094 LibHalPropertySet *properties; 1095 LibHalPropertySetIterator it; 1096 DBusError error; 1097 1098 LIBHAL_CHECK_LIBHALCONTEXT(hal_ctx, NULL); 1099 1100 vol = NULL; 1101 properties = NULL; 1102 disc_type_textual = NULL; 1103 vol_fsusage_textual = NULL; 1104 1105 dbus_error_init (&error); 1106 if (!libhal_device_query_capability (hal_ctx, udi, "volume", &error)) 1107 goto error; 1108 1109 vol = malloc (sizeof (LibHalVolume)); 1110 if (vol == NULL) 1111 goto error; 1112 memset (vol, 0x00, sizeof (LibHalVolume)); 1113 1114 vol->udi = strdup (udi); 1115 1116 properties = libhal_device_get_all_properties (hal_ctx, udi, &error); 1117 if (properties == NULL) 1118 goto error; 1119 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)) { 1122 int type; 1123 char *key; 1124 1125 type = libhal_psi_get_type (&it); 1126 key = libhal_psi_get_key (&it); 1127 1128 LIBHAL_PROP_EXTRACT_BEGIN; 1129 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); 1137 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); 1143 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); 1147 1148 LIBHAL_PROP_EXTRACT_STRING ("block.storage_device", vol->storage_device); 1149 1150 LIBHAL_PROP_EXTRACT_STRING ("volume.crypto_luks.clear.backing_volume", vol->crypto_backing_volume); 1151 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); 1163 1164 LIBHAL_PROP_EXTRACT_BOOL ("volume.ignore", vol->ignore_volume); 1165 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); 1174 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); 1178 1179 LIBHAL_PROP_EXTRACT_END; 1180 } 1181 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; 1215 } 1216 } 1217 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; 1230 } else { 1231 vol->fsusage = LIBHAL_VOLUME_USAGE_UNKNOWN; 1232 } 1233 } 1234 1235 libhal_free_string (vol_fsusage_textual); 1236 libhal_free_string (disc_type_textual); 1237 libhal_free_property_set (properties); 1238 return vol; 1239 error: 1240 if (dbus_error_is_set (&error)) { 1241 dbus_error_free (&error); 1242 } 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); 1247 return NULL; 1248 } 1249 1250 1251 /** If the volume is on a drive with a MSDOS style partition table, return 1252 * the partition table id. 1253 * 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 1258 */ 1259 int 1260 libhal_volume_get_msdos_part_table_type (LibHalVolume *volume) 1261 { 1262 return volume->msdos_part_table_type; 1263 } 1264 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. 1267 * 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 1272 */ 1273 dbus_uint64_t 1274 libhal_volume_get_msdos_part_table_start (LibHalVolume *volume) 1275 { 1276 return volume->msdos_part_table_start; 1277 } 1278 1279 /** If the volume is on a drive with a MSDOS style partition table, return 1280 * the partition size according to the partition table. 1281 * 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 1286 */ 1287 dbus_uint64_t 1288 libhal_volume_get_msdos_part_table_size (LibHalVolume *volume) 1289 { 1290 return volume->msdos_part_table_size; 1291 } 1292 1293 /***********************************************************************/ 1294 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. 1297 * 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 1301 */ 1302 LibHalDrive * 1303 libhal_drive_from_device_file (LibHalContext *hal_ctx, const char *device_file) 1304 { 1305 int i; 1306 char **hal_udis; 1307 int num_hal_udis; 1308 LibHalDrive *result; 1309 char *found_udi; 1310 DBusError error; 1311 1312 LIBHAL_CHECK_LIBHALCONTEXT(hal_ctx, NULL); 1313 1314 result = NULL; 1315 found_udi = NULL; 1316 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); 1321 goto out; 1322 } 1323 1324 for (i = 0; i < num_hal_udis; i++) { 1325 char *udi; 1326 char *storage_udi; 1327 DBusError err1; 1328 DBusError err2; 1329 udi = hal_udis[i]; 1330 1331 dbus_error_init (&err1); 1332 dbus_error_init (&err2); 1333 if (libhal_device_query_capability (hal_ctx, udi, "volume", &err1)) { 1334 1335 storage_udi = libhal_device_get_property_string (hal_ctx, udi, "block.storage_device", &err1); 1336 if (storage_udi == NULL) 1337 continue; 1338 found_udi = strdup (storage_udi); 1339 libhal_free_string (storage_udi); 1340 break; 1341 } else if (libhal_device_query_capability (hal_ctx, udi, "storage", &err2)) { 1342 found_udi = strdup (udi); 1343 } 1344 LIBHAL_FREE_DBUS_ERROR(&err1); 1345 LIBHAL_FREE_DBUS_ERROR(&err2); 1346 } 1347 1348 libhal_free_string_array (hal_udis); 1349 1350 if (found_udi != NULL) 1351 result = libhal_drive_from_udi (hal_ctx, found_udi); 1352 1353 free (found_udi); 1354 out: 1355 return result; 1356 } 1357 1358 1359 /** Get the volume object for a given device file. 1360 * 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 1364 */ 1365 LibHalVolume * 1366 libhal_volume_from_device_file (LibHalContext *hal_ctx, const char *device_file) 1367 { 1368 int i; 1369 char **hal_udis; 1370 int num_hal_udis; 1371 LibHalVolume *result; 1372 char *found_udi; 1373 DBusError error; 1374 1375 LIBHAL_CHECK_LIBHALCONTEXT(hal_ctx, NULL); 1376 1377 result = NULL; 1378 found_udi = NULL; 1379 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) 1383 goto out; 1384 1385 for (i = 0; i < num_hal_udis; i++) { 1386 char *udi; 1387 udi = hal_udis[i]; 1388 if (libhal_device_query_capability (hal_ctx, udi, "volume", &error)) { 1389 found_udi = strdup (udi); 1390 break; 1391 } 1392 } 1393 1394 libhal_free_string_array (hal_udis); 1395 1396 if (found_udi != NULL) 1397 result = libhal_volume_from_udi (hal_ctx, found_udi); 1398 1399 free (found_udi); 1400 out: 1401 LIBHAL_FREE_DBUS_ERROR(&error); 1402 return result; 1403 } 1404 1405 dbus_uint64_t 1406 libhal_volume_get_size (LibHalVolume *volume) 1407 { 1408 if (volume->volume_size > 0) 1409 return volume->volume_size; 1410 else 1411 return ((dbus_uint64_t)volume->block_size) * ((dbus_uint64_t)volume->num_blocks); 1412 } 1413 1414 dbus_uint64_t 1415 libhal_volume_get_disc_capacity (LibHalVolume *volume) 1416 { 1417 return volume->disc_capacity; 1418 } 1419 1420 1421 dbus_bool_t 1422 libhal_drive_is_hotpluggable (LibHalDrive *drive) 1423 { 1424 return drive->is_hotpluggable; 1425 } 1426 1427 dbus_bool_t 1428 libhal_drive_uses_removable_media (LibHalDrive *drive) 1429 { 1430 return drive->is_removable; 1431 } 1432 1433 dbus_bool_t 1434 libhal_drive_is_media_detected (LibHalDrive *drive) 1435 { 1436 return drive->is_media_detected; 1437 } 1438 1439 dbus_uint64_t 1440 libhal_drive_get_size (LibHalDrive *drive) 1441 { 1442 return drive->drive_size; 1443 } 1444 1445 dbus_uint64_t 1446 libhal_drive_get_media_size (LibHalDrive *drive) 1447 { 1448 return drive->drive_media_size; 1449 } 1450 1451 const char * 1452 libhal_drive_get_partition_scheme (LibHalDrive *drive) 1453 { 1454 return drive->partition_scheme; 1455 } 1456 1457 1458 LibHalDriveType 1459 libhal_drive_get_type (LibHalDrive *drive) 1460 { 1461 return drive->type; 1462 } 1463 1464 LibHalDriveBus 1465 libhal_drive_get_bus (LibHalDrive *drive) 1466 { 1467 return drive->bus; 1468 } 1469 1470 LibHalDriveCdromCaps 1471 libhal_drive_get_cdrom_caps (LibHalDrive *drive) 1472 { 1473 return drive->cdrom_caps; 1474 } 1475 1476 unsigned int 1477 libhal_drive_get_device_major (LibHalDrive *drive) 1478 { 1479 return drive->device_major; 1480 } 1481 1482 unsigned int 1483 libhal_drive_get_device_minor (LibHalDrive *drive) 1484 { 1485 return drive->device_minor; 1486 } 1487 1488 const char * 1489 libhal_drive_get_type_textual (LibHalDrive *drive) 1490 { 1491 return drive->type_textual; 1492 } 1493 1494 const char * 1495 libhal_drive_get_device_file (LibHalDrive *drive) 1496 { 1497 return drive->device_file; 1498 } 1499 1500 const char * 1501 libhal_drive_get_udi (LibHalDrive *drive) 1502 { 1503 return drive->udi; 1504 } 1505 1506 const char * 1507 libhal_drive_get_serial (LibHalDrive *drive) 1508 { 1509 return drive->serial; 1510 } 1511 1512 const char * 1513 libhal_drive_get_firmware_version (LibHalDrive *drive) 1514 { 1515 return drive->firmware_version; 1516 } 1517 1518 const char * 1519 libhal_drive_get_model (LibHalDrive *drive) 1520 { 1521 return drive->model; 1522 } 1523 1524 const char * 1525 libhal_drive_get_vendor (LibHalDrive *drive) 1526 { 1527 return drive->vendor; 1528 } 1529 1530 /*****************************************************************************/ 1531 1532 const char * 1533 libhal_volume_get_udi (LibHalVolume *volume) 1534 { 1535 return volume->udi; 1536 } 1537 1538 const char * 1539 libhal_volume_get_device_file (LibHalVolume *volume) 1540 { 1541 return volume->device_file; 1542 } 1543 1544 unsigned int libhal_volume_get_device_major (LibHalVolume *volume) 1545 { 1546 return volume->device_major; 1547 } 1548 1549 unsigned int libhal_volume_get_device_minor (LibHalVolume *volume) 1550 { 1551 return volume->device_minor; 1552 } 1553 1554 const char * 1555 libhal_volume_get_fstype (LibHalVolume *volume) 1556 { 1557 return volume->fstype; 1558 } 1559 1560 const char * 1561 libhal_volume_get_fsversion (LibHalVolume *volume) 1562 { 1563 return volume->fsversion; 1564 } 1565 1566 LibHalVolumeUsage 1567 libhal_volume_get_fsusage (LibHalVolume *volume) 1568 { 1569 return volume->fsusage; 1570 } 1571 1572 dbus_bool_t 1573 libhal_volume_is_mounted (LibHalVolume *volume) 1574 { 1575 return volume->is_mounted; 1576 } 1577 1578 dbus_bool_t 1579 libhal_volume_is_mounted_read_only (LibHalVolume *volume) 1580 { 1581 return volume->is_mounted_read_only; 1582 } 1583 1584 dbus_bool_t 1585 libhal_volume_is_partition (LibHalVolume *volume) 1586 { 1587 return volume->is_partition; 1588 } 1589 1590 dbus_bool_t 1591 libhal_volume_is_disc (LibHalVolume *volume) 1592 { 1593 return volume->is_disc; 1594 } 1595 1596 unsigned int 1597 libhal_volume_get_partition_number (LibHalVolume *volume) 1598 { 1599 return volume->partition_number; 1600 } 1601 1602 const char * 1603 libhal_volume_get_partition_scheme (LibHalVolume *volume) 1604 { 1605 return volume->partition_scheme; 1606 } 1607 1608 const char * 1609 libhal_volume_get_partition_type (LibHalVolume *volume) 1610 { 1611 return volume->partition_type; 1612 } 1613 1614 const char * 1615 libhal_volume_get_partition_label (LibHalVolume *volume) 1616 { 1617 return volume->partition_label; 1618 } 1619 1620 const char * 1621 libhal_volume_get_partition_uuid (LibHalVolume *volume) 1622 { 1623 return volume->partition_uuid; 1624 } 1625 1626 const char ** 1627 libhal_volume_get_partition_flags (LibHalVolume *volume) 1628 { 1629 return (const char **) volume->partition_flags; 1630 } 1631 1632 1633 dbus_uint64_t 1634 libhal_volume_get_partition_start_offset (LibHalVolume *volume) 1635 { 1636 return volume->partition_start_offset; 1637 } 1638 1639 dbus_uint64_t 1640 libhal_volume_get_partition_media_size (LibHalVolume *volume) 1641 { 1642 return volume->partition_media_size; 1643 } 1644 1645 const char * 1646 libhal_volume_get_label (LibHalVolume *volume) 1647 { 1648 return volume->volume_label; 1649 } 1650 1651 const char * 1652 libhal_volume_get_mount_point (LibHalVolume *volume) 1653 { 1654 return volume->mount_point; 1655 } 1656 1657 const char * 1658 libhal_volume_get_uuid (LibHalVolume *volume) 1659 { 1660 return volume->uuid; 1661 } 1662 1663 dbus_bool_t 1664 libhal_volume_disc_has_audio (LibHalVolume *volume) 1665 { 1666 return volume->disc_has_audio; 1667 } 1668 1669 dbus_bool_t 1670 libhal_volume_disc_has_data (LibHalVolume *volume) 1671 { 1672 return volume->disc_has_data; 1673 } 1674 1675 dbus_bool_t 1676 libhal_volume_disc_is_blank (LibHalVolume *volume) 1677 { 1678 return volume->disc_is_blank; 1679 } 1680 1681 dbus_bool_t 1682 libhal_volume_disc_is_rewritable (LibHalVolume *volume) 1683 { 1684 return volume->disc_is_rewritable; 1685 } 1686 1687 dbus_bool_t 1688 libhal_volume_disc_is_appendable (LibHalVolume *volume) 1689 { 1690 return volume->disc_is_appendable; 1691 } 1692 1693 LibHalVolumeDiscType 1694 libhal_volume_get_disc_type (LibHalVolume *volume) 1695 { 1696 return volume->disc_type; 1697 } 1698 1699 dbus_bool_t 1700 libhal_volume_should_ignore (LibHalVolume *volume) 1701 { 1702 return volume->ignore_volume; 1703 } 1704 1705 char ** 1706 libhal_drive_find_all_volumes (LibHalContext *hal_ctx, LibHalDrive *drive, int *num_volumes) 1707 { 1708 int i; 1709 char **udis; 1710 int num_udis; 1711 const char *drive_udi; 1712 char **result; 1713 DBusError error; 1714 1715 LIBHAL_CHECK_LIBHALCONTEXT(hal_ctx, NULL); 1716 1717 udis = NULL; 1718 result = NULL; 1719 *num_volumes = 0; 1720 1721 drive_udi = libhal_drive_get_udi (drive); 1722 if (drive_udi == NULL) 1723 goto out; 1724 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); 1730 goto out; 1731 } 1732 1733 result = malloc (sizeof (char *) * num_udis); 1734 if (result == NULL) 1735 goto out; 1736 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) 1740 continue; 1741 result[*num_volumes] = strdup (udis[i]); 1742 *num_volumes = (*num_volumes) + 1; 1743 } 1744 /* set last element (above removed UDI) to NULL for libhal_free_string_array()*/ 1745 result[*num_volumes] = NULL; 1746 1747 out: 1748 libhal_free_string_array (udis); 1749 return result; 1750 } 1751 1752 const char * 1753 libhal_volume_crypto_get_backing_volume_udi (LibHalVolume *volume) 1754 { 1755 return volume->crypto_backing_volume; 1756 } 1757 1758 char * 1759 libhal_volume_crypto_get_clear_volume_udi (LibHalContext *hal_ctx, LibHalVolume *volume) 1760 { 1761 DBusError error; 1762 char **clear_devices; 1763 int num_clear_devices; 1764 char *result; 1765 1766 result = NULL; 1767 1768 LIBHAL_CHECK_LIBHALCONTEXT (hal_ctx, NULL); 1769 1770 dbus_error_init (&error); 1771 clear_devices = libhal_manager_find_device_string_match (hal_ctx, 1772 "volume.crypto_luks.clear.backing_volume", 1773 volume->udi, 1774 &num_clear_devices, 1775 &error); 1776 if (clear_devices != NULL) { 1777 1778 if (num_clear_devices >= 1) { 1779 result = strdup (clear_devices[0]); 1780 } 1781 libhal_free_string_array (clear_devices); 1782 } 1783 1784 return result; 1785 } 1786 1787 1788 /*************************************************************************/ 1789 1790 char * 1791 libhal_drive_policy_default_get_mount_root (LibHalContext *hal_ctx) 1792 { 1793 char *result; 1794 DBusError error; 1795 1796 LIBHAL_CHECK_LIBHALCONTEXT(hal_ctx, NULL); 1797 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); 1802 1803 return result; 1804 } 1805 1806 dbus_bool_t 1807 libhal_drive_policy_default_use_managed_keyword (LibHalContext *hal_ctx) 1808 { 1809 dbus_bool_t result; 1810 DBusError error; 1811 1812 LIBHAL_CHECK_LIBHALCONTEXT(hal_ctx, FALSE); 1813 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); 1818 1819 return result; 1820 } 1821 1822 char * 1823 libhal_drive_policy_default_get_managed_keyword_primary (LibHalContext *hal_ctx) 1824 { 1825 char *result; 1826 DBusError error; 1827 1828 LIBHAL_CHECK_LIBHALCONTEXT(hal_ctx, NULL); 1829 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); 1834 1835 return result; 1836 } 1837 1838 char * 1839 libhal_drive_policy_default_get_managed_keyword_secondary (LibHalContext *hal_ctx) 1840 { 1841 char *result; 1842 DBusError error; 1843 1844 LIBHAL_CHECK_LIBHALCONTEXT(hal_ctx, NULL); 1845 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); 1850 1851 return result; 1852 } 1853 1854 /*************************************************************************/ 1855 1856 dbus_bool_t 1857 libhal_drive_policy_is_mountable (LibHalDrive *drive, LibHalStoragePolicy *policy) 1858 { 1859 printf ("should_mount=%d, no_partitions_hint=%d\n", drive->should_mount, drive->no_partitions_hint); 1860 1861 return drive->should_mount && drive->no_partitions_hint; 1862 } 1863 1864 const char * 1865 libhal_drive_policy_get_desired_mount_point (LibHalDrive *drive, LibHalStoragePolicy *policy) 1866 { 1867 return drive->desired_mount_point; 1868 } 1869 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); \ 1874 } while(0) 1875 1876 1877 static void 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) 1880 { 1881 LibHalPropertySet *properties; 1882 LibHalPropertySetIterator it; 1883 DBusError error; 1884 1885 if(hal_ctx == 0) { 1886 fprintf (stderr,"%s %d : LibHalContext *ctx is NULL\n",__FILE__, __LINE__); 1887 return; 1888 } 1889 1890 dbus_error_init (&error); 1891 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); 1896 return; 1897 } 1898 1899 for (libhal_psi_init (&it, properties); libhal_psi_has_more (&it); libhal_psi_next (&it)) { 1900 int type; 1901 char *key; 1902 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; 1908 char *location; 1909 dbus_bool_t is_imply_opt; 1910 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; 1917 1918 1919 if (only_collect_imply_opts) { 1920 if (!is_imply_opt) 1921 continue; 1922 } else { 1923 if (is_imply_opt) 1924 continue; 1925 } 1926 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); 1934 } 1935 } else { 1936 /* remove option if already there */ 1937 location = strstr (options_string, option); 1938 if (location != NULL) { 1939 char *end; 1940 1941 end = strchr (location, ','); 1942 if (end == NULL) { 1943 location[0] = '\0'; 1944 } else { 1945 strcpy (location, end + 1); /* skip the extra comma */ 1946 } 1947 } 1948 1949 } 1950 } 1951 } 1952 1953 libhal_free_property_set (properties); 1954 } 1955 1956 1957 const char * 1958 libhal_drive_policy_get_mount_options (LibHalDrive *drive, LibHalStoragePolicy *policy) 1959 { 1960 const char *result; 1961 char stor_mount_option_default_begin[] = "storage.policy.default.mount_option."; 1962 char stor_mount_option_begin[] = "storage.policy.mount_option."; 1963 1964 result = NULL; 1965 drive->mount_options[0] = '\0'; 1966 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); 1977 1978 result = drive->mount_options; 1979 1980 return result; 1981 } 1982 1983 const char * 1984 libhal_drive_policy_get_mount_fs (LibHalDrive *drive, LibHalStoragePolicy *policy) 1985 { 1986 return drive->mount_filesystem; 1987 } 1988 1989 1990 dbus_bool_t 1991 libhal_volume_policy_is_mountable (LibHalDrive *drive, LibHalVolume *volume, LibHalStoragePolicy *policy) 1992 { 1993 return drive->should_mount && volume->should_mount; 1994 } 1995 1996 const char *libhal_volume_policy_get_desired_mount_point (LibHalDrive *drive, LibHalVolume *volume, LibHalStoragePolicy *policy) 1997 { 1998 return volume->desired_mount_point; 1999 } 2000 2001 const char *libhal_volume_policy_get_mount_options (LibHalDrive *drive, LibHalVolume *volume, LibHalStoragePolicy *policy) 2002 { 2003 const char *result; 2004 char stor_mount_option_default_begin[] = "storage.policy.default.mount_option."; 2005 char vol_mount_option_begin[] = "volume.policy.mount_option."; 2006 2007 result = NULL; 2008 volume->mount_options[0] = '\0'; 2009 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); 2020 2021 result = volume->mount_options; 2022 2023 return result; 2024 } 2025 2026 const char *libhal_volume_policy_get_mount_fs (LibHalDrive *drive, LibHalVolume *volume, LibHalStoragePolicy *policy) 2027 { 2028 return volume->mount_filesystem; 2029 } 2030 2031 dbus_bool_t 2032 libhal_drive_no_partitions_hint (LibHalDrive *drive) 2033 { 2034 return drive->no_partitions_hint; 2035 } 2036 2037 /** @} */ 2038