libhal-storage.c

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

Generated on Fri Jun 16 18:03:41 2006 for HAL by  doxygen 1.4.6