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.22 2005/08/10 20:34:21 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) (String)
    00057 # define N_(String) (String)
    00058 #endif
    00059
    00067 typedef struct IconMappingEntry_s {
    00068     LibHalStoragePolicyIcon icon;
    00069     char *path;
    00070     struct IconMappingEntry_s *next;
    00071 } IconMappingEntry;
    00072
    00073 struct LibHalStoragePolicy_s {
    00074     IconMappingEntry *icon_mappings;
    00075 };
    00076
    00077 LibHalStoragePolicy *
    00078 libhal_storage_policy_new ()
    00079 {
    00080     LibHalStoragePolicy *p;
    00081
    00082     p = malloc (sizeof (LibHalStoragePolicy));
    00083     if (p == NULL)
    00084         goto out;
    00085
    00086     p->icon_mappings = NULL;
    00087 out:
    00088     return p;
    00089 }
    00090
    00091 void
    00092 libhal_storage_policy_free (LibHalStoragePolicy *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 libhal_storage_policy_set_icon_path (LibHalStoragePolicy *policy, LibHalStoragePolicyIcon 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 libhal_storage_policy_set_icon_mapping (LibHalStoragePolicy *policy, LibHalStoragePolicyIconPair *pairs)
    00135 {
    00136     LibHalStoragePolicyIconPair *i;
    00137
    00138     for (i = pairs; i->icon != 0x00; i++) {
    00139         libhal_storage_policy_set_icon_path (policy, i->icon, i->icon_path);
    00140     }
    00141 }
    00142
    00143 const char *
    00144 libhal_storage_policy_lookup_icon (LibHalStoragePolicy *policy, LibHalStoragePolicyIcon 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 libhal_volume_policy_compute_size_as_string (LibHalVolume *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 = libhal_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 libhal_drive_policy_compute_display_name (LibHalDrive *drive, LibHalVolume *volume, LibHalStoragePolicy *policy)
    00213 {
    00214     char *name;
    00215     char *size_str;
    00216     char *vendormodel_str;
    00217     const char *model;
    00218     const char *vendor;
    00219     LibHalDriveType drive_type;
    00220     dbus_bool_t drive_is_hotpluggable;
    00221     dbus_bool_t drive_is_removable;
    00222     LibHalDriveCdromCaps drive_cdrom_caps;
    00223     char buf[MAX_STRING_SZ];
    00224
    00225     model = libhal_drive_get_model (drive);
    00226     vendor = libhal_drive_get_vendor (drive);
    00227     drive_type = libhal_drive_get_type (drive);
    00228     drive_is_hotpluggable = libhal_drive_is_hotpluggable (drive);
    00229     drive_is_removable = libhal_drive_uses_removable_media (drive);
    00230     drive_cdrom_caps = libhal_drive_get_cdrom_caps (drive);
    00231
    00232     if (volume != NULL)
    00233         size_str = libhal_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==LIBHAL_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 & LIBHAL_DRIVE_CDROM_CAPS_CDR)
    00262             first = "CD-R";
    00263         if (drive_cdrom_caps & LIBHAL_DRIVE_CDROM_CAPS_CDRW)
    00264             first = "CD-RW";
    00265
    00266         second = "";
    00267         if (drive_cdrom_caps & LIBHAL_DRIVE_CDROM_CAPS_DVDROM)
    00268             second = "/DVD-ROM";
    00269         if (drive_cdrom_caps & LIBHAL_DRIVE_CDROM_CAPS_DVDPLUSR)
    00270             second = "/DVD+R";
    00271         if (drive_cdrom_caps & LIBHAL_DRIVE_CDROM_CAPS_DVDPLUSRW)
    00272             second = "/DVD+RW";
    00273         if (drive_cdrom_caps & LIBHAL_DRIVE_CDROM_CAPS_DVDR)
    00274             second = "/DVD-R";
    00275         if (drive_cdrom_caps & LIBHAL_DRIVE_CDROM_CAPS_DVDRW)
    00276             second = "/DVD-RW";
    00277         if (drive_cdrom_caps & LIBHAL_DRIVE_CDROM_CAPS_DVDRAM)
    00278             second = "/DVD-RAM";
    00279         if ((drive_cdrom_caps & LIBHAL_DRIVE_CDROM_CAPS_DVDR) &&
    00280             (drive_cdrom_caps & LIBHAL_DRIVE_CDROM_CAPS_DVDPLUSR)) {
    00281             if(drive_cdrom_caps & LIBHAL_DRIVE_CDROM_CAPS_DVDPLUSRDL)
    00282                 second = "/DVD±R DL";
    00283             else
    00284                 second = "/DVD±R";
    00285         }
    00286         if ((drive_cdrom_caps & LIBHAL_DRIVE_CDROM_CAPS_DVDRW) &&
    00287             (drive_cdrom_caps & LIBHAL_DRIVE_CDROM_CAPS_DVDPLUSRW)) {
    00288                         if(drive_cdrom_caps & LIBHAL_DRIVE_CDROM_CAPS_DVDPLUSRDL)
    00289                                 second = "/DVD±RW DL";
    00290                         else
    00291                                 second = "/DVD±RW";
    00292                 }
    00293
    00294
    00295         if (drive_is_hotpluggable) {
    00296             snprintf (buf, MAX_STRING_SZ, _("External %s%s Drive"), first, second);
    00297             name = strdup (buf);
    00298         } else {
    00299             snprintf (buf, MAX_STRING_SZ, _("%s%s Drive"), first, second);
    00300             name = strdup (buf);
    00301         }
    00302
    00303     } else if (drive_type==LIBHAL_DRIVE_TYPE_FLOPPY) {
    00304
    00305         /* Floppy Drive handling */
    00306
    00307         if (drive_is_hotpluggable)
    00308             name = strdup (_("External Floppy Drive"));
    00309         else
    00310             name = strdup (_("Floppy Drive"));
    00311     } else if (drive_type==LIBHAL_DRIVE_TYPE_DISK && !drive_is_removable) {
    00312
    00313         /* Harddisks */
    00314
    00315         if (size_str != NULL) {
    00316             if (drive_is_hotpluggable) {
    00317                 snprintf (buf, MAX_STRING_SZ, _("%s External Hard Drive"), size_str);
    00318                 name = strdup (buf);
    00319             } else {
    00320                 snprintf (buf, MAX_STRING_SZ, _("%s Hard Drive"), size_str);
    00321                 name = strdup (buf);
    00322             }
    00323         } else {
    00324             if (drive_is_hotpluggable)
    00325                 name = strdup (_("External Hard Drive"));
    00326             else
    00327                 name = strdup (_("Hard Drive"));
    00328         }
    00329     } else {
    00330
    00331         /* The rest - includes drives with removable Media */
    00332
    00333         if (strlen (vendormodel_str) > 0)
    00334             name = strdup (vendormodel_str);
    00335         else
    00336             name = strdup (_("Drive"));
    00337     }
    00338
    00339     free (vendormodel_str);
    00340     free (size_str);
    00341
    00342     return name;
    00343 }
    00344
    00345 char *
    00346 libhal_volume_policy_compute_display_name (LibHalDrive *drive, LibHalVolume *volume, LibHalStoragePolicy *policy)
    00347 {
    00348     char *name;
    00349     char *size_str;
    00350     const char *volume_label;
    00351     const char *model;
    00352     const char *vendor;
    00353     LibHalDriveType drive_type;
    00354     dbus_bool_t drive_is_hotpluggable;
    00355     dbus_bool_t drive_is_removable;
    00356     LibHalDriveCdromCaps drive_cdrom_caps;
    00357     char buf[MAX_STRING_SZ];
    00358
    00359     volume_label = libhal_volume_get_label (volume);
    00360     model = libhal_drive_get_model (drive);
    00361     vendor = libhal_drive_get_vendor (drive);
    00362     drive_type = libhal_drive_get_type (drive);
    00363     drive_is_hotpluggable = libhal_drive_is_hotpluggable (drive);
    00364     drive_is_removable = libhal_drive_uses_removable_media (drive);
    00365     drive_cdrom_caps = libhal_drive_get_cdrom_caps (drive);
    00366
    00367     size_str = libhal_volume_policy_compute_size_as_string (volume);
    00368
    00369     /* If the volume label is available use that
    00370      *
    00371      * TODO: If label is a fully-qualified UNIX path don't use that
    00372      */
    00373     if (volume_label != NULL) {
    00374         name = strdup (volume_label);
    00375         goto out;
    00376     }
    00377
    00378     /* Handle media in optical drives */
    00379     if (drive_type==LIBHAL_DRIVE_TYPE_CDROM) {
    00380         switch (libhal_volume_get_disc_type (volume)) {
    00381
    00382         default:
    00383             /* explict fallthrough */
    00384         case LIBHAL_VOLUME_DISC_TYPE_CDROM:
    00385             name = strdup (_("CD-ROM "));
    00386             break;
    00387
    00388         case LIBHAL_VOLUME_DISC_TYPE_CDR:
    00389             if (libhal_volume_disc_is_blank (volume))
    00390                 name = strdup (_("Blank CD-R"));
    00391             else
    00392                 name = strdup (_("CD-R"));
    00393             break;
    00394
    00395         case LIBHAL_VOLUME_DISC_TYPE_CDRW:
    00396             if (libhal_volume_disc_is_blank (volume))
    00397                 name = strdup (_("Blank CD-RW"));
    00398             else
    00399                 name = strdup (_("CD-RW"));
    00400             break;
    00401
    00402         case LIBHAL_VOLUME_DISC_TYPE_DVDROM:
    00403             name = strdup (_("DVD-ROM"));
    00404             break;
    00405
    00406         case LIBHAL_VOLUME_DISC_TYPE_DVDRAM:
    00407             if (libhal_volume_disc_is_blank (volume))
    00408                 name = strdup (_("Blank DVD-RAM"));
    00409             else
    00410                 name = strdup (_("DVD-RAM"));
    00411             break;
    00412
    00413         case LIBHAL_VOLUME_DISC_TYPE_DVDR:
    00414             if (libhal_volume_disc_is_blank (volume))
    00415                 name = strdup (_("Blank DVD-R"));
    00416             else
    00417                 name = strdup (_("DVD-R"));
    00418             break;
    00419
    00420         case LIBHAL_VOLUME_DISC_TYPE_DVDRW:
    00421             if (libhal_volume_disc_is_blank (volume))
    00422                 name = strdup (_("Blank DVD-RW"));
    00423             else
    00424                 name = strdup (_("DVD-RW"));
    00425             break;
    00426
    00427         case LIBHAL_VOLUME_DISC_TYPE_DVDPLUSR:
    00428             if (libhal_volume_disc_is_blank (volume))
    00429                 name = strdup (_("Blank DVD+R"));
    00430             else
    00431                 name = strdup (_("DVD+R"));
    00432             break;
    00433
    00434         case LIBHAL_VOLUME_DISC_TYPE_DVDPLUSRW:
    00435             if (libhal_volume_disc_is_blank (volume))
    00436                 name = strdup (_("Blank DVD+RW"));
    00437             else
    00438                 name = strdup (_("DVD+RW"));
    00439             break;
    00440
    00441         case LIBHAL_VOLUME_DISC_TYPE_DVDPLUSR_DL:
    00442             if (libhal_volume_disc_is_blank (volume))
    00443                 name = strdup (_("Blank DVD+R Dual-Layer"));
    00444             else
    00445                 name = strdup (_("DVD+R Dual-Layer"));
    00446             break;
    00447         }
    00448
    00449         /* Special case for pure audio disc */
    00450         if (libhal_volume_disc_has_audio (volume) && !libhal_volume_disc_has_data (volume)) {
    00451             free (name);
    00452             name = strdup (_("Audio CD"));
    00453         }
    00454
    00455         goto out;
    00456     }
    00457
    00458     /* Fallback: size of media */
    00459     if (drive_is_removable) {
    00460         snprintf (buf, MAX_STRING_SZ, _("%s Removable Media"), size_str);
    00461         name = strdup (buf);
    00462     } else {
    00463         snprintf (buf, MAX_STRING_SZ, _("%s Media"), size_str);
    00464         name = strdup (buf);
    00465     }
    00466
    00467     /* Fallback: Use drive name */
    00468     /*name = libhal_drive_policy_compute_display_name (drive, volume);*/
    00469
    00470 out:
    00471     free (size_str);
    00472     return name;
    00473 }
    00474
    00475 char *
    00476 libhal_drive_policy_compute_icon_name (LibHalDrive *drive, LibHalVolume *volume, LibHalStoragePolicy *policy)
    00477 {
    00478     const char *name;
    00479     LibHalDriveBus bus;
    00480     LibHalDriveType drive_type;
    00481
    00482     bus        = libhal_drive_get_bus (drive);
    00483     drive_type = libhal_drive_get_type (drive);
    00484
    00485     /* by design, the enums are laid out so we can do easy computations */
    00486
    00487     switch (drive_type) {
    00488     case LIBHAL_DRIVE_TYPE_REMOVABLE_DISK:
    00489     case LIBHAL_DRIVE_TYPE_DISK:
    00490     case LIBHAL_DRIVE_TYPE_CDROM:
    00491     case LIBHAL_DRIVE_TYPE_FLOPPY:
    00492         name = libhal_storage_policy_lookup_icon (policy, 0x10000 + drive_type*0x100 + bus);
    00493         break;
    00494
    00495     default:
    00496         name = libhal_storage_policy_lookup_icon (policy, 0x10000 + drive_type*0x100);
    00497     }
    00498
    00499     if (name != NULL)
    00500         return strdup (name);
    00501     else
    00502         return NULL;
    00503 }
    00504
    00505 char *
    00506 libhal_volume_policy_compute_icon_name (LibHalDrive *drive, LibHalVolume *volume, LibHalStoragePolicy *policy)
    00507 {
    00508     const char *name;
    00509     LibHalDriveBus bus;
    00510     LibHalDriveType drive_type;
    00511     LibHalVolumeDiscType disc_type;
    00512
    00513     /* by design, the enums are laid out so we can do easy computations */
    00514
    00515     if (libhal_volume_is_disc (volume)) {
    00516         disc_type = libhal_volume_get_disc_type (volume);
    00517         name = libhal_storage_policy_lookup_icon (policy, 0x30000 + disc_type);
    00518         goto out;
    00519     }
    00520
    00521     if (drive == NULL) {
    00522         name = libhal_storage_policy_lookup_icon (policy, LIBHAL_STORAGE_ICON_VOLUME_REMOVABLE_DISK);
    00523         goto out;
    00524     }
    00525
    00526     bus        = libhal_drive_get_bus (drive);
    00527     drive_type = libhal_drive_get_type (drive);
    00528
    00529     switch (drive_type) {
    00530     case LIBHAL_DRIVE_TYPE_REMOVABLE_DISK:
    00531     case LIBHAL_DRIVE_TYPE_DISK:
    00532     case LIBHAL_DRIVE_TYPE_CDROM:
    00533     case LIBHAL_DRIVE_TYPE_FLOPPY:
    00534         name = libhal_storage_policy_lookup_icon (policy, 0x20000 + drive_type*0x100 + bus);
    00535         break;
    00536
    00537     default:
    00538         name = libhal_storage_policy_lookup_icon (policy, 0x20000 + drive_type*0x100);
    00539     }
    00540 out:
    00541     if (name != NULL)
    00542         return strdup (name);
    00543     else
    00544         return NULL;
    00545 }
    00546
    00563 dbus_bool_t
    00564 libhal_volume_policy_should_be_visible (LibHalDrive *drive, LibHalVolume *volume, LibHalStoragePolicy *policy,
    00565                      const char *target_mount_point)
    00566 {
    00567     unsigned int i;
    00568     dbus_bool_t is_visible;
    00569     const char *label;
    00570     const char *mount_point;
    00571     const char *fstype;
    00572     const char *fhs23_toplevel_mount_points[] = {
    00573         "/",
    00574         "/bin",
    00575         "/boot",
    00576         "/dev",
    00577         "/etc",
    00578         "/home",
    00579         "/lib",
    00580         "/lib64",
    00581         "/media",
    00582         "/mnt",
    00583         "/opt",
    00584         "/root",
    00585         "/sbin",
    00586         "/srv",
    00587         "/tmp",
    00588         "/usr",
    00589         "/var",
    00590         "/proc",
    00591         "/sbin",
    00592         NULL
    00593     };
    00594
    00595     is_visible = FALSE;
    00596
    00597     /* skip if hal says it's not used as a filesystem */
    00598     if (libhal_volume_get_fsusage (volume) != LIBHAL_VOLUME_USAGE_MOUNTABLE_FILESYSTEM)
    00599         goto out;
    00600
    00601     label = libhal_volume_get_label (volume);
    00602     mount_point = libhal_volume_get_mount_point (volume);
    00603     fstype = libhal_volume_get_fstype (volume);
    00604
    00605     /* use target mount point if we're not mounted yet */
    00606     if (mount_point == NULL)
    00607         mount_point = target_mount_point;
    00608
    00609     /* bail out if we don't know the filesystem */
    00610     if (fstype == NULL)
    00611         goto out;
    00612
    00613     /* blacklist fhs2.3 top level mount points */
    00614     if (mount_point != NULL) {
    00615         for (i = 0; fhs23_toplevel_mount_points[i] != NULL; i++) {
    00616             if (strcmp (mount_point, fhs23_toplevel_mount_points[i]) == 0)
    00617                 goto out;
    00618         }
    00619     }
    00620
    00621     /* blacklist partitions with name 'bootstrap' of type HFS (Apple uses that) */
    00622     if (label != NULL && strcmp (label, "bootstrap") == 0 && strcmp (fstype, "hfs") == 0)
    00623         goto out;
    00624
    00625     /* only the real lucky mount points will make it this far :-) */
    00626     is_visible = TRUE;
    00627
    00628 out:
    00629     return is_visible;
    00630 }
    00631
    00632 /*************************************************************************/
    00633
    00634 #define MOUNT_OPTIONS_SIZE 256
    00635
    00636 struct LibHalDrive_s {
    00637     char *udi;
    00638
    00639     int device_major;
    00640     int device_minor;
    00641     char *device_file;
    00642
    00643     LibHalDriveBus bus;
    00644     char *vendor;             /* may be "", is never NULL */
    00645     char *model;              /* may be "", is never NULL */
    00646     dbus_bool_t is_hotpluggable;
    00647     dbus_bool_t is_removable;
    00648     dbus_bool_t requires_eject;
    00649
    00650     LibHalDriveType type;
    00651     char *type_textual;
    00652
    00653     char *physical_device;  /* UDI of physical device, e.g. the
    00654                  * IDE, USB, IEEE1394 device */
    00655
    00656     char *dedicated_icon_drive;
    00657     char *dedicated_icon_volume;
    00658
    00659     char *serial;
    00660     char *firmware_version;
    00661     LibHalDriveCdromCaps cdrom_caps;
    00662
    00663     char *desired_mount_point;
    00664     char *mount_filesystem;
    00665     dbus_bool_t should_mount;
    00666
    00667     dbus_bool_t no_partitions_hint;
    00668
    00669     LibHalContext *hal_ctx;
    00670
    00671     char **capabilities;
    00672
    00673     char mount_options[MOUNT_OPTIONS_SIZE];
    00674 };
    00675
    00676 struct LibHalVolume_s {
    00677     char *udi;
    00678
    00679     int device_major;
    00680     int device_minor;
    00681     char *device_file;
    00682     char *volume_label; /* may be NULL, is never "" */
    00683     dbus_bool_t is_mounted;
    00684     char *mount_point;  /* NULL iff !is_mounted */
    00685     char *fstype;       /* NULL iff !is_mounted or unknown */
    00686     char *fsversion;
    00687     char *uuid;
    00688     char *storage_device;
    00689
    00690     LibHalVolumeUsage fsusage;
    00691
    00692     dbus_bool_t is_partition;
    00693     unsigned int partition_number;
    00694
    00695     int msdos_part_table_type;
    00696
    00697
    00698     dbus_bool_t is_disc;
    00699     LibHalVolumeDiscType disc_type;
    00700     dbus_bool_t disc_has_audio;
    00701     dbus_bool_t disc_has_data;
    00702     dbus_bool_t disc_is_appendable;
    00703     dbus_bool_t disc_is_blank;
    00704     dbus_bool_t disc_is_rewritable;
    00705
    00706     unsigned int block_size;
    00707     unsigned int num_blocks;
    00708
    00709     char *desired_mount_point;
    00710     char *mount_filesystem;
    00711     dbus_bool_t should_mount;
    00712
    00713     char mount_options[MOUNT_OPTIONS_SIZE];
    00714 };
    00715
    00716 const char *
    00717 libhal_drive_get_dedicated_icon_drive (LibHalDrive *drive)
    00718 {
    00719     return drive->dedicated_icon_drive;
    00720 }
    00721
    00722 const char *
    00723 libhal_drive_get_dedicated_icon_volume (LibHalDrive *drive)
    00724 {
    00725     return drive->dedicated_icon_volume;
    00726 }
    00727
    00732 void
    00733 libhal_drive_free (LibHalDrive *drive)
    00734 {
    00735     if (drive == NULL )
    00736         return;
    00737
    00738     free (drive->udi);
    00739     libhal_free_string (drive->device_file);
    00740     libhal_free_string (drive->vendor);
    00741     libhal_free_string (drive->model);
    00742     libhal_free_string (drive->type_textual);
    00743     libhal_free_string (drive->physical_device);
    00744     libhal_free_string (drive->serial);
    00745     libhal_free_string (drive->firmware_version);
    00746     libhal_free_string (drive->desired_mount_point);
    00747     libhal_free_string (drive->mount_filesystem);
    00748     libhal_free_string_array (drive->capabilities);
    00749 }
    00750
    00751
    00756 void
    00757 libhal_volume_free (LibHalVolume *vol)
    00758 {
    00759     if (vol == NULL )
    00760         return;
    00761
    00762     free (vol->udi);
    00763     libhal_free_string (vol->device_file);
    00764     libhal_free_string (vol->volume_label);
    00765     libhal_free_string (vol->fstype);
    00766     libhal_free_string (vol->mount_point);
    00767     libhal_free_string (vol->fsversion);
    00768     libhal_free_string (vol->uuid);
    00769     libhal_free_string (vol->desired_mount_point);
    00770     libhal_free_string (vol->mount_filesystem);
    00771 }
    00772
    00773
    00774 static char **
    00775 my_strvdup (char **strv)
    00776 {
    00777     unsigned int num_elems;
    00778     unsigned int i;
    00779     char **res;
    00780
    00781     for (num_elems = 0; strv[num_elems] != NULL; num_elems++)
    00782         ;
    00783
    00784     res = calloc (num_elems + 1, sizeof (char*));
    00785     if (res == NULL)
    00786         goto out;
    00787
    00788     for (i = 0; i < num_elems; i++)
    00789         res[i] = strdup (strv[i]);
    00790     res[i] = NULL;
    00791
    00792 out:
    00793     return res;
    00794 }
    00795
    00796 /* ok, hey, so this is a bit ugly */
    00797
    00798 #define LIBHAL_PROP_EXTRACT_BEGIN if (FALSE)
    00799 #define LIBHAL_PROP_EXTRACT_END ;
    00800 #define LIBHAL_PROP_EXTRACT_INT(_property_, _where_) else if (strcmp (key, _property_) == 0 && type == LIBHAL_PROPERTY_TYPE_INT32) _where_ = libhal_psi_get_int (&it)
    00801 #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
    00802 #define LIBHAL_PROP_EXTRACT_BOOL(_property_, _where_) else if (strcmp (key, _property_) == 0 && type == LIBHAL_PROPERTY_TYPE_BOOLEAN) _where_ = libhal_psi_get_bool (&it)
    00803 #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
    00804 #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))
    00805
    00814 LibHalDrive *
    00815 libhal_drive_from_udi (LibHalContext *hal_ctx, const char *udi)
    00816 {
    00817     char *bus_textual;
    00818     LibHalDrive *drive;
    00819     LibHalPropertySet *properties;
    00820     LibHalPropertySetIterator it;
    00821     DBusError error;
    00822     unsigned int i;
    00823
    00824     LIBHAL_CHECK_LIBHALCONTEXT(hal_ctx, NULL);
    00825
    00826     drive = NULL;
    00827     properties = NULL;
    00828     bus_textual = NULL;
    00829
    00830     dbus_error_init (&error);
    00831     if (!libhal_device_query_capability (hal_ctx, udi, "storage", &error))
    00832         goto error;
    00833
    00834     drive = malloc (sizeof (LibHalDrive));
    00835     if (drive == NULL)
    00836         goto error;
    00837     memset (drive, 0x00, sizeof (LibHalDrive));
    00838
    00839     drive->hal_ctx = hal_ctx;
    00840
    00841     drive->udi = strdup (udi);
    00842     if (drive->udi == NULL)
    00843         goto error;
    00844
    00845     properties = libhal_device_get_all_properties (hal_ctx, udi, &error);
    00846     if (properties == NULL)
    00847         goto error;
    00848
    00849     /* we can count on hal to give us all these properties */
    00850     for (libhal_psi_init (&it, properties); libhal_psi_has_more (&it); libhal_psi_next (&it)) {
    00851         int type;
    00852         char *key;
    00853
    00854         type = libhal_psi_get_type (&it);
    00855         key = libhal_psi_get_key (&it);
    00856
    00857         LIBHAL_PROP_EXTRACT_BEGIN;
    00858
    00859         LIBHAL_PROP_EXTRACT_INT    ("block.minor",               drive->device_minor);
    00860         LIBHAL_PROP_EXTRACT_INT    ("block.major",               drive->device_major);
    00861         LIBHAL_PROP_EXTRACT_STRING ("block.device",              drive->device_file);
    00862         LIBHAL_PROP_EXTRACT_STRING ("storage.bus",               bus_textual);
    00863         LIBHAL_PROP_EXTRACT_STRING ("storage.vendor",            drive->vendor);
    00864         LIBHAL_PROP_EXTRACT_STRING ("storage.model",             drive->model);
    00865         LIBHAL_PROP_EXTRACT_STRING ("storage.drive_type",        drive->type_textual);
    00866
    00867
    00868         LIBHAL_PROP_EXTRACT_STRING ("storage.icon.drive",        drive->dedicated_icon_drive);
    00869         LIBHAL_PROP_EXTRACT_STRING ("storage.icon.volume",       drive->dedicated_icon_volume);
    00870
    00871         LIBHAL_PROP_EXTRACT_BOOL   ("storage.hotpluggable",      drive->is_hotpluggable);
    00872         LIBHAL_PROP_EXTRACT_BOOL   ("storage.removable",         drive->is_removable);
    00873         LIBHAL_PROP_EXTRACT_BOOL   ("storage.requires_eject",    drive->requires_eject);
    00874
    00875         LIBHAL_PROP_EXTRACT_STRING ("storage.physical_device",   drive->physical_device);
    00876         LIBHAL_PROP_EXTRACT_STRING ("storage.firmware_version",  drive->firmware_version);
    00877         LIBHAL_PROP_EXTRACT_STRING ("storage.serial",            drive->serial);
    00878
    00879         LIBHAL_PROP_EXTRACT_BOOL_BITFIELD ("storage.cdrom.cdr", drive->cdrom_caps, LIBHAL_DRIVE_CDROM_CAPS_CDR);
    00880         LIBHAL_PROP_EXTRACT_BOOL_BITFIELD ("storage.cdrom.cdrw", drive->cdrom_caps, LIBHAL_DRIVE_CDROM_CAPS_CDRW);
    00881         LIBHAL_PROP_EXTRACT_BOOL_BITFIELD ("storage.cdrom.dvd", drive->cdrom_caps, LIBHAL_DRIVE_CDROM_CAPS_DVDROM);
    00882         LIBHAL_PROP_EXTRACT_BOOL_BITFIELD ("storage.cdrom.dvdplusr", drive->cdrom_caps, LIBHAL_DRIVE_CDROM_CAPS_DVDPLUSR);
    00883         LIBHAL_PROP_EXTRACT_BOOL_BITFIELD ("storage.cdrom.dvdplusrw", drive->cdrom_caps, LIBHAL_DRIVE_CDROM_CAPS_DVDPLUSRW);
    00884         LIBHAL_PROP_EXTRACT_BOOL_BITFIELD ("storage.cdrom.dvdplusrdl", drive->cdrom_caps, LIBHAL_DRIVE_CDROM_CAPS_DVDPLUSRDL);
    00885         LIBHAL_PROP_EXTRACT_BOOL_BITFIELD ("storage.cdrom.dvdr", drive->cdrom_caps, LIBHAL_DRIVE_CDROM_CAPS_DVDR);
    00886         LIBHAL_PROP_EXTRACT_BOOL_BITFIELD ("storage.cdrom.dvdrw", drive->cdrom_caps, LIBHAL_DRIVE_CDROM_CAPS_DVDRW);
    00887         LIBHAL_PROP_EXTRACT_BOOL_BITFIELD ("storage.cdrom.dvdram", drive->cdrom_caps, LIBHAL_DRIVE_CDROM_CAPS_DVDRAM);
    00888
    00889         LIBHAL_PROP_EXTRACT_BOOL   ("storage.policy.should_mount",        drive->should_mount);
    00890         LIBHAL_PROP_EXTRACT_STRING ("storage.policy.desired_mount_point", drive->desired_mount_point);
    00891         LIBHAL_PROP_EXTRACT_STRING ("storage.policy.mount_filesystem",    drive->mount_filesystem);
    00892
    00893         LIBHAL_PROP_EXTRACT_BOOL   ("storage.no_partitions_hint",        drive->no_partitions_hint);
    00894
    00895         LIBHAL_PROP_EXTRACT_STRLIST ("info.capabilities",                drive->capabilities);
    00896
    00897         LIBHAL_PROP_EXTRACT_END;
    00898     }
    00899
    00900     if (drive->type_textual != NULL) {
    00901         if (strcmp (drive->type_textual, "cdrom") == 0) {
    00902             drive->cdrom_caps |= LIBHAL_DRIVE_CDROM_CAPS_CDROM;
    00903             drive->type = LIBHAL_DRIVE_TYPE_CDROM;
    00904         } else if (strcmp (drive->type_textual, "floppy") == 0) {
    00905             drive->type = LIBHAL_DRIVE_TYPE_FLOPPY;
    00906         } else if (strcmp (drive->type_textual, "disk") == 0) {
    00907             if (drive->is_removable)
    00908                 drive->type = LIBHAL_DRIVE_TYPE_REMOVABLE_DISK;
    00909             else
    00910                 drive->type = LIBHAL_DRIVE_TYPE_DISK;
    00911         } else if (strcmp (drive->type_textual, "tape") == 0) {
    00912             drive->type = LIBHAL_DRIVE_TYPE_TAPE;
    00913         } else if (strcmp (drive->type_textual, "compact_flash") == 0) {
    00914             drive->type = LIBHAL_DRIVE_TYPE_COMPACT_FLASH;
    00915         } else if (strcmp (drive->type_textual, "memory_stick") == 0) {
    00916             drive->type = LIBHAL_DRIVE_TYPE_MEMORY_STICK;
    00917         } else if (strcmp (drive->type_textual, "smart_media") == 0) {
    00918             drive->type = LIBHAL_DRIVE_TYPE_SMART_MEDIA;
    00919         } else if (strcmp (drive->type_textual, "sd_mmc") == 0) {
    00920             drive->type = LIBHAL_DRIVE_TYPE_SD_MMC;
    00921         } else if (strcmp (drive->type_textual, "zip") == 0) {
    00922             drive->type = LIBHAL_DRIVE_TYPE_ZIP;
    00923         } else if (strcmp (drive->type_textual, "jaz") == 0) {
    00924             drive->type = LIBHAL_DRIVE_TYPE_JAZ;
    00925         } else if (strcmp (drive->type_textual, "flashkey") == 0) {
    00926             drive->type = LIBHAL_DRIVE_TYPE_FLASHKEY;
    00927         } else {
    00928                 drive->type = LIBHAL_DRIVE_TYPE_DISK;
    00929         }
    00930
    00931     }
    00932
    00933     if (drive->capabilities != NULL) {
    00934         for (i = 0; drive->capabilities[i] != NULL; i++) {
    00935             if (strcmp (drive->capabilities[i], "portable_audio_player") == 0) {
    00936                 drive->type = LIBHAL_DRIVE_TYPE_PORTABLE_AUDIO_PLAYER;
    00937                 break;
    00938             } else if (strcmp (drive->capabilities[i], "camera") == 0) {
    00939                 drive->type = LIBHAL_DRIVE_TYPE_CAMERA;
    00940                 break;
    00941             }
    00942         }
    00943     }
    00944
    00945     if (bus_textual != NULL) {
    00946         if (strcmp (bus_textual, "usb") == 0) {
    00947             drive->bus = LIBHAL_DRIVE_BUS_USB;
    00948         } else if (strcmp (bus_textual, "ieee1394") == 0) {
    00949             drive->bus = LIBHAL_DRIVE_BUS_IEEE1394;
    00950         } else if (strcmp (bus_textual, "ide") == 0) {
    00951             drive->bus = LIBHAL_DRIVE_BUS_IDE;
    00952         } else if (strcmp (bus_textual, "scsi") == 0) {
    00953             drive->bus = LIBHAL_DRIVE_BUS_SCSI;
    00954         } else if (strcmp (bus_textual, "ccw") == 0) {
    00955             drive->bus = LIBHAL_DRIVE_BUS_CCW;
    00956         }
    00957     }
    00958
    00959     libhal_free_string (bus_textual);
    00960     libhal_free_property_set (properties);
    00961
    00962     return drive;
    00963
    00964 error:
    00965     libhal_free_string (bus_textual);
    00966     libhal_free_property_set (properties);
    00967     libhal_drive_free (drive);
    00968     return NULL;
    00969 }
    00970
    00971 const char *
    00972 libhal_volume_get_storage_device_udi (LibHalVolume *volume)
    00973 {
    00974     return volume->storage_device;
    00975 }
    00976
    00977 const char *libhal_drive_get_physical_device_udi (LibHalDrive *drive)
    00978 {
    00979     return drive->physical_device;
    00980 }
    00981
    00982 dbus_bool_t
    00983 libhal_drive_requires_eject (LibHalDrive *drive)
    00984 {
    00985     return drive->requires_eject;
    00986 }
    00987
    00996 LibHalVolume *
    00997 libhal_volume_from_udi (LibHalContext *hal_ctx, const char *udi)
    00998 {
    00999     char *disc_type_textual;
    01000     char *vol_fsusage_textual;
    01001     LibHalVolume *vol;
    01002     LibHalPropertySet *properties;
    01003     LibHalPropertySetIterator it;
    01004     DBusError error;
    01005
    01006     LIBHAL_CHECK_LIBHALCONTEXT(hal_ctx, NULL);
    01007
    01008     vol = NULL;
    01009     properties = NULL;
    01010     disc_type_textual = NULL;
    01011     vol_fsusage_textual = NULL;
    01012
    01013     dbus_error_init (&error);
    01014     if (!libhal_device_query_capability (hal_ctx, udi, "volume", &error))
    01015         goto error;
    01016
    01017     vol = malloc (sizeof (LibHalVolume));
    01018     if (vol == NULL)
    01019         goto error;
    01020     memset (vol, 0x00, sizeof (LibHalVolume));
    01021
    01022     vol->udi = strdup (udi);
    01023
    01024     properties = libhal_device_get_all_properties (hal_ctx, udi, &error);
    01025     if (properties == NULL)
    01026         goto error;
    01027
    01028     /* we can count on hal to give us all these properties */
    01029     for (libhal_psi_init (&it, properties); libhal_psi_has_more (&it); libhal_psi_next (&it)) {
    01030         int type;
    01031         char *key;
    01032
    01033         type = libhal_psi_get_type (&it);
    01034         key = libhal_psi_get_key (&it);
    01035
    01036         LIBHAL_PROP_EXTRACT_BEGIN;
    01037
    01038         LIBHAL_PROP_EXTRACT_INT    ("volume.partition.msdos_part_table_type", vol->msdos_part_table_type);
    01039
    01040         LIBHAL_PROP_EXTRACT_INT    ("block.minor",               vol->device_minor);
    01041         LIBHAL_PROP_EXTRACT_INT    ("block.major",               vol->device_major);
    01042         LIBHAL_PROP_EXTRACT_STRING ("block.device",              vol->device_file);
    01043
    01044         LIBHAL_PROP_EXTRACT_STRING ("block.storage_device",      vol->storage_device);
    01045
    01046         LIBHAL_PROP_EXTRACT_INT    ("volume.block_size",         vol->block_size);
    01047         LIBHAL_PROP_EXTRACT_INT    ("volume.num_blocks",         vol->num_blocks);
    01048         LIBHAL_PROP_EXTRACT_STRING ("volume.label",              vol->volume_label);
    01049         LIBHAL_PROP_EXTRACT_STRING ("volume.mount_point",        vol->mount_point);
    01050         LIBHAL_PROP_EXTRACT_STRING ("volume.fstype",             vol->fstype);
    01051         LIBHAL_PROP_EXTRACT_BOOL   ("volume.is_mounted",         vol->is_mounted);
    01052         LIBHAL_PROP_EXTRACT_STRING ("volume.fsusage",            vol_fsusage_textual);
    01053
    01054         LIBHAL_PROP_EXTRACT_BOOL   ("volume.is_disc",            vol->is_disc);
    01055         LIBHAL_PROP_EXTRACT_STRING ("volume.disc.type",          disc_type_textual);
    01056         LIBHAL_PROP_EXTRACT_BOOL   ("volume.disc.has_audio",     vol->disc_has_audio);
    01057         LIBHAL_PROP_EXTRACT_BOOL   ("volume.disc.has_data",      vol->disc_has_data);
    01058         LIBHAL_PROP_EXTRACT_BOOL   ("volume.disc.is_appendable", vol->disc_is_appendable);
    01059         LIBHAL_PROP_EXTRACT_BOOL   ("volume.disc.is_blank",      vol->disc_is_blank);
    01060         LIBHAL_PROP_EXTRACT_BOOL   ("volume.disc.is_rewritable", vol->disc_is_rewritable);
    01061
    01062         LIBHAL_PROP_EXTRACT_BOOL   ("volume.policy.should_mount",        vol->should_mount);
    01063         LIBHAL_PROP_EXTRACT_STRING ("volume.policy.desired_mount_point", vol->desired_mount_point);
    01064         LIBHAL_PROP_EXTRACT_STRING ("volume.policy.mount_filesystem",    vol->mount_filesystem);
    01065
    01066         LIBHAL_PROP_EXTRACT_END;
    01067     }
    01068
    01069     if (disc_type_textual != NULL) {
    01070         if (strcmp (disc_type_textual, "cd_rom") == 0) {
    01071             vol->disc_type = LIBHAL_VOLUME_DISC_TYPE_CDROM;
    01072         } else if (strcmp (disc_type_textual, "cd_r") == 0) {
    01073             vol->disc_type = LIBHAL_VOLUME_DISC_TYPE_CDR;
    01074         } else if (strcmp (disc_type_textual, "cd_rw") == 0) {
    01075             vol->disc_type = LIBHAL_VOLUME_DISC_TYPE_CDRW;
    01076         } else if (strcmp (disc_type_textual, "dvd_rom") == 0) {
    01077             vol->disc_type = LIBHAL_VOLUME_DISC_TYPE_DVDROM;
    01078         } else if (strcmp (disc_type_textual, "dvd_ram") == 0) {
    01079             vol->disc_type = LIBHAL_VOLUME_DISC_TYPE_DVDRAM;
    01080         } else if (strcmp (disc_type_textual, "dvd_r") == 0) {
    01081             vol->disc_type = LIBHAL_VOLUME_DISC_TYPE_DVDR;
    01082         } else if (strcmp (disc_type_textual, "dvd_rw") == 0) {
    01083             vol->disc_type = LIBHAL_VOLUME_DISC_TYPE_DVDRW;
    01084         } else if (strcmp (disc_type_textual, "dvd_plus_r") == 0) {
    01085             vol->disc_type = LIBHAL_VOLUME_DISC_TYPE_DVDPLUSR;
    01086         } else if (strcmp (disc_type_textual, "dvd_plus_rw") == 0) {
    01087             vol->disc_type = LIBHAL_VOLUME_DISC_TYPE_DVDPLUSRW;
    01088         } else if (strcmp (disc_type_textual, "dvd_plus_r_dl") == 0) {
    01089             vol->disc_type = LIBHAL_VOLUME_DISC_TYPE_DVDPLUSR_DL;
    01090         }
    01091     }
    01092
    01093     if (vol_fsusage_textual != NULL) {
    01094         if (strcmp (vol_fsusage_textual, "filesystem") == 0) {
    01095             vol->fsusage = LIBHAL_VOLUME_USAGE_MOUNTABLE_FILESYSTEM;
    01096         } else if (strcmp (vol_fsusage_textual, "partitiontable") == 0) {
    01097             vol->fsusage = LIBHAL_VOLUME_USAGE_PARTITION_TABLE;
    01098         } else if (strcmp (vol_fsusage_textual, "raid") == 0) {
    01099             vol->fsusage = LIBHAL_VOLUME_USAGE_RAID_MEMBER;
    01100         } else if (strcmp (vol_fsusage_textual, "crypto") == 0) {
    01101             vol->fsusage = LIBHAL_VOLUME_USAGE_CRYPTO;
    01102         } else {
    01103             vol->fsusage = LIBHAL_VOLUME_USAGE_UNKNOWN;
    01104         }
    01105     }
    01106
    01107     libhal_free_string (vol_fsusage_textual);
    01108     libhal_free_string (disc_type_textual);
    01109     libhal_free_property_set (properties);
    01110     return vol;
    01111 error:
    01112     libhal_free_string (vol_fsusage_textual);
    01113     libhal_free_string (disc_type_textual);
    01114     libhal_free_property_set (properties);
    01115     libhal_volume_free (vol);
    01116     return NULL;
    01117 }
    01118
    01119
    01128 int
    01129 libhal_volume_get_msdos_part_table_type (LibHalVolume *volume)
    01130 {
    01131     return volume->msdos_part_table_type;
    01132 }
    01133
    01134 /***********************************************************************/
    01135
    01143 LibHalDrive *
    01144 libhal_drive_from_device_file (LibHalContext *hal_ctx, const char *device_file)
    01145 {
    01146     int i;
    01147     char **hal_udis;
    01148     int num_hal_udis;
    01149     LibHalDrive *result;
    01150     char *found_udi;
    01151     DBusError error;
    01152
    01153     LIBHAL_CHECK_LIBHALCONTEXT(hal_ctx, NULL);
    01154
    01155     result = NULL;
    01156     found_udi = NULL;
    01157
    01158     dbus_error_init (&error);
    01159     if ((hal_udis = libhal_manager_find_device_string_match (hal_ctx, "block.device",
    01160                                  device_file, &num_hal_udis, &error)) == NULL)
    01161         goto out;
    01162
    01163     for (i = 0; i < num_hal_udis; i++) {
    01164         char *udi;
    01165         char *storage_udi;
    01166         DBusError err1;
    01167         DBusError err2;
    01168         udi = hal_udis[i];
    01169
    01170         dbus_error_init (&err1);
    01171         dbus_error_init (&err2);
    01172         if (libhal_device_query_capability (hal_ctx, udi, "volume", &err1)) {
    01173
    01174             storage_udi = libhal_device_get_property_string (hal_ctx, udi, "block.storage_device", &err1);
    01175             if (storage_udi == NULL)
    01176                 continue;
    01177             found_udi = strdup (storage_udi);
    01178             libhal_free_string (storage_udi);
    01179             break;
    01180         } else if (libhal_device_query_capability (hal_ctx, udi, "storage", &err2)) {
    01181             found_udi = strdup (udi);
    01182         }
    01183     }
    01184
    01185     libhal_free_string_array (hal_udis);
    01186
    01187     if (found_udi != NULL)
    01188         result = libhal_drive_from_udi (hal_ctx, found_udi);
    01189
    01190     free (found_udi);
    01191 out:
    01192     return result;
    01193 }
    01194
    01195
    01202 LibHalVolume *
    01203 libhal_volume_from_device_file (LibHalContext *hal_ctx, const char *device_file)
    01204 {
    01205     int i;
    01206     char **hal_udis;
    01207     int num_hal_udis;
    01208     LibHalVolume *result;
    01209     char *found_udi;
    01210     DBusError error;
    01211
    01212     LIBHAL_CHECK_LIBHALCONTEXT(hal_ctx, NULL);
    01213
    01214     result = NULL;
    01215     found_udi = NULL;
    01216
    01217     dbus_error_init (&error);
    01218     if ((hal_udis = libhal_manager_find_device_string_match (hal_ctx, "block.device",
    01219                                  device_file, &num_hal_udis, &error)) == NULL)
    01220         goto out;
    01221
    01222     for (i = 0; i < num_hal_udis; i++) {
    01223         char *udi;
    01224         udi = hal_udis[i];
    01225         if (libhal_device_query_capability (hal_ctx, udi, "volume", &error)) {
    01226             found_udi = strdup (udi);
    01227             break;
    01228         }
    01229     }
    01230
    01231     libhal_free_string_array (hal_udis);
    01232
    01233     if (found_udi != NULL)
    01234         result = libhal_volume_from_udi (hal_ctx, found_udi);
    01235
    01236     free (found_udi);
    01237 out:
    01238     return result;
    01239 }
    01240
    01241 dbus_uint64_t
    01242 libhal_volume_get_size (LibHalVolume *volume)
    01243 {
    01244     return ((dbus_uint64_t)volume->block_size) * ((dbus_uint64_t)volume->num_blocks);
    01245 }
    01246
    01247
    01248 dbus_bool_t
    01249 libhal_drive_is_hotpluggable (LibHalDrive *drive)
    01250 {
    01251     return drive->is_hotpluggable;
    01252 }
    01253
    01254 dbus_bool_t
    01255 libhal_drive_uses_removable_media (LibHalDrive *drive)
    01256 {
    01257     return drive->is_removable;
    01258 }
    01259
    01260 LibHalDriveType
    01261 libhal_drive_get_type (LibHalDrive *drive)
    01262 {
    01263     return drive->type;
    01264 }
    01265
    01266 LibHalDriveBus
    01267 libhal_drive_get_bus (LibHalDrive *drive)
    01268 {
    01269     return drive->bus;
    01270 }
    01271
    01272 LibHalDriveCdromCaps
    01273 libhal_drive_get_cdrom_caps (LibHalDrive *drive)
    01274 {
    01275     return drive->cdrom_caps;
    01276 }
    01277
    01278 unsigned int
    01279 libhal_drive_get_device_major (LibHalDrive *drive)
    01280 {
    01281     return drive->device_major;
    01282 }
    01283
    01284 unsigned int
    01285 libhal_drive_get_device_minor (LibHalDrive *drive)
    01286 {
    01287     return drive->device_minor;
    01288 }
    01289
    01290 const char *
    01291 libhal_drive_get_type_textual (LibHalDrive *drive)
    01292 {
    01293     return drive->type_textual;
    01294 }
    01295
    01296 const char *
    01297 libhal_drive_get_device_file (LibHalDrive *drive)
    01298 {
    01299     return drive->device_file;
    01300 }
    01301
    01302 const char *
    01303 libhal_drive_get_udi (LibHalDrive *drive)
    01304 {
    01305     return drive->udi;
    01306 }
    01307
    01308 const char *
    01309 libhal_drive_get_serial (LibHalDrive *drive)
    01310 {
    01311     return drive->serial;
    01312 }
    01313
    01314 const char *
    01315 libhal_drive_get_firmware_version (LibHalDrive *drive)
    01316 {
    01317     return drive->firmware_version;
    01318 }
    01319
    01320 const char *
    01321 libhal_drive_get_model (LibHalDrive *drive)
    01322 {
    01323     return drive->model;
    01324 }
    01325
    01326 const char *
    01327 libhal_drive_get_vendor (LibHalDrive *drive)
    01328 {
    01329     return drive->vendor;
    01330 }
    01331
    01332 /*****************************************************************************/
    01333
    01334 const char *
    01335 libhal_volume_get_udi (LibHalVolume *volume)
    01336 {
    01337     return volume->udi;
    01338 }
    01339
    01340 const char *
    01341 libhal_volume_get_device_file (LibHalVolume *volume)
    01342 {
    01343     return volume->device_file;
    01344 }
    01345
    01346 unsigned int libhal_volume_get_device_major (LibHalVolume *volume)
    01347 {
    01348     return volume->device_major;
    01349 }
    01350
    01351 unsigned int libhal_volume_get_device_minor (LibHalVolume *volume)
    01352 {
    01353     return volume->device_minor;
    01354 }
    01355
    01356 const char *
    01357 libhal_volume_get_fstype (LibHalVolume *volume)
    01358 {
    01359     return volume->fstype;
    01360 }
    01361
    01362 const char *
    01363 libhal_volume_get_fsversion (LibHalVolume *volume)
    01364 {
    01365     return volume->fsversion;
    01366 }
    01367
    01368 LibHalVolumeUsage
    01369 libhal_volume_get_fsusage (LibHalVolume *volume)
    01370 {
    01371     return volume->fsusage;
    01372 }
    01373
    01374 dbus_bool_t
    01375 libhal_volume_is_mounted (LibHalVolume *volume)
    01376 {
    01377     return volume->is_mounted;
    01378 }
    01379
    01380 dbus_bool_t
    01381 libhal_volume_is_partition (LibHalVolume *volume)
    01382 {
    01383     return volume->is_partition;
    01384 }
    01385
    01386 dbus_bool_t
    01387 libhal_volume_is_disc (LibHalVolume *volume)
    01388 {
    01389     return volume->is_disc;
    01390 }
    01391
    01392 unsigned int
    01393 libhal_volume_get_partition_number (LibHalVolume *volume)
    01394 {
    01395     return volume->partition_number;
    01396 }
    01397
    01398 const char *
    01399 libhal_volume_get_label (LibHalVolume *volume)
    01400 {
    01401     return volume->volume_label;
    01402 }
    01403
    01404 const char *
    01405 libhal_volume_get_mount_point (LibHalVolume *volume)
    01406 {
    01407     return volume->mount_point;
    01408 }
    01409
    01410 const char *
    01411 libhal_volume_get_uuid (LibHalVolume *volume)
    01412 {
    01413     return volume->uuid;
    01414 }
    01415
    01416 dbus_bool_t
    01417 libhal_volume_disc_has_audio (LibHalVolume *volume)
    01418 {
    01419     return volume->disc_has_audio;
    01420 }
    01421
    01422 dbus_bool_t
    01423 libhal_volume_disc_has_data (LibHalVolume *volume)
    01424 {
    01425     return volume->disc_has_data;
    01426 }
    01427
    01428 dbus_bool_t
    01429 libhal_volume_disc_is_blank (LibHalVolume *volume)
    01430 {
    01431     return volume->disc_is_blank;
    01432 }
    01433
    01434 dbus_bool_t
    01435 libhal_volume_disc_is_rewritable (LibHalVolume *volume)
    01436 {
    01437     return volume->disc_is_rewritable;
    01438 }
    01439
    01440 dbus_bool_t
    01441 libhal_volume_disc_is_appendable (LibHalVolume *volume)
    01442 {
    01443     return volume->disc_is_appendable;
    01444 }
    01445
    01446 LibHalVolumeDiscType
    01447 libhal_volume_get_disc_type (LibHalVolume *volume)
    01448 {
    01449     return volume->disc_type;
    01450 }
    01451
    01452 char **
    01453 libhal_drive_find_all_volumes (LibHalContext *hal_ctx, LibHalDrive *drive, int *num_volumes)
    01454 {
    01455     int i;
    01456     char **udis;
    01457     int num_udis;
    01458     const char *drive_udi;
    01459     char **result;
    01460     DBusError error;
    01461
    01462     LIBHAL_CHECK_LIBHALCONTEXT(hal_ctx, NULL);
    01463
    01464     udis = NULL;
    01465     result = NULL;
    01466     *num_volumes = 0;
    01467
    01468     drive_udi = libhal_drive_get_udi (drive);
    01469     if (drive_udi == NULL)
    01470         goto out;
    01471
    01472     /* get initial list... */
    01473     dbus_error_init (&error);
    01474     if ((udis = libhal_manager_find_device_string_match (hal_ctx, "block.storage_device",
    01475                                  drive_udi, &num_udis, &error)) == NULL)
    01476         goto out;
    01477
    01478     result = malloc (sizeof (char *) * num_udis);
    01479     if (result == NULL)
    01480         goto out;
    01481
    01482     /* ...and filter out the single UDI that is the drive itself */
    01483     for (i = 0; i < num_udis; i++) {
    01484         if (strcmp (udis[i], drive_udi) == 0)
    01485             continue;
    01486         result[*num_volumes] = strdup (udis[i]);
    01487         *num_volumes = (*num_volumes) + 1;
    01488     }
    01489
    01490 out:
    01491     libhal_free_string_array (udis);
    01492     return result;
    01493 }
    01494
    01495 /*************************************************************************/
    01496
    01497 char *
    01498 libhal_drive_policy_default_get_mount_root (LibHalContext *hal_ctx)
    01499 {
    01500     DBusError error;
    01501
    01502     LIBHAL_CHECK_LIBHALCONTEXT(hal_ctx, NULL);
    01503
    01504     dbus_error_init (&error);
    01505     return libhal_device_get_property_string (hal_ctx, "/org/freedesktop/Hal/devices/computer",
    01506                           "storage.policy.default.mount_root", &error);
    01507 }
    01508
    01509 dbus_bool_t
    01510 libhal_drive_policy_default_use_managed_keyword (LibHalContext *hal_ctx)
    01511 {
    01512     DBusError error;
    01513
    01514     LIBHAL_CHECK_LIBHALCONTEXT(hal_ctx, FALSE);
    01515
    01516     dbus_error_init (&error);
    01517     return libhal_device_get_property_bool (hal_ctx, "/org/freedesktop/Hal/devices/computer",
    01518                         "storage.policy.default.use_managed_keyword", &error);
    01519 }
    01520
    01521 char *
    01522 libhal_drive_policy_default_get_managed_keyword_primary (LibHalContext *hal_ctx)
    01523 {
    01524     DBusError error;
    01525
    01526     LIBHAL_CHECK_LIBHALCONTEXT(hal_ctx, NULL);
    01527
    01528     dbus_error_init (&error);
    01529     return libhal_device_get_property_string (hal_ctx, "/org/freedesktop/Hal/devices/computer",
    01530                           "storage.policy.default.managed_keyword.primary", &error);
    01531 }
    01532
    01533 char *
    01534 libhal_drive_policy_default_get_managed_keyword_secondary (LibHalContext *hal_ctx)
    01535 {
    01536     DBusError error;
    01537
    01538     LIBHAL_CHECK_LIBHALCONTEXT(hal_ctx, NULL);
    01539
    01540     dbus_error_init (&error);
    01541     return libhal_device_get_property_string (hal_ctx, "/org/freedesktop/Hal/devices/computer",
    01542                           "storage.policy.default.managed_keyword.secondary", &error);
    01543 }
    01544
    01545 /*************************************************************************/
    01546
    01547 dbus_bool_t
    01548 libhal_drive_policy_is_mountable (LibHalDrive *drive, LibHalStoragePolicy *policy)
    01549 {
    01550     printf ("should_mount=%d, no_partitions_hint=%d\n", drive->should_mount, drive->no_partitions_hint);
    01551
    01552     return drive->should_mount && drive->no_partitions_hint;
    01553 }
    01554
    01555 const char *
    01556 libhal_drive_policy_get_desired_mount_point (LibHalDrive *drive, LibHalStoragePolicy *policy)
    01557 {
    01558     return drive->desired_mount_point;
    01559 }
    01560
    01561 /* safely strcat() at most the remaining space in 'dst' */
    01562 #define strcat_len(dst, src, dstmaxlen) do {    \
    01563     dst[dstmaxlen - 1] = '\0'; \
    01564     strncat (dst, src, dstmaxlen - strlen (dst) - 1); \
    01565 } while(0)
    01566
    01567
    01568 static void
    01569 mopts_collect (LibHalContext *hal_ctx, const char *namespace, int namespace_len,
    01570            const char *udi, char *options_string, size_t options_max_len, dbus_bool_t only_collect_imply_opts)
    01571 {
    01572     LibHalPropertySet *properties;
    01573     LibHalPropertySetIterator it;
    01574     DBusError error;
    01575
    01576     if(hal_ctx == 0) {
    01577         fprintf (stderr,"%s %d : LibHalContext *ctx is NULL\n",__FILE__, __LINE__);
    01578         return;
    01579     }
    01580
    01581     dbus_error_init (&error);
    01582
    01583     /* first collect from root computer device */
    01584     properties = libhal_device_get_all_properties (hal_ctx, udi, &error);
    01585     if (properties == NULL)
    01586         goto error;
    01587     for (libhal_psi_init (&it, properties); libhal_psi_has_more (&it); libhal_psi_next (&it)) {
    01588         int type;
    01589         char *key;
    01590
    01591         type = libhal_psi_get_type (&it);
    01592         key = libhal_psi_get_key (&it);
    01593         if (libhal_psi_get_type (&it) == LIBHAL_PROPERTY_TYPE_BOOLEAN &&
    01594             strncmp (key, namespace, namespace_len - 1) == 0) {
    01595             const char *option = key + namespace_len - 1;
    01596             char *location;
    01597             dbus_bool_t is_imply_opt;
    01598
    01599             is_imply_opt = FALSE;
    01600             if (strcmp (option, "user") == 0 ||
    01601                 strcmp (option, "users") == 0 ||
    01602                 strcmp (option, "defaults") == 0 ||
    01603                 strcmp (option, "pamconsole") == 0)
    01604                 is_imply_opt = TRUE;
    01605
    01606
    01607             if (only_collect_imply_opts) {
    01608                 if (!is_imply_opt)
    01609                     continue;
    01610             } else {
    01611                 if (is_imply_opt)
    01612                     continue;
    01613             }
    01614
    01615             if (libhal_psi_get_bool (&it)) {
    01616                 /* see if option is already there */
    01617                 location = strstr (options_string, option);
    01618                 if (location == NULL) {
    01619                     if (strlen (options_string) > 0)
    01620                         strcat_len (options_string, ",", options_max_len);
    01621                     strcat_len (options_string, option, options_max_len);
    01622                 }
    01623             } else {
    01624                 /* remove option if already there */
    01625                 location = strstr (options_string, option);
    01626                 if (location != NULL) {
    01627                     char *end;
    01628
    01629                     end = strchr (location, ',');
    01630                     if (end == NULL) {
    01631                         location[0] = '\0';
    01632                     } else {
    01633                         strcpy (location, end + 1); /* skip the extra comma */
    01634                     }
    01635                 }
    01636
    01637             }
    01638         }
    01639     }
    01640 error:
    01641     libhal_free_property_set (properties);
    01642 }
    01643
    01644
    01645 const char *
    01646 libhal_drive_policy_get_mount_options (LibHalDrive *drive, LibHalStoragePolicy *policy)
    01647 {
    01648     const char *result;
    01649     char stor_mount_option_default_begin[] = "storage.policy.default.mount_option.";
    01650     char stor_mount_option_begin[] = "storage.policy.mount_option.";
    01651
    01652     result = NULL;
    01653     drive->mount_options[0] = '\0';
    01654
    01655     /* collect options != ('pamconsole', 'user', 'users', 'defaults' options that imply other options)  */
    01656     mopts_collect (drive->hal_ctx, stor_mount_option_default_begin, sizeof (stor_mount_option_default_begin),
    01657                "/org/freedesktop/Hal/devices/computer", drive->mount_options, MOUNT_OPTIONS_SIZE, TRUE);
    01658     mopts_collect (drive->hal_ctx, stor_mount_option_begin, sizeof (stor_mount_option_begin),
    01659                drive->udi, drive->mount_options, MOUNT_OPTIONS_SIZE, TRUE);
    01660     /* ensure ('pamconsole', 'user', 'users', 'defaults' options that imply other options), are first */
    01661     mopts_collect (drive->hal_ctx, stor_mount_option_default_begin, sizeof (stor_mount_option_default_begin),
    01662                "/org/freedesktop/Hal/devices/computer", drive->mount_options, MOUNT_OPTIONS_SIZE, FALSE);
    01663     mopts_collect (drive->hal_ctx, stor_mount_option_begin, sizeof (stor_mount_option_begin),
    01664                drive->udi, drive->mount_options, MOUNT_OPTIONS_SIZE, FALSE);
    01665
    01666     result = drive->mount_options;
    01667
    01668     return result;
    01669 }
    01670
    01671 const char *
    01672 libhal_drive_policy_get_mount_fs (LibHalDrive *drive, LibHalStoragePolicy *policy)
    01673 {
    01674     return drive->mount_filesystem;
    01675 }
    01676
    01677
    01678 dbus_bool_t
    01679 libhal_volume_policy_is_mountable (LibHalDrive *drive, LibHalVolume *volume, LibHalStoragePolicy *policy)
    01680 {
    01681     return drive->should_mount && volume->should_mount;
    01682 }
    01683
    01684 const char *libhal_volume_policy_get_desired_mount_point (LibHalDrive *drive, LibHalVolume *volume, LibHalStoragePolicy *policy)
    01685 {
    01686     return volume->desired_mount_point;
    01687 }
    01688
    01689 const char *libhal_volume_policy_get_mount_options (LibHalDrive *drive, LibHalVolume *volume, LibHalStoragePolicy *policy)
    01690 {
    01691     const char *result;
    01692     char stor_mount_option_default_begin[] = "storage.policy.default.mount_option.";
    01693     char vol_mount_option_begin[] = "volume.policy.mount_option.";
    01694
    01695     result = NULL;
    01696     volume->mount_options[0] = '\0';
    01697
    01698     /* ensure ('pamconsole', 'user', 'users', 'defaults' options that imply other options), are first */
    01699     mopts_collect (drive->hal_ctx, stor_mount_option_default_begin, sizeof (stor_mount_option_default_begin),
    01700                "/org/freedesktop/Hal/devices/computer", volume->mount_options, MOUNT_OPTIONS_SIZE, TRUE);
    01701     mopts_collect (drive->hal_ctx, vol_mount_option_begin, sizeof (vol_mount_option_begin),
    01702                volume->udi, volume->mount_options, MOUNT_OPTIONS_SIZE, TRUE);
    01703     /* collect options != ('pamconsole', 'user', 'users', 'defaults' options that imply other options)  */
    01704     mopts_collect (drive->hal_ctx, stor_mount_option_default_begin, sizeof (stor_mount_option_default_begin),
    01705                "/org/freedesktop/Hal/devices/computer", volume->mount_options, MOUNT_OPTIONS_SIZE, FALSE);
    01706     mopts_collect (drive->hal_ctx, vol_mount_option_begin, sizeof (vol_mount_option_begin),
    01707                volume->udi, volume->mount_options, MOUNT_OPTIONS_SIZE, FALSE);
    01708
    01709     result = volume->mount_options;
    01710
    01711     return result;
    01712 }
    01713
    01714 const char *libhal_volume_policy_get_mount_fs (LibHalDrive *drive, LibHalVolume *volume, LibHalStoragePolicy *policy)
    01715 {
    01716     return volume->mount_filesystem;
    01717 }
    01718
    01719 dbus_bool_t
    01720 libhal_drive_no_partitions_hint (LibHalDrive *drive)
    01721 {
    01722     return drive->no_partitions_hint;
    01723 }
    01724