HAL: libhal-storage.c Source File

Main Page | Modules | Data Structures | Directories | File List | Data Fields | Related Pages

# libhal-storage.c

    00001 /***************************************************************************
    00002  * CVSID: $Id: libhal-storage.c,v 1.8.2.5 2005/01/27 16:11:34 david Exp $
    00003  *
    00004  * libhal-storage.c : HAL convenience library for storage devices and volumes
    00005  *
    00006  * Copyright (C) 2004 Red Hat, Inc.
    00007  *
    00008  * Author: David Zeuthen <davidz@redhat.com>
    00009  *
    00010  * Licensed under the Academic Free License version 2.0
    00011  *
    00012  * This program is free software; you can redistribute it and/or modify
    00013  * it under the terms of the GNU General Public License as published by
    00014  * the Free Software Foundation; either version 2 of the License, or
    00015  * (at your option) any later version.
    00016  *
    00017  * This program is distributed in the hope that it will be useful,
    00018  * but WITHOUT ANY WARRANTY; without even the implied warranty of
    00019  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    00020  * GNU General Public License for more details.
    00021  *
    00022  * You should have received a copy of the GNU General Public License
    00023  * along with this program; if not, write to the Free Software
    00024  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    00025  *
    00026  **************************************************************************/
    00027
    00028 #ifdef HAVE_CONFIG_H
    00029 #  include <config.h>
    00030 #endif
    00031
    00032 #include <stdio.h>
    00033 #include <stdlib.h>
    00034 #include <string.h>
    00035 #include <dbus/dbus.h>
    00036
    00037 #include "../libhal/libhal.h"
    00038 #include "libhal-storage.h"
    00039
    00040
    00041 #ifdef ENABLE_NLS
    00042 # include <libintl.h>
    00043 # define _(String) dgettext (GETTEXT_PACKAGE, String)
    00044 # ifdef gettext_noop
    00045 #   define N_(String) gettext_noop (String)
    00046 # else
    00047 #   define N_(String) (String)
    00048 # endif
    00049 #else
    00050 /* Stubs that do something close enough.  */
    00051 # define textdomain(String) (String)
    00052 # define gettext(String) (String)
    00053 # define dgettext(Domain,Message) (Message)
    00054 # define dcgettext(Domain,Message,Type) (Message)
    00055 # define bindtextdomain(Domain,Directory) (Domain)
    00056 # define _(String)
    00057 # define N_(String) (String)
    00058 #endif
    00059
    00067 typedef struct IconMappingEntry_s {
    00068     HalStoragePolicyIcon icon;
    00069     char *path;
    00070     struct IconMappingEntry_s *next;
    00071 } IconMappingEntry;
    00072
    00073 struct HalStoragePolicy_s {
    00074     IconMappingEntry *icon_mappings;
    00075 };
    00076
    00077 HalStoragePolicy *
    00078 hal_storage_policy_new ()
    00079 {
    00080     HalStoragePolicy *p;
    00081
    00082     p = malloc (sizeof (HalStoragePolicy));
    00083     if (p == NULL)
    00084         goto out;
    00085
    00086     p->icon_mappings = NULL;
    00087 out:
    00088     return p;
    00089 }
    00090
    00091 void
    00092 hal_storage_policy_free (HalStoragePolicy *policy)
    00093 {
    00094     IconMappingEntry *i;
    00095     IconMappingEntry *j;
    00096
    00097     /* free all icon mappings */
    00098     for (i = policy->icon_mappings; i != NULL; i = j) {
    00099         j = i->next;
    00100         free (i->path);
    00101         free (i);
    00102     }
    00103
    00104     free (policy);
    00105 }
    00106
    00107 void
    00108 hal_storage_policy_set_icon_path (HalStoragePolicy *policy, HalStoragePolicyIcon icon, const char *path)
    00109 {
    00110     IconMappingEntry *i;
    00111
    00112     /* see if it already exist */
    00113     for (i = policy->icon_mappings; i != NULL; i = i->next) {
    00114         if (i->icon == icon) {
    00115             free (i->path);
    00116             i->path = strdup (path);
    00117             goto out;
    00118         }
    00119     }
    00120
    00121     i = malloc (sizeof (IconMappingEntry));
    00122     if (i == NULL)
    00123         goto out;
    00124     i->icon = icon;
    00125     i->path = strdup (path);
    00126     i->next = policy->icon_mappings;
    00127     policy->icon_mappings = i;
    00128
    00129 out:
    00130     return;
    00131 }
    00132
    00133 void
    00134 hal_storage_policy_set_icon_mapping (HalStoragePolicy *policy, HalStoragePolicyIconPair *pairs)
    00135 {
    00136     HalStoragePolicyIconPair *i;
    00137
    00138     for (i = pairs; i->icon != 0x00; i++) {
    00139         hal_storage_policy_set_icon_path (policy, i->icon, i->icon_path);
    00140     }
    00141 }
    00142
    00143 const char *
    00144 hal_storage_policy_lookup_icon (HalStoragePolicy *policy, HalStoragePolicyIcon icon)
    00145 {
    00146     IconMappingEntry *i;
    00147     const char *path;
    00148
    00149     path = NULL;
    00150     for (i = policy->icon_mappings; i != NULL; i = i->next) {
    00151         if (i->icon == icon) {
    00152             path = i->path;
    00153             goto out;
    00154         }
    00155     }
    00156 out:
    00157     return path;
    00158 }
    00159
    00160
    00161 #define MAX_STRING_SZ 256
    00162
    00163 char *
    00164 hal_volume_policy_compute_size_as_string (HalVolume *volume)
    00165 {
    00166     dbus_uint64_t size;
    00167     char *result;
    00168     char* sizes_str[] = {"K", "M", "G", "T", NULL};
    00169     dbus_uint64_t cur = 1000L;
    00170     dbus_uint64_t base = 10L;
    00171     dbus_uint64_t step = 10L*10L*10L;
    00172     int cur_str = 0;
    00173     char buf[MAX_STRING_SZ];
    00174
    00175     result = NULL;
    00176
    00177     size = hal_volume_get_size (volume);
    00178
    00179     do {
    00180         if (sizes_str[cur_str+1] == NULL || size < cur*step) {
    00181             /* found the unit, display a comma number if result is a single digit */
    00182             if (size < cur*base) {
    00183                 snprintf (buf, MAX_STRING_SZ, "%.01f%s",
    00184                       ((double)size)/((double)cur), sizes_str[cur_str]);
    00185                 result = strdup (buf);
    00186             } else {
    00187                 snprintf (buf, MAX_STRING_SZ, "%lld%s", size / cur, sizes_str[cur_str]);
    00188                 result = strdup (buf);
    00189                 }
    00190             goto out;
    00191         }
    00192
    00193         cur *= step;
    00194         cur_str++;
    00195     } while (1);
    00196
    00197 out:
    00198     return result;
    00199 }
    00200
    00201 static void
    00202 fixup_string (char *s)
    00203 {
    00204     /* TODO: first strip leading and trailing whitespace */
    00205     /*g_strstrip (s);*/
    00206
    00207     /* TODO: could do nice things on all-upper case strings */
    00208 }
    00209
    00210 /* volume may be NULL (e.g. if drive supports removable media) */
    00211 char *
    00212 hal_drive_policy_compute_display_name (HalDrive *drive, HalVolume *volume, HalStoragePolicy *policy)
    00213 {
    00214     char *name;
    00215     char *size_str;
    00216     char *vendormodel_str;
    00217     const char *model;
    00218     const char *vendor;
    00219     HalDriveType drive_type;
    00220     dbus_bool_t drive_is_hotpluggable;
    00221     dbus_bool_t drive_is_removable;
    00222     HalDriveCdromCaps drive_cdrom_caps;
    00223     char buf[MAX_STRING_SZ];
    00224
    00225     model = hal_drive_get_model (drive);
    00226     vendor = hal_drive_get_vendor (drive);
    00227     drive_type = hal_drive_get_type (drive);
    00228     drive_is_hotpluggable = hal_drive_is_hotpluggable (drive);
    00229     drive_is_removable = hal_drive_uses_removable_media (drive);
    00230     drive_cdrom_caps = hal_drive_get_cdrom_caps (drive);
    00231
    00232     if (volume != NULL)
    00233         size_str = hal_volume_policy_compute_size_as_string (volume);
    00234     else
    00235         size_str = NULL;
    00236
    00237     if (vendor == NULL || strlen (vendor) == 0) {
    00238         if (model == NULL || strlen (model) == 0)
    00239             vendormodel_str = strdup ("");
    00240         else
    00241             vendormodel_str = strdup (model);
    00242     } else {
    00243         if (model == NULL || strlen (model) == 0)
    00244             vendormodel_str = strdup (vendor);
    00245         else {
    00246             snprintf (buf, MAX_STRING_SZ, "%s %s", vendor, model);
    00247             vendormodel_str = strdup (buf);
    00248         }
    00249     }
    00250
    00251     fixup_string (vendormodel_str);
    00252
    00253     if (drive_type==HAL_DRIVE_TYPE_CDROM) {
    00254
    00255         /* Optical drive handling */
    00256         char *first;
    00257         char *second;
    00258
    00259
    00260         first = "CD-ROM";
    00261         if (drive_cdrom_caps & HAL_DRIVE_CDROM_CAPS_CDR)
    00262             first = "CD-R";
    00263         if (drive_cdrom_caps & HAL_DRIVE_CDROM_CAPS_CDRW)
    00264             first = "CD-RW";
    00265
    00266         second = "";
    00267         if (drive_cdrom_caps & HAL_DRIVE_CDROM_CAPS_DVDROM)
    00268             second = "/DVD-ROM";
    00269         if (drive_cdrom_caps & HAL_DRIVE_CDROM_CAPS_DVDPLUSR)
    00270             second = "/DVD+R";
    00271         if (drive_cdrom_caps & HAL_DRIVE_CDROM_CAPS_DVDPLUSRW)
    00272             second = "/DVD+RW";
    00273         if (drive_cdrom_caps & HAL_DRIVE_CDROM_CAPS_DVDR)
    00274             second = "/DVD-R";
    00275         if (drive_cdrom_caps & HAL_DRIVE_CDROM_CAPS_DVDRW)
    00276             second = "/DVD-RW";
    00277         if (drive_cdrom_caps & HAL_DRIVE_CDROM_CAPS_DVDRAM)
    00278             second = "/DVD-RAM";
    00279         if ((drive_cdrom_caps & HAL_DRIVE_CDROM_CAPS_DVDR) &&
    00280             (drive_cdrom_caps & HAL_DRIVE_CDROM_CAPS_DVDPLUSR))
    00281             second = "/DVD±R";
    00282         if ((drive_cdrom_caps & HAL_DRIVE_CDROM_CAPS_DVDRW) &&
    00283             (drive_cdrom_caps & HAL_DRIVE_CDROM_CAPS_DVDPLUSRW))
    00284             second = "/DVD±RW";
    00285
    00286
    00287         if (drive_is_hotpluggable) {
    00288             snprintf (buf, MAX_STRING_SZ, _("External %s%s Drive"), first, second);
    00289             name = strdup (buf);
    00290         } else {
    00291             snprintf (buf, MAX_STRING_SZ, _("%s%s Drive"), first, second);
    00292             name = strdup (buf);
    00293         }
    00294
    00295     } else if (drive_type==HAL_DRIVE_TYPE_FLOPPY) {
    00296
    00297         /* Floppy Drive handling */
    00298
    00299         if (drive_is_hotpluggable)
    00300             name = strdup (_("External Floppy Drive"));
    00301         else
    00302             name = strdup (_("Floppy Drive"));
    00303     } else if (drive_type==HAL_DRIVE_TYPE_DISK && !drive_is_removable) {
    00304
    00305         /* Harddisks */
    00306
    00307         if (size_str != NULL) {
    00308             if (drive_is_hotpluggable) {
    00309                 snprintf (buf, MAX_STRING_SZ, _("%s External Hard Drive"), size_str);
    00310                 name = strdup (buf);
    00311             } else {
    00312                 snprintf (buf, MAX_STRING_SZ, _("%s Hard Drive"), size_str);
    00313                 name = strdup (buf);
    00314             }
    00315         } else {
    00316             if (drive_is_hotpluggable)
    00317                 name = strdup (_("External Hard Drive"));
    00318             else
    00319                 name = strdup (_("Hard Drive"));
    00320         }
    00321     } else {
    00322
    00323         /* The rest - includes drives with removable Media */
    00324
    00325         if (strlen (vendormodel_str) > 0)
    00326             name = strdup (vendormodel_str);
    00327         else
    00328             name = strdup (_("Drive"));
    00329     }
    00330
    00331     free (vendormodel_str);
    00332     free (size_str);
    00333
    00334     return name;
    00335 }
    00336
    00337 char *
    00338 hal_volume_policy_compute_display_name (HalDrive *drive, HalVolume *volume, HalStoragePolicy *policy)
    00339 {
    00340     char *name;
    00341     char *size_str;
    00342     const char *volume_label;
    00343     const char *model;
    00344     const char *vendor;
    00345     HalDriveType drive_type;
    00346     dbus_bool_t drive_is_hotpluggable;
    00347     dbus_bool_t drive_is_removable;
    00348     HalDriveCdromCaps drive_cdrom_caps;
    00349     char buf[MAX_STRING_SZ];
    00350
    00351     volume_label = hal_volume_get_label (volume);
    00352     model = hal_drive_get_model (drive);
    00353     vendor = hal_drive_get_vendor (drive);
    00354     drive_type = hal_drive_get_type (drive);
    00355     drive_is_hotpluggable = hal_drive_is_hotpluggable (drive);
    00356     drive_is_removable = hal_drive_uses_removable_media (drive);
    00357     drive_cdrom_caps = hal_drive_get_cdrom_caps (drive);
    00358
    00359     size_str = hal_volume_policy_compute_size_as_string (volume);
    00360
    00361     /* If the volume label is available use that
    00362      *
    00363      * TODO: If label is a fully-qualified UNIX path don't use that
    00364      */
    00365     if (volume_label != NULL) {
    00366         name = strdup (volume_label);
    00367         goto out;
    00368     }
    00369
    00370     /* Handle media in optical drives */
    00371     if (drive_type==HAL_DRIVE_TYPE_CDROM) {
    00372         switch (hal_volume_get_disc_type (volume)) {
    00373
    00374         default:
    00375             /* explict fallthrough */
    00376         case HAL_VOLUME_DISC_TYPE_CDROM:
    00377             name = strdup (_("CD-ROM Disc"));
    00378             break;
    00379
    00380         case HAL_VOLUME_DISC_TYPE_CDR:
    00381             if (hal_volume_disc_is_blank (volume))
    00382                 name = strdup (_("Blank CD-R Disc"));
    00383             else
    00384                 name = strdup (_("CD-R Disc"));
    00385             break;
    00386
    00387         case HAL_VOLUME_DISC_TYPE_CDRW:
    00388             if (hal_volume_disc_is_blank (volume))
    00389                 name = strdup (_("Blank CD-RW Disc"));
    00390             else
    00391                 name = strdup (_("CD-RW Disc"));
    00392             break;
    00393
    00394         case HAL_VOLUME_DISC_TYPE_DVDROM:
    00395             name = strdup (_("DVD-ROM Disc"));
    00396             break;
    00397
    00398         case HAL_VOLUME_DISC_TYPE_DVDRAM:
    00399             if (hal_volume_disc_is_blank (volume))
    00400                 name = strdup (_("Blank DVD-RAM Disc"));
    00401             else
    00402                 name = strdup (_("DVD-RAM Disc"));
    00403             break;
    00404
    00405         case HAL_VOLUME_DISC_TYPE_DVDR:
    00406             if (hal_volume_disc_is_blank (volume))
    00407                 name = strdup (_("Blank DVD-R Disc"));
    00408             else
    00409                 name = strdup (_("DVD-R Disc"));
    00410             break;
    00411
    00412         case HAL_VOLUME_DISC_TYPE_DVDRW:
    00413             if (hal_volume_disc_is_blank (volume))
    00414                 name = strdup (_("Blank DVD-RW Disc"));
    00415             else
    00416                 name = strdup (_("DVD-RW Disc"));
    00417
    00418             break;
    00419
    00420         case HAL_VOLUME_DISC_TYPE_DVDPLUSR:
    00421             if (hal_volume_disc_is_blank (volume))
    00422                 name = strdup (_("Blank DVD+R Disc"));
    00423             else
    00424                 name = strdup (_("DVD+R Disc"));
    00425             break;
    00426
    00427         case HAL_VOLUME_DISC_TYPE_DVDPLUSRW:
    00428             if (hal_volume_disc_is_blank (volume))
    00429                 name = strdup (_("Blank DVD+RW Disc"));
    00430             else
    00431                 name = strdup (_("DVD+RW Disc"));
    00432             break;
    00433         }
    00434
    00435         /* Special case for pure audio disc */
    00436         if (hal_volume_disc_has_audio (volume) && !hal_volume_disc_has_data (volume)) {
    00437             free (name);
    00438             name = strdup (_("Audio Disc"));
    00439         }
    00440
    00441         goto out;
    00442     }
    00443
    00444     /* Fallback: size of media */
    00445     if (drive_is_removable) {
    00446         snprintf (buf, MAX_STRING_SZ, _("%s Removable Media"), size_str);
    00447         name = strdup (buf);
    00448     } else {
    00449         snprintf (buf, MAX_STRING_SZ, _("%s Media"), size_str);
    00450         name = strdup (buf);
    00451     }
    00452
    00453     /* Fallback: Use drive name */
    00454     /*name = hal_drive_policy_compute_display_name (drive, volume);*/
    00455
    00456 out:
    00457     free (size_str);
    00458     return name;
    00459 }
    00460
    00461 char *
    00462 hal_drive_policy_compute_icon_name (HalDrive *drive, HalVolume *volume, HalStoragePolicy *policy)
    00463 {
    00464     const char *name;
    00465     HalDriveBus bus;
    00466     HalDriveType drive_type;
    00467
    00468     bus        = hal_drive_get_bus (drive);
    00469     drive_type = hal_drive_get_type (drive);
    00470
    00471     /* by design, the enums are laid out so we can do easy computations */
    00472
    00473     switch (drive_type) {
    00474     case HAL_DRIVE_TYPE_REMOVABLE_DISK:
    00475     case HAL_DRIVE_TYPE_DISK:
    00476     case HAL_DRIVE_TYPE_CDROM:
    00477     case HAL_DRIVE_TYPE_FLOPPY:
    00478         name = hal_storage_policy_lookup_icon (policy, 0x10000 + drive_type*0x100 + bus);
    00479         break;
    00480
    00481     default:
    00482         name = hal_storage_policy_lookup_icon (policy, 0x10000 + drive_type*0x100);
    00483     }
    00484
    00485     if (name != NULL)
    00486         return strdup (name);
    00487     else
    00488         return NULL;
    00489 }
    00490
    00491 char *
    00492 hal_volume_policy_compute_icon_name (HalDrive *drive, HalVolume *volume, HalStoragePolicy *policy)
    00493 {
    00494     const char *name;
    00495     HalDriveBus bus;
    00496     HalDriveType drive_type;
    00497     HalVolumeDiscType disc_type;
    00498
    00499     /* by design, the enums are laid out so we can do easy computations */
    00500
    00501     if (hal_volume_is_disc (volume)) {
    00502         disc_type = hal_volume_get_disc_type (volume);
    00503         name = hal_storage_policy_lookup_icon (policy, 0x30000 + disc_type);
    00504         goto out;
    00505     }
    00506
    00507     if (drive == NULL) {
    00508         name = hal_storage_policy_lookup_icon (policy, HAL_STORAGE_ICON_VOLUME_REMOVABLE_DISK);
    00509         goto out;
    00510     }
    00511
    00512     bus        = hal_drive_get_bus (drive);
    00513     drive_type = hal_drive_get_type (drive);
    00514
    00515     switch (drive_type) {
    00516     case HAL_DRIVE_TYPE_REMOVABLE_DISK:
    00517     case HAL_DRIVE_TYPE_DISK:
    00518     case HAL_DRIVE_TYPE_CDROM:
    00519     case HAL_DRIVE_TYPE_FLOPPY:
    00520         name = hal_storage_policy_lookup_icon (policy, 0x20000 + drive_type*0x100 + bus);
    00521         break;
    00522
    00523     default:
    00524         name = hal_storage_policy_lookup_icon (policy, 0x20000 + drive_type*0x100);
    00525     }
    00526 out:
    00527     if (name != NULL)
    00528         return strdup (name);
    00529     else
    00530         return NULL;
    00531 }
    00532
    00549 dbus_bool_t
    00550 hal_volume_policy_should_be_visible (HalDrive *drive, HalVolume *volume, HalStoragePolicy *policy,
    00551                      const char *target_mount_point)
    00552 {
    00553     unsigned int i;
    00554     dbus_bool_t is_visible;
    00555     const char *label;
    00556     const char *mount_point;
    00557     const char *fstype;
    00558     const char *fhs23_toplevel_mount_points[] = {
    00559         "/",
    00560         "/bin",
    00561         "/boot",
    00562         "/dev",
    00563         "/etc",
    00564         "/home",
    00565         "/lib",
    00566         "/lib64",
    00567         "/media",
    00568         "/mnt",
    00569         "/opt",
    00570         "/root",
    00571         "/sbin",
    00572         "/srv",
    00573         "/tmp",
    00574         "/usr",
    00575         "/var",
    00576         "/proc",
    00577         "/sbin",
    00578         NULL
    00579     };
    00580
    00581     is_visible = FALSE;
    00582
    00583     /* skip if hal says it's not used as a filesystem */
    00584     if (hal_volume_get_fsusage (volume) != HAL_VOLUME_USAGE_MOUNTABLE_FILESYSTEM)
    00585         goto out;
    00586
    00587     label = hal_volume_get_label (volume);
    00588     mount_point = hal_volume_get_mount_point (volume);
    00589     fstype = hal_volume_get_fstype (volume);
    00590
    00591     /* use target mount point if we're not mounted yet */
    00592     if (mount_point == NULL)
    00593         mount_point = target_mount_point;
    00594
    00595     /* bail out if we don't know the filesystem */
    00596     if (fstype == NULL)
    00597         goto out;
    00598
    00599     /* blacklist fhs2.3 top level mount points */
    00600     if (mount_point != NULL) {
    00601         for (i = 0; fhs23_toplevel_mount_points[i] != NULL; i++) {
    00602             if (strcmp (mount_point, fhs23_toplevel_mount_points[i]) == 0)
    00603                 goto out;
    00604         }
    00605     }
    00606
    00607     /* blacklist partitions with name 'bootstrap' of type HFS (Apple uses that) */
    00608     if (label != NULL && strcmp (label, "bootstrap") == 0 && strcmp (fstype, "hfs") == 0)
    00609         goto out;
    00610
    00611     /* only the real lucky mount points will make it this far :-) */
    00612     is_visible = TRUE;
    00613
    00614 out:
    00615     return is_visible;
    00616 }
    00617
    00618 /*************************************************************************/
    00619
    00620 #define MOUNT_OPTIONS_SIZE 256
    00621
    00622 struct HalDrive_s {
    00623     char *udi;
    00624
    00625     int device_major;
    00626     int device_minor;
    00627     char *device_file;
    00628
    00629     HalDriveBus bus;
    00630     char *vendor;             /* may be "", is never NULL */
    00631     char *model;              /* may be "", is never NULL */
    00632     dbus_bool_t is_hotpluggable;
    00633     dbus_bool_t is_removable;
    00634     dbus_bool_t requires_eject;
    00635
    00636     HalDriveType type;
    00637     char *type_textual;
    00638
    00639     char *physical_device;  /* UDI of physical device, e.g. the
    00640                  * IDE, USB, IEEE1394 device */
    00641
    00642     char *dedicated_icon_drive;
    00643     char *dedicated_icon_volume;
    00644
    00645     char *serial;
    00646     char *firmware_version;
    00647     HalDriveCdromCaps cdrom_caps;
    00648
    00649     char *desired_mount_point;
    00650     char *mount_filesystem;
    00651     dbus_bool_t should_mount;
    00652
    00653     dbus_bool_t no_partitions_hint;
    00654
    00655     LibHalContext *hal_ctx;
    00656
    00657     char mount_options[MOUNT_OPTIONS_SIZE];
    00658 };
    00659
    00660 struct HalVolume_s {
    00661     char *udi;
    00662
    00663     int device_major;
    00664     int device_minor;
    00665     char *device_file;
    00666     char *volume_label; /* may be NULL, is never "" */
    00667     dbus_bool_t is_mounted;
    00668     char *mount_point;  /* NULL iff !is_mounted */
    00669     char *fstype;       /* NULL iff !is_mounted or unknown */
    00670     char *fsversion;
    00671     char *uuid;
    00672     char *storage_device;
    00673
    00674     HalVolumeUsage fsusage;
    00675
    00676     dbus_bool_t is_partition;
    00677     unsigned int partition_number;
    00678
    00679     int msdos_part_table_type;
    00680
    00681
    00682     dbus_bool_t is_disc;
    00683     HalVolumeDiscType disc_type;
    00684     dbus_bool_t disc_has_audio;
    00685     dbus_bool_t disc_has_data;
    00686     dbus_bool_t disc_is_appendable;
    00687     dbus_bool_t disc_is_blank;
    00688     dbus_bool_t disc_is_rewritable;
    00689
    00690     unsigned int block_size;
    00691     unsigned int num_blocks;
    00692
    00693     char *desired_mount_point;
    00694     char *mount_filesystem;
    00695     dbus_bool_t should_mount;
    00696
    00697     char mount_options[MOUNT_OPTIONS_SIZE];
    00698 };
    00699
    00700 const char *
    00701 hal_drive_get_dedicated_icon_drive (HalDrive *drive)
    00702 {
    00703     return drive->dedicated_icon_drive;
    00704 }
    00705
    00706 const char *
    00707 hal_drive_get_dedicated_icon_volume (HalDrive *drive)
    00708 {
    00709     return drive->dedicated_icon_volume;
    00710 }
    00711
    00716 void
    00717 hal_drive_free (HalDrive *drive)
    00718 {
    00719     if (drive == NULL )
    00720         return;
    00721
    00722     free (drive->udi);
    00723     hal_free_string (drive->device_file);
    00724     hal_free_string (drive->vendor);
    00725     hal_free_string (drive->model);
    00726     hal_free_string (drive->type_textual);
    00727     hal_free_string (drive->physical_device);
    00728     hal_free_string (drive->serial);
    00729     hal_free_string (drive->firmware_version);
    00730     hal_free_string (drive->desired_mount_point);
    00731     hal_free_string (drive->mount_filesystem);
    00732 }
    00733
    00734
    00739 void
    00740 hal_volume_free (HalVolume *vol)
    00741 {
    00742     if (vol == NULL )
    00743         return;
    00744
    00745     free (vol->udi);
    00746     hal_free_string (vol->device_file);
    00747     hal_free_string (vol->volume_label);
    00748     hal_free_string (vol->fstype);
    00749     hal_free_string (vol->mount_point);
    00750     hal_free_string (vol->fsversion);
    00751     hal_free_string (vol->uuid);
    00752     hal_free_string (vol->desired_mount_point);
    00753     hal_free_string (vol->mount_filesystem);
    00754 }
    00755
    00756
    00757 /* ok, hey, so this is a bit ugly */
    00758
    00759 #define HAL_PROP_EXTRACT_BEGIN if (FALSE)
    00760 #define HAL_PROP_EXTRACT_END ;
    00761 #define HAL_PROP_EXTRACT_INT(_property_, _where_) else if (strcmp (key, _property_) == 0 && type == DBUS_TYPE_INT32) _where_ = hal_psi_get_int (&it)
    00762 #define HAL_PROP_EXTRACT_STRING(_property_, _where_) else if (strcmp (key, _property_) == 0 && type == DBUS_TYPE_STRING) _where_ = (hal_psi_get_string (&it) != NULL && strlen (hal_psi_get_string (&it)) > 0) ? strdup (hal_psi_get_string (&it)) : NULL
    00763 #define HAL_PROP_EXTRACT_BOOL(_property_, _where_) else if (strcmp (key, _property_) == 0 && type == DBUS_TYPE_BOOLEAN) _where_ = hal_psi_get_bool (&it)
    00764 #define HAL_PROP_EXTRACT_BOOL_BITFIELD(_property_, _where_, _field_) else if (strcmp (key, _property_) == 0 && type == DBUS_TYPE_BOOLEAN) _where_ |= hal_psi_get_bool (&it) ? _field_ : 0
    00765
    00774 HalDrive *
    00775 hal_drive_from_udi (LibHalContext *hal_ctx, const char *udi)
    00776 {
    00777     char *bus_textual;
    00778     HalDrive *drive;
    00779     LibHalPropertySet *properties;
    00780     LibHalPropertySetIterator it;
    00781
    00782     drive = NULL;
    00783     properties = NULL;
    00784     bus_textual = NULL;
    00785
    00786     if (!hal_device_query_capability (hal_ctx, udi, "storage"))
    00787         goto error;
    00788
    00789     drive = malloc (sizeof (HalDrive));
    00790     if (drive == NULL)
    00791         goto error;
    00792     memset (drive, 0x00, sizeof (HalDrive));
    00793
    00794     drive->hal_ctx = hal_ctx;
    00795
    00796     drive->udi = strdup (udi);
    00797     if (drive->udi == NULL)
    00798         goto error;
    00799
    00800     properties = hal_device_get_all_properties (hal_ctx, udi);
    00801     if (properties == NULL)
    00802         goto error;
    00803
    00804     /* we can count on hal to give us all these properties */
    00805     for (hal_psi_init (&it, properties); hal_psi_has_more (&it); hal_psi_next (&it)) {
    00806         int type;
    00807         char *key;
    00808
    00809         type = hal_psi_get_type (&it);
    00810         key = hal_psi_get_key (&it);
    00811
    00812         HAL_PROP_EXTRACT_BEGIN;
    00813
    00814         HAL_PROP_EXTRACT_INT    ("block.minor",               drive->device_minor);
    00815         HAL_PROP_EXTRACT_INT    ("block.major",               drive->device_major);
    00816         HAL_PROP_EXTRACT_STRING ("block.device",              drive->device_file);
    00817         HAL_PROP_EXTRACT_STRING ("storage.bus",               bus_textual);
    00818         HAL_PROP_EXTRACT_STRING ("storage.vendor",            drive->vendor);
    00819         HAL_PROP_EXTRACT_STRING ("storage.model",             drive->model);
    00820         HAL_PROP_EXTRACT_STRING ("storage.drive_type",        drive->type_textual);
    00821
    00822
    00823         HAL_PROP_EXTRACT_STRING ("storage.icon.drive",        drive->dedicated_icon_drive);
    00824         HAL_PROP_EXTRACT_STRING ("storage.icon.volume",       drive->dedicated_icon_volume);
    00825
    00826         HAL_PROP_EXTRACT_BOOL   ("storage.hotpluggable",      drive->is_hotpluggable);
    00827         HAL_PROP_EXTRACT_BOOL   ("storage.removable",         drive->is_removable);
    00828         HAL_PROP_EXTRACT_BOOL   ("storage.requires_eject",    drive->requires_eject);
    00829
    00830         HAL_PROP_EXTRACT_STRING ("storage.physical_device",   drive->physical_device);
    00831         HAL_PROP_EXTRACT_STRING ("storage.firmware_version",  drive->firmware_version);
    00832         HAL_PROP_EXTRACT_STRING ("storage.serial",            drive->serial);
    00833
    00834         HAL_PROP_EXTRACT_BOOL_BITFIELD ("storage.cdrom.cdr", drive->cdrom_caps, HAL_DRIVE_CDROM_CAPS_CDR);
    00835         HAL_PROP_EXTRACT_BOOL_BITFIELD ("storage.cdrom.cdrw", drive->cdrom_caps, HAL_DRIVE_CDROM_CAPS_CDRW);
    00836         HAL_PROP_EXTRACT_BOOL_BITFIELD ("storage.cdrom.dvd", drive->cdrom_caps, HAL_DRIVE_CDROM_CAPS_DVDROM);
    00837         HAL_PROP_EXTRACT_BOOL_BITFIELD ("storage.cdrom.dvdplusr", drive->cdrom_caps, HAL_DRIVE_CDROM_CAPS_DVDPLUSR);
    00838         HAL_PROP_EXTRACT_BOOL_BITFIELD ("storage.cdrom.dvdplusrw", drive->cdrom_caps, HAL_DRIVE_CDROM_CAPS_DVDPLUSRW);
    00839         HAL_PROP_EXTRACT_BOOL_BITFIELD ("storage.cdrom.dvdr", drive->cdrom_caps, HAL_DRIVE_CDROM_CAPS_DVDR);
    00840         HAL_PROP_EXTRACT_BOOL_BITFIELD ("storage.cdrom.dvdrw", drive->cdrom_caps, HAL_DRIVE_CDROM_CAPS_DVDRW);
    00841         HAL_PROP_EXTRACT_BOOL_BITFIELD ("storage.cdrom.dvdram", drive->cdrom_caps, HAL_DRIVE_CDROM_CAPS_DVDRAM);
    00842
    00843         HAL_PROP_EXTRACT_BOOL   ("storage.policy.should_mount",        drive->should_mount);
    00844         HAL_PROP_EXTRACT_STRING ("storage.policy.desired_mount_point", drive->desired_mount_point);
    00845         HAL_PROP_EXTRACT_STRING ("storage.policy.mount_filesystem",    drive->mount_filesystem);
    00846
    00847         HAL_PROP_EXTRACT_BOOL   ("storage.no_partitions_hint",        drive->no_partitions_hint);
    00848
    00849         HAL_PROP_EXTRACT_END;
    00850     }
    00851
    00852     if (drive->type_textual != NULL) {
    00853         if (strcmp (drive->type_textual, "cdrom") == 0) {
    00854             drive->cdrom_caps |= HAL_DRIVE_CDROM_CAPS_CDROM;
    00855             drive->type = HAL_DRIVE_TYPE_CDROM;
    00856         } else if (strcmp (drive->type_textual, "floppy") == 0) {
    00857             drive->type = HAL_DRIVE_TYPE_FLOPPY;
    00858         } else if (strcmp (drive->type_textual, "disk") == 0) {
    00859             if (drive->is_removable)
    00860                 drive->type = HAL_DRIVE_TYPE_REMOVABLE_DISK;
    00861             else
    00862                 drive->type = HAL_DRIVE_TYPE_DISK;
    00863         } else if (strcmp (drive->type_textual, "tape") == 0) {
    00864             drive->type = HAL_DRIVE_TYPE_TAPE;
    00865         } else if (strcmp (drive->type_textual, "compact_flash") == 0) {
    00866             drive->type = HAL_DRIVE_TYPE_COMPACT_FLASH;
    00867         } else if (strcmp (drive->type_textual, "memory_stick") == 0) {
    00868             drive->type = HAL_DRIVE_TYPE_MEMORY_STICK;
    00869         } else if (strcmp (drive->type_textual, "smart_media") == 0) {
    00870             drive->type = HAL_DRIVE_TYPE_SMART_MEDIA;
    00871         } else if (strcmp (drive->type_textual, "sd_mmc") == 0) {
    00872             drive->type = HAL_DRIVE_TYPE_SD_MMC;
    00873 /*
    00874         } else if (strcmp (drive->type_textual, "zip") == 0) {
    00875             drive->type = HAL_DRIVE_TYPE_ZIP;
    00876         } else if (strcmp (drive->type_textual, "jaz") == 0) {
    00877             drive->type = HAL_DRIVE_TYPE_JAZ;
    00878 */
    00879         } else {
    00880                 drive->type = HAL_DRIVE_TYPE_DISK;
    00881         }
    00882
    00883     }
    00884
    00885     /* check if physical device is a camera or mp3 player */
    00886     if (drive->physical_device != NULL) {
    00887         char *category;
    00888
    00889         category = hal_device_get_property_string (hal_ctx, drive->physical_device, "info.category");
    00890         if (category != NULL) {
    00891             if (strcmp (category, "portable_audio_player") == 0) {
    00892                 drive->type = HAL_DRIVE_TYPE_PORTABLE_AUDIO_PLAYER;
    00893             } else if (strcmp (category, "camera") == 0) {
    00894                 drive->type = HAL_DRIVE_TYPE_CAMERA;
    00895             }
    00896
    00897             hal_free_string (category);
    00898         }
    00899     }
    00900
    00901     if (bus_textual != NULL) {
    00902         if (strcmp (bus_textual, "usb") == 0) {
    00903             drive->bus = HAL_DRIVE_BUS_USB;
    00904         } else if (strcmp (bus_textual, "ieee1394") == 0) {
    00905             drive->bus = HAL_DRIVE_BUS_IEEE1394;
    00906         } else if (strcmp (bus_textual, "ide") == 0) {
    00907             drive->bus = HAL_DRIVE_BUS_IDE;
    00908         } else if (strcmp (bus_textual, "scsi") == 0) {
    00909             drive->bus = HAL_DRIVE_BUS_SCSI;
    00910         }
    00911     }
    00912
    00913     hal_free_string (bus_textual);
    00914     hal_free_property_set (properties);
    00915
    00916     return drive;
    00917
    00918 error:
    00919     hal_free_string (bus_textual);
    00920     hal_free_property_set (properties);
    00921     hal_drive_free (drive);
    00922     return NULL;
    00923 }
    00924
    00925 const char *
    00926 hal_volume_get_storage_device_udi (HalVolume *volume)
    00927 {
    00928     return volume->storage_device;
    00929 }
    00930
    00931 const char *hal_drive_get_physical_device_udi (HalDrive *drive)
    00932 {
    00933     return drive->physical_device;
    00934 }
    00935
    00936 dbus_bool_t
    00937 hal_drive_requires_eject (HalDrive *drive)
    00938 {
    00939     return drive->requires_eject;
    00940 }
    00941
    00950 HalVolume *
    00951 hal_volume_from_udi (LibHalContext *hal_ctx, const char *udi)
    00952 {
    00953     char *disc_type_textual;
    00954     HalVolume *vol;
    00955     LibHalPropertySet *properties;
    00956     LibHalPropertySetIterator it;
    00957
    00958     vol = NULL;
    00959     properties = NULL;
    00960     disc_type_textual = NULL;
    00961
    00962     if (!hal_device_query_capability (hal_ctx, udi, "volume"))
    00963         goto error;
    00964
    00965     vol = malloc (sizeof (HalVolume));
    00966     if (vol == NULL)
    00967         goto error;
    00968     memset (vol, 0x00, sizeof (HalVolume));
    00969
    00970     vol->udi = strdup (udi);
    00971
    00972     properties = hal_device_get_all_properties (hal_ctx, udi);
    00973     if (properties == NULL)
    00974         goto error;
    00975
    00976     /* we can count on hal to give us all these properties */
    00977     for (hal_psi_init (&it, properties); hal_psi_has_more (&it); hal_psi_next (&it)) {
    00978         int type;
    00979         char *key;
    00980
    00981         type = hal_psi_get_type (&it);
    00982         key = hal_psi_get_key (&it);
    00983
    00984         HAL_PROP_EXTRACT_BEGIN;
    00985
    00986         HAL_PROP_EXTRACT_INT    ("volume.partition.msdos_part_table_type", vol->msdos_part_table_type);
    00987
    00988         HAL_PROP_EXTRACT_INT    ("block.minor",               vol->device_minor);
    00989         HAL_PROP_EXTRACT_INT    ("block.major",               vol->device_major);
    00990         HAL_PROP_EXTRACT_STRING ("block.device",              vol->device_file);
    00991
    00992         HAL_PROP_EXTRACT_STRING ("block.storage_device",      vol->storage_device);
    00993
    00994         HAL_PROP_EXTRACT_INT    ("volume.block_size",         vol->block_size);
    00995         HAL_PROP_EXTRACT_INT    ("volume.num_blocks",         vol->num_blocks);
    00996         HAL_PROP_EXTRACT_STRING ("volume.label",              vol->volume_label);
    00997         HAL_PROP_EXTRACT_STRING ("volume.mount_point",        vol->mount_point);
    00998         HAL_PROP_EXTRACT_STRING ("volume.fstype",             vol->fstype);
    00999         HAL_PROP_EXTRACT_BOOL   ("volume.is_mounted",         vol->is_mounted);
    01000
    01001         HAL_PROP_EXTRACT_BOOL   ("volume.is_disc",            vol->is_disc);
    01002         HAL_PROP_EXTRACT_STRING ("volume.disc.type",          disc_type_textual);
    01003         HAL_PROP_EXTRACT_BOOL   ("volume.disc.has_audio",     vol->disc_has_audio);
    01004         HAL_PROP_EXTRACT_BOOL   ("volume.disc.has_data",      vol->disc_has_data);
    01005         HAL_PROP_EXTRACT_BOOL   ("volume.disc.is_appendable", vol->disc_is_appendable);
    01006         HAL_PROP_EXTRACT_BOOL   ("volume.disc.is_blank",      vol->disc_is_blank);
    01007         HAL_PROP_EXTRACT_BOOL   ("volume.disc.is_rewritable", vol->disc_is_rewritable);
    01008
    01009         HAL_PROP_EXTRACT_BOOL   ("volume.policy.should_mount",        vol->should_mount);
    01010         HAL_PROP_EXTRACT_STRING ("volume.policy.desired_mount_point", vol->desired_mount_point);
    01011         HAL_PROP_EXTRACT_STRING ("volume.policy.mount_filesystem",    vol->mount_filesystem);
    01012
    01013         HAL_PROP_EXTRACT_END;
    01014     }
    01015
    01016     if (disc_type_textual != NULL) {
    01017         if (strcmp (disc_type_textual, "cd_rom") == 0) {
    01018             vol->disc_type = HAL_VOLUME_DISC_TYPE_CDROM;
    01019         } else if (strcmp (disc_type_textual, "cd_r") == 0) {
    01020             vol->disc_type = HAL_VOLUME_DISC_TYPE_CDR;
    01021         } else if (strcmp (disc_type_textual, "cd_rw") == 0) {
    01022             vol->disc_type = HAL_VOLUME_DISC_TYPE_CDRW;
    01023         } else if (strcmp (disc_type_textual, "dvd_rom") == 0) {
    01024             vol->disc_type = HAL_VOLUME_DISC_TYPE_DVDROM;
    01025         } else if (strcmp (disc_type_textual, "dvd_ram") == 0) {
    01026             vol->disc_type = HAL_VOLUME_DISC_TYPE_DVDRAM;
    01027         } else if (strcmp (disc_type_textual, "dvd_r") == 0) {
    01028             vol->disc_type = HAL_VOLUME_DISC_TYPE_DVDR;
    01029         } else if (strcmp (disc_type_textual, "dvd_rw") == 0) {
    01030             vol->disc_type = HAL_VOLUME_DISC_TYPE_DVDRW;
    01031         } else if (strcmp (disc_type_textual, "dvd_plusr") == 0) {
    01032             vol->disc_type = HAL_VOLUME_DISC_TYPE_DVDPLUSR;
    01033         } else if (strcmp (disc_type_textual, "dvd_plusrw") == 0) {
    01034             vol->disc_type = HAL_VOLUME_DISC_TYPE_DVDPLUSRW;
    01035         }
    01036     }
    01037
    01038     hal_free_string (disc_type_textual);
    01039     hal_free_property_set (properties);
    01040     return vol;
    01041 error:
    01042     hal_free_string (disc_type_textual);
    01043     hal_free_property_set (properties);
    01044     hal_volume_free (vol);
    01045     return NULL;
    01046 }
    01047
    01048
    01057 int
    01058 hal_volume_get_msdos_part_table_type (HalVolume *volume)
    01059 {
    01060     return volume->msdos_part_table_type;
    01061 }
    01062
    01063 /***********************************************************************/
    01064
    01072 HalDrive *
    01073 hal_drive_from_device_file (LibHalContext *hal_ctx, const char *device_file)
    01074 {
    01075     int i;
    01076     char **hal_udis;
    01077     int num_hal_udis;
    01078     HalDrive *result;
    01079     char *found_udi;
    01080
    01081     result = NULL;
    01082     found_udi = NULL;
    01083
    01084     if ((hal_udis = hal_manager_find_device_string_match (hal_ctx, "block.device",
    01085                                   device_file, &num_hal_udis)) == NULL)
    01086         goto out;
    01087
    01088     for (i = 0; i < num_hal_udis; i++) {
    01089         char *udi;
    01090         char *storage_udi;
    01091         udi = hal_udis[i];
    01092         if (hal_device_query_capability (hal_ctx, udi, "volume")) {
    01093
    01094             storage_udi = hal_device_get_property_string (hal_ctx, udi, "block.storage_device");
    01095             if (storage_udi == NULL)
    01096                 continue;
    01097             found_udi = strdup (storage_udi);
    01098             hal_free_string (storage_udi);
    01099             break;
    01100         } else if (hal_device_query_capability (hal_ctx, udi, "storage")) {
    01101             found_udi = strdup (udi);
    01102         }
    01103     }
    01104
    01105     hal_free_string_array (hal_udis);
    01106
    01107     if (found_udi != NULL)
    01108         result = hal_drive_from_udi (hal_ctx, found_udi);
    01109
    01110     free (found_udi);
    01111 out:
    01112     return result;
    01113 }
    01114
    01115
    01122 HalVolume *
    01123 hal_volume_from_device_file (LibHalContext *hal_ctx, const char *device_file)
    01124 {
    01125     int i;
    01126     char **hal_udis;
    01127     int num_hal_udis;
    01128     HalVolume *result;
    01129     char *found_udi;
    01130
    01131     result = NULL;
    01132     found_udi = NULL;
    01133
    01134     if ((hal_udis = hal_manager_find_device_string_match (hal_ctx, "block.device",
    01135                                   device_file, &num_hal_udis)) == NULL)
    01136         goto out;
    01137
    01138     for (i = 0; i < num_hal_udis; i++) {
    01139         char *udi;
    01140         udi = hal_udis[i];
    01141         if (hal_device_query_capability (hal_ctx, udi, "volume")) {
    01142             found_udi = strdup (udi);
    01143             break;
    01144         }
    01145     }
    01146
    01147     hal_free_string_array (hal_udis);
    01148
    01149     if (found_udi != NULL)
    01150         result = hal_volume_from_udi (hal_ctx, found_udi);
    01151
    01152     free (found_udi);
    01153 out:
    01154     return result;
    01155 }
    01156
    01157 dbus_uint64_t
    01158 hal_volume_get_size (HalVolume *volume)
    01159 {
    01160     return ((dbus_uint64_t)volume->block_size) * ((dbus_uint64_t)volume->num_blocks);
    01161 }
    01162
    01163
    01164 dbus_bool_t
    01165 hal_drive_is_hotpluggable (HalDrive *drive)
    01166 {
    01167     return drive->is_hotpluggable;
    01168 }
    01169
    01170 dbus_bool_t
    01171 hal_drive_uses_removable_media (HalDrive *drive)
    01172 {
    01173     return drive->is_removable;
    01174 }
    01175
    01176 HalDriveType
    01177 hal_drive_get_type (HalDrive *drive)
    01178 {
    01179     return drive->type;
    01180 }
    01181
    01182 HalDriveBus
    01183 hal_drive_get_bus (HalDrive *drive)
    01184 {
    01185     return drive->bus;
    01186 }
    01187
    01188 HalDriveCdromCaps
    01189 hal_drive_get_cdrom_caps (HalDrive *drive)
    01190 {
    01191     return drive->cdrom_caps;
    01192 }
    01193
    01194 unsigned int
    01195 hal_drive_get_device_major (HalDrive *drive)
    01196 {
    01197     return drive->device_major;
    01198 }
    01199
    01200 unsigned int
    01201 hal_drive_get_device_minor (HalDrive *drive)
    01202 {
    01203     return drive->device_minor;
    01204 }
    01205
    01206 const char *
    01207 hal_drive_get_type_textual (HalDrive *drive)
    01208 {
    01209     return drive->type_textual;
    01210 }
    01211
    01212 const char *
    01213 hal_drive_get_device_file (HalDrive *drive)
    01214 {
    01215     return drive->device_file;
    01216 }
    01217
    01218 const char *
    01219 hal_drive_get_udi (HalDrive *drive)
    01220 {
    01221     return drive->udi;
    01222 }
    01223
    01224 const char *
    01225 hal_drive_get_serial (HalDrive *drive)
    01226 {
    01227     return drive->serial;
    01228 }
    01229
    01230 const char *
    01231 hal_drive_get_firmware_version (HalDrive *drive)
    01232 {
    01233     return drive->firmware_version;
    01234 }
    01235
    01236 const char *
    01237 hal_drive_get_model (HalDrive *drive)
    01238 {
    01239     return drive->model;
    01240 }
    01241
    01242 const char *
    01243 hal_drive_get_vendor (HalDrive *drive)
    01244 {
    01245     return drive->vendor;
    01246 }
    01247
    01248 /*****************************************************************************/
    01249
    01250 const char *
    01251 hal_volume_get_udi (HalVolume *volume)
    01252 {
    01253     return volume->udi;
    01254 }
    01255
    01256 const char *
    01257 hal_volume_get_device_file (HalVolume *volume)
    01258 {
    01259     return volume->device_file;
    01260 }
    01261
    01262 unsigned int hal_volume_get_device_major (HalVolume *volume)
    01263 {
    01264     return volume->device_major;
    01265 }
    01266
    01267 unsigned int hal_volume_get_device_minor (HalVolume *volume)
    01268 {
    01269     return volume->device_minor;
    01270 }
    01271
    01272 const char *
    01273 hal_volume_get_fstype (HalVolume *volume)
    01274 {
    01275     return volume->fstype;
    01276 }
    01277
    01278 const char *
    01279 hal_volume_get_fsversion (HalVolume *volume)
    01280 {
    01281     return volume->fsversion;
    01282 }
    01283
    01284 HalVolumeUsage
    01285 hal_volume_get_fsusage (HalVolume *volume)
    01286 {
    01287     return volume->fsusage;
    01288 }
    01289
    01290 dbus_bool_t
    01291 hal_volume_is_mounted (HalVolume *volume)
    01292 {
    01293     return volume->is_mounted;
    01294 }
    01295
    01296 dbus_bool_t
    01297 hal_volume_is_partition (HalVolume *volume)
    01298 {
    01299     return volume->is_partition;
    01300 }
    01301
    01302 dbus_bool_t
    01303 hal_volume_is_disc (HalVolume *volume)
    01304 {
    01305     return volume->is_disc;
    01306 }
    01307
    01308 unsigned int
    01309 hal_volume_get_partition_number (HalVolume *volume)
    01310 {
    01311     return volume->partition_number;
    01312 }
    01313
    01314 const char *
    01315 hal_volume_get_label (HalVolume *volume)
    01316 {
    01317     return volume->volume_label;
    01318 }
    01319
    01320 const char *
    01321 hal_volume_get_mount_point (HalVolume *volume)
    01322 {
    01323     return volume->mount_point;
    01324 }
    01325
    01326 const char *
    01327 hal_volume_get_uuid (HalVolume *volume)
    01328 {
    01329     return volume->uuid;
    01330 }
    01331
    01332 dbus_bool_t
    01333 hal_volume_disc_has_audio (HalVolume *volume)
    01334 {
    01335     return volume->disc_has_audio;
    01336 }
    01337
    01338 dbus_bool_t
    01339 hal_volume_disc_has_data (HalVolume *volume)
    01340 {
    01341     return volume->disc_has_data;
    01342 }
    01343
    01344 dbus_bool_t
    01345 hal_volume_disc_is_blank (HalVolume *volume)
    01346 {
    01347     return volume->disc_is_blank;
    01348 }
    01349
    01350 dbus_bool_t
    01351 hal_volume_disc_is_rewritable (HalVolume *volume)
    01352 {
    01353     return volume->disc_is_rewritable;
    01354 }
    01355
    01356 dbus_bool_t
    01357 hal_volume_disc_is_appendable (HalVolume *volume)
    01358 {
    01359     return volume->disc_is_appendable;
    01360 }
    01361
    01362 HalVolumeDiscType
    01363 hal_volume_get_disc_type (HalVolume *volume)
    01364 {
    01365     return volume->disc_type;
    01366 }
    01367
    01368 char **
    01369 hal_drive_find_all_volumes (LibHalContext *hal_ctx, HalDrive *drive, int *num_volumes)
    01370 {
    01371     int i;
    01372     char **udis;
    01373     int num_udis;
    01374     const char *drive_udi;
    01375     char **result;
    01376
    01377     udis = NULL;
    01378     result = NULL;
    01379     *num_volumes = 0;
    01380
    01381     drive_udi = hal_drive_get_udi (drive);
    01382     if (drive_udi == NULL)
    01383         goto out;
    01384
    01385     /* get initial list... */
    01386     if ((udis = hal_manager_find_device_string_match (hal_ctx, "block.storage_device",
    01387                               drive_udi, &num_udis)) == NULL)
    01388         goto out;
    01389
    01390     result = malloc (sizeof (char *) * num_udis);
    01391     if (result == NULL)
    01392         goto out;
    01393
    01394     /* ...and filter out the single UDI that is the drive itself */
    01395     for (i = 0; i < num_udis; i++) {
    01396         if (strcmp (udis[i], drive_udi) == 0)
    01397             continue;
    01398         result[*num_volumes] = strdup (udis[i]);
    01399         *num_volumes = (*num_volumes) + 1;
    01400     }
    01401
    01402 out:
    01403     hal_free_string_array (udis);
    01404     return result;
    01405 }
    01406
    01407 /*************************************************************************/
    01408
    01409 char *
    01410 hal_drive_policy_default_get_mount_root (LibHalContext *hal_ctx)
    01411 {
    01412     return hal_device_get_property_string (hal_ctx, "/org/freedesktop/Hal/devices/computer",
    01413                            "storage.policy.default.mount_root");
    01414 }
    01415
    01416 dbus_bool_t
    01417 hal_drive_policy_default_use_managed_keyword (LibHalContext *hal_ctx)
    01418 {
    01419     return hal_device_get_property_bool (hal_ctx, "/org/freedesktop/Hal/devices/computer",
    01420                          "storage.policy.default.use_managed_keyword");
    01421 }
    01422
    01423 char *
    01424 hal_drive_policy_default_get_managed_keyword_primary (LibHalContext *hal_ctx)
    01425 {
    01426     return hal_device_get_property_string (hal_ctx, "/org/freedesktop/Hal/devices/computer",
    01427                            "storage.policy.default.managed_keyword.primary");
    01428 }
    01429
    01430 char *
    01431 hal_drive_policy_default_get_managed_keyword_secondary (LibHalContext *hal_ctx)
    01432 {
    01433     return hal_device_get_property_string (hal_ctx, "/org/freedesktop/Hal/devices/computer",
    01434                            "storage.policy.default.managed_keyword.secondary");
    01435 }
    01436
    01437 /*************************************************************************/
    01438
    01439 dbus_bool_t
    01440 hal_drive_policy_is_mountable (HalDrive *drive, HalStoragePolicy *policy)
    01441 {
    01442     return drive->should_mount && drive->no_partitions_hint;
    01443 }
    01444
    01445 const char *
    01446 hal_drive_policy_get_desired_mount_point (HalDrive *drive, HalStoragePolicy *policy)
    01447 {
    01448     return drive->desired_mount_point;
    01449 }
    01450
    01451 /* safely strcat() at most the remaining space in 'dst' */
    01452 #define strcat_len(dst, src, dstmaxlen) do {    \
    01453     dst[dstmaxlen - 1] = '\0'; \
    01454     strncat (dst, src, dstmaxlen - strlen (dst) - 1); \
    01455 } while(0)
    01456
    01457
    01458 static void
    01459 mopts_collect (LibHalContext *hal_ctx, const char *namespace, int namespace_len,
    01460            const char *udi, char *options_string, size_t options_max_len, dbus_bool_t only_collect_imply_opts)
    01461 {
    01462     LibHalPropertySet *properties;
    01463     LibHalPropertySetIterator it;
    01464
    01465     /* first collect from root computer device */
    01466     properties = hal_device_get_all_properties (hal_ctx, udi);
    01467     if (properties == NULL)
    01468         goto error;
    01469     for (hal_psi_init (&it, properties); hal_psi_has_more (&it); hal_psi_next (&it)) {
    01470         int type;
    01471         char *key;
    01472
    01473         type = hal_psi_get_type (&it);
    01474         key = hal_psi_get_key (&it);
    01475         if (hal_psi_get_type (&it) == DBUS_TYPE_BOOLEAN &&
    01476             strncmp (key, namespace, namespace_len - 1) == 0) {
    01477             const char *option = key + namespace_len - 1;
    01478             char *location;
    01479             dbus_bool_t is_imply_opt;
    01480
    01481             is_imply_opt = FALSE;
    01482             if (strcmp (option, "user") == 0 ||
    01483                 strcmp (option, "users") == 0 ||
    01484                 strcmp (option, "defaults") == 0 ||
    01485                 strcmp (option, "pamconsole") == 0)
    01486                 is_imply_opt = TRUE;
    01487
    01488
    01489             if (only_collect_imply_opts) {
    01490                 if (!is_imply_opt)
    01491                     continue;
    01492             } else {
    01493                 if (is_imply_opt)
    01494                     continue;
    01495             }
    01496
    01497             if (hal_psi_get_bool (&it)) {
    01498                 /* see if option is already there */
    01499                 location = strstr (options_string, option);
    01500                 if (location == NULL) {
    01501                     if (strlen (options_string) > 0)
    01502                         strcat_len (options_string, ",", options_max_len);
    01503                     strcat_len (options_string, option, options_max_len);
    01504                 }
    01505             } else {
    01506                 /* remove option if already there */
    01507                 location = strstr (options_string, option);
    01508                 if (location != NULL) {
    01509                     char *end;
    01510
    01511                     end = strchr (location, ',');
    01512                     if (end == NULL) {
    01513                         /* pointer arithmetic; uhh */
    01514                         if (location > options_string) {
    01515                             location[-1] = '\0'; /* uh, remove trailing comma */
    01516                         } else {
    01517                             location[0] = '\0';
    01518                         }
    01519                     } else {
    01520                         strcpy (location, end + 1); /* skip the extra comma */
    01521                     }
    01522                 }
    01523
    01524             }
    01525         }
    01526     }
    01527 error:
    01528     hal_free_property_set (properties);
    01529 }
    01530
    01531
    01532 const char *
    01533 hal_drive_policy_get_mount_options (HalDrive *drive, HalStoragePolicy *policy)
    01534 {
    01535     const char *result;
    01536     char stor_mount_option_default_begin[] = "storage.policy.default.mount_option.";
    01537     char stor_mount_option_begin[] = "storage.policy.mount_option.";
    01538
    01539     result = NULL;
    01540     drive->mount_options[0] = '\0';
    01541
    01542     /* collect options != ('pamconsole', 'user', 'users', 'defaults' options that imply other options)  */
    01543     mopts_collect (drive->hal_ctx, stor_mount_option_default_begin, sizeof (stor_mount_option_default_begin),
    01544                "/org/freedesktop/Hal/devices/computer", drive->mount_options, MOUNT_OPTIONS_SIZE, TRUE);
    01545     mopts_collect (drive->hal_ctx, stor_mount_option_begin, sizeof (stor_mount_option_begin),
    01546                drive->udi, drive->mount_options, MOUNT_OPTIONS_SIZE, TRUE);
    01547     /* ensure ('pamconsole', 'user', 'users', 'defaults' options that imply other options), are first */
    01548     mopts_collect (drive->hal_ctx, stor_mount_option_default_begin, sizeof (stor_mount_option_default_begin),
    01549                "/org/freedesktop/Hal/devices/computer", drive->mount_options, MOUNT_OPTIONS_SIZE, FALSE);
    01550     mopts_collect (drive->hal_ctx, stor_mount_option_begin, sizeof (stor_mount_option_begin),
    01551                drive->udi, drive->mount_options, MOUNT_OPTIONS_SIZE, FALSE);
    01552
    01553     result = drive->mount_options;
    01554
    01555     return result;
    01556 }
    01557
    01558 const char *
    01559 hal_drive_policy_get_mount_fs (HalDrive *drive, HalStoragePolicy *policy)
    01560 {
    01561     return drive->mount_filesystem;
    01562 }
    01563
    01564
    01565 dbus_bool_t
    01566 hal_volume_policy_is_mountable (HalDrive *drive, HalVolume *volume, HalStoragePolicy *policy)
    01567 {
    01568     return drive->should_mount && volume->should_mount;
    01569 }
    01570
    01571 const char *hal_volume_policy_get_desired_mount_point (HalDrive *drive, HalVolume *volume, HalStoragePolicy *policy)
    01572 {
    01573     return volume->desired_mount_point;
    01574 }
    01575
    01576 const char *hal_volume_policy_get_mount_options (HalDrive *drive, HalVolume *volume, HalStoragePolicy *policy)
    01577 {
    01578     const char *result;
    01579     char stor_mount_option_default_begin[] = "storage.policy.default.mount_option.";
    01580     char vol_mount_option_begin[] = "volume.policy.mount_option.";
    01581
    01582     result = NULL;
    01583     volume->mount_options[0] = '\0';
    01584
    01585     /* ensure ('pamconsole', 'user', 'users', 'defaults' options that imply other options), are first */
    01586     mopts_collect (drive->hal_ctx, stor_mount_option_default_begin, sizeof (stor_mount_option_default_begin),
    01587                "/org/freedesktop/Hal/devices/computer", volume->mount_options, MOUNT_OPTIONS_SIZE, TRUE);
    01588     mopts_collect (drive->hal_ctx, vol_mount_option_begin, sizeof (vol_mount_option_begin),
    01589                volume->udi, volume->mount_options, MOUNT_OPTIONS_SIZE, TRUE);
    01590     /* collect options != ('pamconsole', 'user', 'users', 'defaults' options that imply other options)  */
    01591     mopts_collect (drive->hal_ctx, stor_mount_option_default_begin, sizeof (stor_mount_option_default_begin),
    01592                "/org/freedesktop/Hal/devices/computer", volume->mount_options, MOUNT_OPTIONS_SIZE, FALSE);
    01593     mopts_collect (drive->hal_ctx, vol_mount_option_begin, sizeof (vol_mount_option_begin),
    01594                volume->udi, volume->mount_options, MOUNT_OPTIONS_SIZE, FALSE);
    01595
    01596     result = volume->mount_options;
    01597
    01598     return result;
    01599 }
    01600
    01601 const char *hal_volume_policy_get_mount_fs (HalDrive *drive, HalVolume *volume, HalStoragePolicy *policy)
    01602 {
    01603     return volume->mount_filesystem;
    01604 }
    01605
    01606 dbus_bool_t
    01607 hal_drive_no_partitions_hint (HalDrive *drive)
    01608 {
    01609     return drive->no_partitions_hint;
    01610 }
    01611