libhal-storage.c

00001 /***************************************************************************
00002  * CVSID: $Id: libhal-storage.c,v 1.24 2005/11/02 15:38:14 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.1
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 
00071 typedef struct IconMappingEntry_s {
00072     LibHalStoragePolicyIcon icon;
00073     char *path;
00074     struct IconMappingEntry_s *next;
00075 } IconMappingEntry;
00076 
00077 struct LibHalStoragePolicy_s {
00078     IconMappingEntry *icon_mappings;
00079 };
00080 
00081 LibHalStoragePolicy *
00082 libhal_storage_policy_new ()
00083 {
00084     LibHalStoragePolicy *p;
00085 
00086     p = malloc (sizeof (LibHalStoragePolicy));
00087     if (p == NULL)
00088         goto out;
00089 
00090     p->icon_mappings = NULL;
00091 out:
00092     return p;
00093 }
00094 
00095 void
00096 libhal_storage_policy_free (LibHalStoragePolicy *policy)
00097 {
00098     IconMappingEntry *i;
00099     IconMappingEntry *j;
00100 
00101     /* free all icon mappings */
00102     for (i = policy->icon_mappings; i != NULL; i = j) {
00103         j = i->next;
00104         free (i->path);
00105         free (i);
00106     }
00107 
00108     free (policy);
00109 }
00110 
00111 void
00112 libhal_storage_policy_set_icon_path (LibHalStoragePolicy *policy, LibHalStoragePolicyIcon icon, const char *path)
00113 {
00114     IconMappingEntry *i;
00115 
00116     /* see if it already exist */
00117     for (i = policy->icon_mappings; i != NULL; i = i->next) {
00118         if (i->icon == icon) {
00119             free (i->path);
00120             i->path = strdup (path);
00121             goto out;
00122         }
00123     }
00124 
00125     i = malloc (sizeof (IconMappingEntry));
00126     if (i == NULL)
00127         goto out;
00128     i->icon = icon;
00129     i->path = strdup (path);
00130     i->next = policy->icon_mappings;
00131     policy->icon_mappings = i;
00132 
00133 out:
00134     return;
00135 }
00136 
00137 void
00138 libhal_storage_policy_set_icon_mapping (LibHalStoragePolicy *policy, LibHalStoragePolicyIconPair *pairs)
00139 {
00140     LibHalStoragePolicyIconPair *i;
00141 
00142     for (i = pairs; i->icon != 0x00; i++) {
00143         libhal_storage_policy_set_icon_path (policy, i->icon, i->icon_path);
00144     }
00145 }
00146 
00147 const char *
00148 libhal_storage_policy_lookup_icon (LibHalStoragePolicy *policy, LibHalStoragePolicyIcon icon)
00149 {
00150     IconMappingEntry *i;
00151     const char *path;
00152 
00153     path = NULL;
00154     for (i = policy->icon_mappings; i != NULL; i = i->next) {
00155         if (i->icon == icon) {
00156             path = i->path;
00157             goto out;
00158         }
00159     }
00160 out:
00161     return path;
00162 }
00163 
00164 
00165 #define MAX_STRING_SZ 256
00166 
00167 char *
00168 libhal_volume_policy_compute_size_as_string (LibHalVolume *volume)
00169 {
00170     dbus_uint64_t size;
00171     char *result;
00172     char* sizes_str[] = {"K", "M", "G", "T", NULL};
00173     dbus_uint64_t cur = 1000L;
00174     dbus_uint64_t base = 10L;
00175     dbus_uint64_t step = 10L*10L*10L;
00176     int cur_str = 0;
00177     char buf[MAX_STRING_SZ];
00178 
00179     result = NULL;
00180 
00181     size = libhal_volume_get_size (volume);
00182 
00183     do {
00184         if (sizes_str[cur_str+1] == NULL || size < cur*step) {
00185             /* found the unit, display a comma number if result is a single digit */
00186             if (size < cur*base) {
00187                 snprintf (buf, MAX_STRING_SZ, "%.01f%s", 
00188                       ((double)size)/((double)cur), sizes_str[cur_str]);
00189                 result = strdup (buf);
00190             } else {
00191                 snprintf (buf, MAX_STRING_SZ, "%lld%s", size / cur, sizes_str[cur_str]);
00192                 result = strdup (buf);
00193                 }
00194             goto out;
00195         }
00196 
00197         cur *= step;
00198         cur_str++;
00199     } while (1);
00200 
00201 out:
00202     return result;
00203 }
00204 
00205 static void
00206 fixup_string (char *s)
00207 {
00208     /* TODO: first strip leading and trailing whitespace */
00209     /*g_strstrip (s);*/
00210 
00211     /* TODO: could do nice things on all-upper case strings */
00212 }
00213 
00214 /* volume may be NULL (e.g. if drive supports removable media) */
00215 char *
00216 libhal_drive_policy_compute_display_name (LibHalDrive *drive, LibHalVolume *volume, LibHalStoragePolicy *policy)
00217 {
00218     char *name;
00219     char *size_str;
00220     char *vendormodel_str;
00221     const char *model;
00222     const char *vendor;
00223     LibHalDriveType drive_type;
00224     dbus_bool_t drive_is_hotpluggable;
00225     dbus_bool_t drive_is_removable;
00226     LibHalDriveCdromCaps drive_cdrom_caps;
00227     char buf[MAX_STRING_SZ];
00228 
00229     model = libhal_drive_get_model (drive);
00230     vendor = libhal_drive_get_vendor (drive);
00231     drive_type = libhal_drive_get_type (drive);
00232     drive_is_hotpluggable = libhal_drive_is_hotpluggable (drive);
00233     drive_is_removable = libhal_drive_uses_removable_media (drive);
00234     drive_cdrom_caps = libhal_drive_get_cdrom_caps (drive);
00235 
00236     if (volume != NULL)
00237         size_str = libhal_volume_policy_compute_size_as_string (volume);
00238     else
00239         size_str = NULL;
00240 
00241     if (vendor == NULL || strlen (vendor) == 0) {
00242         if (model == NULL || strlen (model) == 0)
00243             vendormodel_str = strdup ("");
00244         else
00245             vendormodel_str = strdup (model);
00246     } else {
00247         if (model == NULL || strlen (model) == 0)
00248             vendormodel_str = strdup (vendor);
00249         else {
00250             snprintf (buf, MAX_STRING_SZ, "%s %s", vendor, model);
00251             vendormodel_str = strdup (buf);
00252         }
00253     }
00254 
00255     fixup_string (vendormodel_str);
00256 
00257     if (drive_type==LIBHAL_DRIVE_TYPE_CDROM) {
00258 
00259         /* Optical drive handling */
00260         char *first;
00261         char *second;
00262 
00263 
00264         first = "CD-ROM";
00265         if (drive_cdrom_caps & LIBHAL_DRIVE_CDROM_CAPS_CDR)
00266             first = "CD-R";
00267         if (drive_cdrom_caps & LIBHAL_DRIVE_CDROM_CAPS_CDRW)
00268             first = "CD-RW";
00269 
00270         second = "";
00271         if (drive_cdrom_caps & LIBHAL_DRIVE_CDROM_CAPS_DVDROM)
00272             second = "/DVD-ROM";
00273         if (drive_cdrom_caps & LIBHAL_DRIVE_CDROM_CAPS_DVDPLUSR)
00274             second = "/DVD+R";
00275         if (drive_cdrom_caps & LIBHAL_DRIVE_CDROM_CAPS_DVDPLUSRW)
00276             second = "/DVD+RW";
00277         if (drive_cdrom_caps & LIBHAL_DRIVE_CDROM_CAPS_DVDR)
00278             second = "/DVD-R";
00279         if (drive_cdrom_caps & LIBHAL_DRIVE_CDROM_CAPS_DVDRW)
00280             second = "/DVD-RW";
00281         if (drive_cdrom_caps & LIBHAL_DRIVE_CDROM_CAPS_DVDRAM)
00282             second = "/DVD-RAM";
00283         if ((drive_cdrom_caps & LIBHAL_DRIVE_CDROM_CAPS_DVDR) &&
00284             (drive_cdrom_caps & LIBHAL_DRIVE_CDROM_CAPS_DVDPLUSR)) {
00285             if(drive_cdrom_caps & LIBHAL_DRIVE_CDROM_CAPS_DVDPLUSRDL)
00286                 second = "/DVD±R DL";
00287             else
00288                 second = "/DVD±R";
00289         }
00290         if ((drive_cdrom_caps & LIBHAL_DRIVE_CDROM_CAPS_DVDRW) &&
00291             (drive_cdrom_caps & LIBHAL_DRIVE_CDROM_CAPS_DVDPLUSRW)) {
00292                         if(drive_cdrom_caps & LIBHAL_DRIVE_CDROM_CAPS_DVDPLUSRDL)
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 
00702     dbus_bool_t is_disc;
00703     LibHalVolumeDiscType disc_type;
00704     dbus_bool_t disc_has_audio;
00705     dbus_bool_t disc_has_data;
00706     dbus_bool_t disc_is_appendable;
00707     dbus_bool_t disc_is_blank;
00708     dbus_bool_t disc_is_rewritable;
00709 
00710     unsigned int block_size;
00711     unsigned int num_blocks;
00712 
00713     char *desired_mount_point;
00714     char *mount_filesystem;
00715     dbus_bool_t should_mount;
00716 
00717     char mount_options[MOUNT_OPTIONS_SIZE];
00718 };
00719 
00720 const char *
00721 libhal_drive_get_dedicated_icon_drive (LibHalDrive *drive)
00722 {
00723     return drive->dedicated_icon_drive;
00724 }
00725 
00726 const char *
00727 libhal_drive_get_dedicated_icon_volume (LibHalDrive *drive)
00728 {
00729     return drive->dedicated_icon_volume;
00730 }
00731 
00736 void
00737 libhal_drive_free (LibHalDrive *drive)
00738 {
00739     if (drive == NULL )
00740         return;
00741 
00742     free (drive->udi);
00743     libhal_free_string (drive->device_file);
00744     libhal_free_string (drive->vendor);
00745     libhal_free_string (drive->model);
00746     libhal_free_string (drive->type_textual);
00747     libhal_free_string (drive->physical_device);
00748     libhal_free_string (drive->serial);
00749     libhal_free_string (drive->firmware_version);
00750     libhal_free_string (drive->desired_mount_point);
00751     libhal_free_string (drive->mount_filesystem);
00752     libhal_free_string_array (drive->capabilities);
00753 }
00754 
00755 
00760 void
00761 libhal_volume_free (LibHalVolume *vol)
00762 {
00763     if (vol == NULL )
00764         return;
00765 
00766     free (vol->udi);
00767     libhal_free_string (vol->device_file);
00768     libhal_free_string (vol->volume_label);
00769     libhal_free_string (vol->fstype);
00770     libhal_free_string (vol->mount_point);
00771     libhal_free_string (vol->fsversion);
00772     libhal_free_string (vol->uuid);
00773     libhal_free_string (vol->desired_mount_point);
00774     libhal_free_string (vol->mount_filesystem);
00775 }
00776 
00777 
00778 static char **
00779 my_strvdup (char **strv)
00780 {
00781     unsigned int num_elems;
00782     unsigned int i;
00783     char **res;
00784 
00785     for (num_elems = 0; strv[num_elems] != NULL; num_elems++)
00786         ;
00787 
00788     res = calloc (num_elems + 1, sizeof (char*));
00789     if (res == NULL)
00790         goto out;
00791 
00792     for (i = 0; i < num_elems; i++)
00793         res[i] = strdup (strv[i]);
00794     res[i] = NULL;
00795 
00796 out:
00797     return res;
00798 }
00799 
00800 /* ok, hey, so this is a bit ugly */
00801 
00802 #define LIBHAL_PROP_EXTRACT_BEGIN if (FALSE)
00803 #define LIBHAL_PROP_EXTRACT_END ;
00804 #define LIBHAL_PROP_EXTRACT_INT(_property_, _where_) else if (strcmp (key, _property_) == 0 && type == LIBHAL_PROPERTY_TYPE_INT32) _where_ = libhal_psi_get_int (&it)
00805 #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
00806 #define LIBHAL_PROP_EXTRACT_BOOL(_property_, _where_) else if (strcmp (key, _property_) == 0 && type == LIBHAL_PROPERTY_TYPE_BOOLEAN) _where_ = libhal_psi_get_bool (&it)
00807 #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
00808 #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))
00809 
00818 LibHalDrive *
00819 libhal_drive_from_udi (LibHalContext *hal_ctx, const char *udi)
00820 {   
00821     char *bus_textual;
00822     LibHalDrive *drive;
00823     LibHalPropertySet *properties;
00824     LibHalPropertySetIterator it;
00825     DBusError error;
00826     unsigned int i;
00827 
00828     LIBHAL_CHECK_LIBHALCONTEXT(hal_ctx, NULL);
00829 
00830     drive = NULL;
00831     properties = NULL;
00832     bus_textual = NULL;
00833 
00834     dbus_error_init (&error);
00835     if (!libhal_device_query_capability (hal_ctx, udi, "storage", &error))
00836         goto error;
00837 
00838     drive = malloc (sizeof (LibHalDrive));
00839     if (drive == NULL)
00840         goto error;
00841     memset (drive, 0x00, sizeof (LibHalDrive));
00842 
00843     drive->hal_ctx = hal_ctx;
00844 
00845     drive->udi = strdup (udi);
00846     if (drive->udi == NULL)
00847         goto error;
00848 
00849     properties = libhal_device_get_all_properties (hal_ctx, udi, &error);
00850     if (properties == NULL)
00851         goto error;
00852 
00853     /* we can count on hal to give us all these properties */
00854     for (libhal_psi_init (&it, properties); libhal_psi_has_more (&it); libhal_psi_next (&it)) {
00855         int type;
00856         char *key;
00857         
00858         type = libhal_psi_get_type (&it);
00859         key = libhal_psi_get_key (&it);
00860 
00861         LIBHAL_PROP_EXTRACT_BEGIN;
00862 
00863         LIBHAL_PROP_EXTRACT_INT    ("block.minor",               drive->device_minor);
00864         LIBHAL_PROP_EXTRACT_INT    ("block.major",               drive->device_major);
00865         LIBHAL_PROP_EXTRACT_STRING ("block.device",              drive->device_file);
00866         LIBHAL_PROP_EXTRACT_STRING ("storage.bus",               bus_textual);
00867         LIBHAL_PROP_EXTRACT_STRING ("storage.vendor",            drive->vendor);
00868         LIBHAL_PROP_EXTRACT_STRING ("storage.model",             drive->model);
00869         LIBHAL_PROP_EXTRACT_STRING ("storage.drive_type",        drive->type_textual);
00870 
00871 
00872         LIBHAL_PROP_EXTRACT_STRING ("storage.icon.drive",        drive->dedicated_icon_drive);
00873         LIBHAL_PROP_EXTRACT_STRING ("storage.icon.volume",       drive->dedicated_icon_volume);
00874 
00875         LIBHAL_PROP_EXTRACT_BOOL   ("storage.hotpluggable",      drive->is_hotpluggable);
00876         LIBHAL_PROP_EXTRACT_BOOL   ("storage.removable",         drive->is_removable);
00877         LIBHAL_PROP_EXTRACT_BOOL   ("storage.requires_eject",    drive->requires_eject);
00878 
00879         LIBHAL_PROP_EXTRACT_STRING ("storage.physical_device",   drive->physical_device);
00880         LIBHAL_PROP_EXTRACT_STRING ("storage.firmware_version",  drive->firmware_version);
00881         LIBHAL_PROP_EXTRACT_STRING ("storage.serial",            drive->serial);
00882 
00883         LIBHAL_PROP_EXTRACT_BOOL_BITFIELD ("storage.cdrom.cdr", drive->cdrom_caps, LIBHAL_DRIVE_CDROM_CAPS_CDR);
00884         LIBHAL_PROP_EXTRACT_BOOL_BITFIELD ("storage.cdrom.cdrw", drive->cdrom_caps, LIBHAL_DRIVE_CDROM_CAPS_CDRW);
00885         LIBHAL_PROP_EXTRACT_BOOL_BITFIELD ("storage.cdrom.dvd", drive->cdrom_caps, LIBHAL_DRIVE_CDROM_CAPS_DVDROM);
00886         LIBHAL_PROP_EXTRACT_BOOL_BITFIELD ("storage.cdrom.dvdplusr", drive->cdrom_caps, LIBHAL_DRIVE_CDROM_CAPS_DVDPLUSR);
00887         LIBHAL_PROP_EXTRACT_BOOL_BITFIELD ("storage.cdrom.dvdplusrw", drive->cdrom_caps, LIBHAL_DRIVE_CDROM_CAPS_DVDPLUSRW);
00888         LIBHAL_PROP_EXTRACT_BOOL_BITFIELD ("storage.cdrom.dvdplusrdl", drive->cdrom_caps, LIBHAL_DRIVE_CDROM_CAPS_DVDPLUSRDL);
00889         LIBHAL_PROP_EXTRACT_BOOL_BITFIELD ("storage.cdrom.dvdr", drive->cdrom_caps, LIBHAL_DRIVE_CDROM_CAPS_DVDR);
00890         LIBHAL_PROP_EXTRACT_BOOL_BITFIELD ("storage.cdrom.dvdrw", drive->cdrom_caps, LIBHAL_DRIVE_CDROM_CAPS_DVDRW);
00891         LIBHAL_PROP_EXTRACT_BOOL_BITFIELD ("storage.cdrom.dvdram", drive->cdrom_caps, LIBHAL_DRIVE_CDROM_CAPS_DVDRAM);
00892 
00893         LIBHAL_PROP_EXTRACT_BOOL   ("storage.policy.should_mount",        drive->should_mount);
00894         LIBHAL_PROP_EXTRACT_STRING ("storage.policy.desired_mount_point", drive->desired_mount_point);
00895         LIBHAL_PROP_EXTRACT_STRING ("storage.policy.mount_filesystem",    drive->mount_filesystem);
00896 
00897         LIBHAL_PROP_EXTRACT_BOOL   ("storage.no_partitions_hint",        drive->no_partitions_hint);
00898 
00899         LIBHAL_PROP_EXTRACT_STRLIST ("info.capabilities",                drive->capabilities);
00900 
00901         LIBHAL_PROP_EXTRACT_END;
00902     }
00903 
00904     if (drive->type_textual != NULL) {
00905         if (strcmp (drive->type_textual, "cdrom") == 0) {
00906             drive->cdrom_caps |= LIBHAL_DRIVE_CDROM_CAPS_CDROM;
00907             drive->type = LIBHAL_DRIVE_TYPE_CDROM;
00908         } else if (strcmp (drive->type_textual, "floppy") == 0) {
00909             drive->type = LIBHAL_DRIVE_TYPE_FLOPPY;
00910         } else if (strcmp (drive->type_textual, "disk") == 0) {
00911             if (drive->is_removable)
00912                 drive->type = LIBHAL_DRIVE_TYPE_REMOVABLE_DISK;
00913             else
00914                 drive->type = LIBHAL_DRIVE_TYPE_DISK;               
00915         } else if (strcmp (drive->type_textual, "tape") == 0) {
00916             drive->type = LIBHAL_DRIVE_TYPE_TAPE;
00917         } else if (strcmp (drive->type_textual, "compact_flash") == 0) {
00918             drive->type = LIBHAL_DRIVE_TYPE_COMPACT_FLASH;
00919         } else if (strcmp (drive->type_textual, "memory_stick") == 0) {
00920             drive->type = LIBHAL_DRIVE_TYPE_MEMORY_STICK;
00921         } else if (strcmp (drive->type_textual, "smart_media") == 0) {
00922             drive->type = LIBHAL_DRIVE_TYPE_SMART_MEDIA;
00923         } else if (strcmp (drive->type_textual, "sd_mmc") == 0) {
00924             drive->type = LIBHAL_DRIVE_TYPE_SD_MMC;
00925         } else if (strcmp (drive->type_textual, "zip") == 0) {
00926             drive->type = LIBHAL_DRIVE_TYPE_ZIP;
00927         } else if (strcmp (drive->type_textual, "jaz") == 0) {
00928             drive->type = LIBHAL_DRIVE_TYPE_JAZ;
00929         } else if (strcmp (drive->type_textual, "flashkey") == 0) {
00930             drive->type = LIBHAL_DRIVE_TYPE_FLASHKEY;
00931         } else {
00932                 drive->type = LIBHAL_DRIVE_TYPE_DISK; 
00933         }
00934 
00935     }
00936 
00937     if (drive->capabilities != NULL) {
00938         for (i = 0; drive->capabilities[i] != NULL; i++) {
00939             if (strcmp (drive->capabilities[i], "portable_audio_player") == 0) {
00940                 drive->type = LIBHAL_DRIVE_TYPE_PORTABLE_AUDIO_PLAYER;
00941                 break;
00942             } else if (strcmp (drive->capabilities[i], "camera") == 0) {
00943                 drive->type = LIBHAL_DRIVE_TYPE_CAMERA;
00944                 break;
00945             }
00946         }
00947     }
00948 
00949     if (bus_textual != NULL) {
00950         if (strcmp (bus_textual, "usb") == 0) {
00951             drive->bus = LIBHAL_DRIVE_BUS_USB;
00952         } else if (strcmp (bus_textual, "ieee1394") == 0) {
00953             drive->bus = LIBHAL_DRIVE_BUS_IEEE1394;
00954         } else if (strcmp (bus_textual, "ide") == 0) {
00955             drive->bus = LIBHAL_DRIVE_BUS_IDE;
00956         } else if (strcmp (bus_textual, "scsi") == 0) {
00957             drive->bus = LIBHAL_DRIVE_BUS_SCSI;
00958         } else if (strcmp (bus_textual, "ccw") == 0) {
00959             drive->bus = LIBHAL_DRIVE_BUS_CCW;
00960         }
00961     }
00962 
00963     libhal_free_string (bus_textual);
00964     libhal_free_property_set (properties);
00965 
00966     return drive;
00967 
00968 error:
00969     libhal_free_string (bus_textual);
00970     libhal_free_property_set (properties);
00971     libhal_drive_free (drive);
00972     return NULL;
00973 }
00974 
00975 const char *
00976 libhal_volume_get_storage_device_udi (LibHalVolume *volume)
00977 {
00978     return volume->storage_device;
00979 }
00980 
00981 const char *libhal_drive_get_physical_device_udi (LibHalDrive *drive)
00982 {
00983     return drive->physical_device;
00984 }
00985 
00986 dbus_bool_t
00987 libhal_drive_requires_eject (LibHalDrive *drive)
00988 {
00989     return drive->requires_eject;
00990 }
00991 
01000 LibHalVolume *
01001 libhal_volume_from_udi (LibHalContext *hal_ctx, const char *udi)
01002 {
01003     char *disc_type_textual;
01004     char *vol_fsusage_textual;
01005     LibHalVolume *vol;
01006     LibHalPropertySet *properties;
01007     LibHalPropertySetIterator it;
01008     DBusError error;
01009 
01010     LIBHAL_CHECK_LIBHALCONTEXT(hal_ctx, NULL);
01011 
01012     vol = NULL;
01013     properties = NULL;
01014     disc_type_textual = NULL;
01015     vol_fsusage_textual = NULL;
01016 
01017     dbus_error_init (&error);
01018     if (!libhal_device_query_capability (hal_ctx, udi, "volume", &error))
01019         goto error;
01020 
01021     vol = malloc (sizeof (LibHalVolume));
01022     if (vol == NULL)
01023         goto error;
01024     memset (vol, 0x00, sizeof (LibHalVolume));
01025 
01026     vol->udi = strdup (udi);
01027 
01028     properties = libhal_device_get_all_properties (hal_ctx, udi, &error);
01029     if (properties == NULL)
01030         goto error;
01031 
01032     /* we can count on hal to give us all these properties */
01033     for (libhal_psi_init (&it, properties); libhal_psi_has_more (&it); libhal_psi_next (&it)) {
01034         int type;
01035         char *key;
01036         
01037         type = libhal_psi_get_type (&it);
01038         key = libhal_psi_get_key (&it);
01039 
01040         LIBHAL_PROP_EXTRACT_BEGIN;
01041 
01042         LIBHAL_PROP_EXTRACT_INT    ("volume.partition.msdos_part_table_type", vol->msdos_part_table_type);
01043 
01044         LIBHAL_PROP_EXTRACT_INT    ("block.minor",               vol->device_minor);
01045         LIBHAL_PROP_EXTRACT_INT    ("block.major",               vol->device_major);
01046         LIBHAL_PROP_EXTRACT_STRING ("block.device",              vol->device_file);
01047 
01048         LIBHAL_PROP_EXTRACT_STRING ("block.storage_device",      vol->storage_device);
01049 
01050         LIBHAL_PROP_EXTRACT_INT    ("volume.block_size",         vol->block_size);
01051         LIBHAL_PROP_EXTRACT_INT    ("volume.num_blocks",         vol->num_blocks);
01052         LIBHAL_PROP_EXTRACT_STRING ("volume.label",              vol->volume_label);
01053         LIBHAL_PROP_EXTRACT_STRING ("volume.mount_point",        vol->mount_point);
01054         LIBHAL_PROP_EXTRACT_STRING ("volume.fstype",             vol->fstype);
01055         LIBHAL_PROP_EXTRACT_BOOL   ("volume.is_mounted",         vol->is_mounted);
01056         LIBHAL_PROP_EXTRACT_STRING ("volume.fsusage",            vol_fsusage_textual);
01057 
01058         LIBHAL_PROP_EXTRACT_BOOL   ("volume.is_disc",            vol->is_disc);
01059         LIBHAL_PROP_EXTRACT_STRING ("volume.disc.type",          disc_type_textual);
01060         LIBHAL_PROP_EXTRACT_BOOL   ("volume.disc.has_audio",     vol->disc_has_audio);
01061         LIBHAL_PROP_EXTRACT_BOOL   ("volume.disc.has_data",      vol->disc_has_data);
01062         LIBHAL_PROP_EXTRACT_BOOL   ("volume.disc.is_appendable", vol->disc_is_appendable);
01063         LIBHAL_PROP_EXTRACT_BOOL   ("volume.disc.is_blank",      vol->disc_is_blank);
01064         LIBHAL_PROP_EXTRACT_BOOL   ("volume.disc.is_rewritable", vol->disc_is_rewritable);
01065 
01066         LIBHAL_PROP_EXTRACT_BOOL   ("volume.policy.should_mount",        vol->should_mount);
01067         LIBHAL_PROP_EXTRACT_STRING ("volume.policy.desired_mount_point", vol->desired_mount_point);
01068         LIBHAL_PROP_EXTRACT_STRING ("volume.policy.mount_filesystem",    vol->mount_filesystem);
01069 
01070         LIBHAL_PROP_EXTRACT_END;
01071     }
01072 
01073     if (disc_type_textual != NULL) {
01074         if (strcmp (disc_type_textual, "cd_rom") == 0) {
01075             vol->disc_type = LIBHAL_VOLUME_DISC_TYPE_CDROM;
01076         } else if (strcmp (disc_type_textual, "cd_r") == 0) {
01077             vol->disc_type = LIBHAL_VOLUME_DISC_TYPE_CDR;
01078         } else if (strcmp (disc_type_textual, "cd_rw") == 0) {
01079             vol->disc_type = LIBHAL_VOLUME_DISC_TYPE_CDRW;
01080         } else if (strcmp (disc_type_textual, "dvd_rom") == 0) {
01081             vol->disc_type = LIBHAL_VOLUME_DISC_TYPE_DVDROM;
01082         } else if (strcmp (disc_type_textual, "dvd_ram") == 0) {
01083             vol->disc_type = LIBHAL_VOLUME_DISC_TYPE_DVDRAM;
01084         } else if (strcmp (disc_type_textual, "dvd_r") == 0) {
01085             vol->disc_type = LIBHAL_VOLUME_DISC_TYPE_DVDR;
01086         } else if (strcmp (disc_type_textual, "dvd_rw") == 0) {
01087             vol->disc_type = LIBHAL_VOLUME_DISC_TYPE_DVDRW;
01088         } else if (strcmp (disc_type_textual, "dvd_plus_r") == 0) {
01089             vol->disc_type = LIBHAL_VOLUME_DISC_TYPE_DVDPLUSR;
01090         } else if (strcmp (disc_type_textual, "dvd_plus_rw") == 0) {
01091             vol->disc_type = LIBHAL_VOLUME_DISC_TYPE_DVDPLUSRW;
01092         } else if (strcmp (disc_type_textual, "dvd_plus_r_dl") == 0) {
01093             vol->disc_type = LIBHAL_VOLUME_DISC_TYPE_DVDPLUSR_DL;
01094         }
01095     }
01096 
01097     if (vol_fsusage_textual != NULL) {
01098         if (strcmp (vol_fsusage_textual, "filesystem") == 0) {
01099             vol->fsusage = LIBHAL_VOLUME_USAGE_MOUNTABLE_FILESYSTEM;
01100         } else if (strcmp (vol_fsusage_textual, "partitiontable") == 0) {
01101             vol->fsusage = LIBHAL_VOLUME_USAGE_PARTITION_TABLE;
01102         } else if (strcmp (vol_fsusage_textual, "raid") == 0) {
01103             vol->fsusage = LIBHAL_VOLUME_USAGE_RAID_MEMBER;
01104         } else if (strcmp (vol_fsusage_textual, "crypto") == 0) {
01105             vol->fsusage = LIBHAL_VOLUME_USAGE_CRYPTO;
01106         } else {
01107             vol->fsusage = LIBHAL_VOLUME_USAGE_UNKNOWN;
01108         } 
01109     }
01110 
01111     libhal_free_string (vol_fsusage_textual);
01112     libhal_free_string (disc_type_textual);
01113     libhal_free_property_set (properties);
01114     return vol;
01115 error:
01116     libhal_free_string (vol_fsusage_textual);
01117     libhal_free_string (disc_type_textual);
01118     libhal_free_property_set (properties);
01119     libhal_volume_free (vol);
01120     return NULL;
01121 }
01122 
01123 
01132 int
01133 libhal_volume_get_msdos_part_table_type (LibHalVolume *volume)
01134 {
01135     return volume->msdos_part_table_type;
01136 }
01137 
01138 /***********************************************************************/
01139 
01147 LibHalDrive *
01148 libhal_drive_from_device_file (LibHalContext *hal_ctx, const char *device_file)
01149 {
01150     int i;
01151     char **hal_udis;
01152     int num_hal_udis;
01153     LibHalDrive *result;
01154     char *found_udi;
01155     DBusError error;
01156 
01157     LIBHAL_CHECK_LIBHALCONTEXT(hal_ctx, NULL);
01158 
01159     result = NULL;
01160     found_udi = NULL;
01161 
01162     dbus_error_init (&error);
01163     if ((hal_udis = libhal_manager_find_device_string_match (hal_ctx, "block.device", 
01164                                  device_file, &num_hal_udis, &error)) == NULL)
01165         goto out;
01166 
01167     for (i = 0; i < num_hal_udis; i++) {
01168         char *udi;
01169         char *storage_udi;
01170         DBusError err1;
01171         DBusError err2;
01172         udi = hal_udis[i];
01173 
01174         dbus_error_init (&err1);
01175         dbus_error_init (&err2);
01176         if (libhal_device_query_capability (hal_ctx, udi, "volume", &err1)) {
01177 
01178             storage_udi = libhal_device_get_property_string (hal_ctx, udi, "block.storage_device", &err1);
01179             if (storage_udi == NULL)
01180                 continue;
01181             found_udi = strdup (storage_udi);
01182             libhal_free_string (storage_udi);
01183             break;
01184         } else if (libhal_device_query_capability (hal_ctx, udi, "storage", &err2)) {
01185             found_udi = strdup (udi);
01186         }
01187     }
01188 
01189     libhal_free_string_array (hal_udis);
01190 
01191     if (found_udi != NULL)
01192         result = libhal_drive_from_udi (hal_ctx, found_udi);
01193 
01194     free (found_udi);
01195 out:
01196     return result;
01197 }
01198 
01199 
01206 LibHalVolume *
01207 libhal_volume_from_device_file (LibHalContext *hal_ctx, const char *device_file)
01208 {
01209     int i;
01210     char **hal_udis;
01211     int num_hal_udis;
01212     LibHalVolume *result;
01213     char *found_udi;
01214     DBusError error;
01215 
01216     LIBHAL_CHECK_LIBHALCONTEXT(hal_ctx, NULL);
01217 
01218     result = NULL;
01219     found_udi = NULL;
01220 
01221     dbus_error_init (&error);
01222     if ((hal_udis = libhal_manager_find_device_string_match (hal_ctx, "block.device", 
01223                                  device_file, &num_hal_udis, &error)) == NULL)
01224         goto out;
01225 
01226     for (i = 0; i < num_hal_udis; i++) {
01227         char *udi;
01228         udi = hal_udis[i];
01229         if (libhal_device_query_capability (hal_ctx, udi, "volume", &error)) {
01230             found_udi = strdup (udi);
01231             break;
01232         }
01233     }
01234 
01235     libhal_free_string_array (hal_udis);
01236 
01237     if (found_udi != NULL)
01238         result = libhal_volume_from_udi (hal_ctx, found_udi);
01239 
01240     free (found_udi);
01241 out:
01242     return result;
01243 }
01244 
01245 dbus_uint64_t
01246 libhal_volume_get_size (LibHalVolume *volume)
01247 {
01248     return ((dbus_uint64_t)volume->block_size) * ((dbus_uint64_t)volume->num_blocks);
01249 }
01250 
01251 
01252 dbus_bool_t
01253 libhal_drive_is_hotpluggable (LibHalDrive *drive)
01254 {
01255     return drive->is_hotpluggable;
01256 }
01257 
01258 dbus_bool_t
01259 libhal_drive_uses_removable_media (LibHalDrive *drive)
01260 {
01261     return drive->is_removable;
01262 }
01263 
01264 LibHalDriveType
01265 libhal_drive_get_type (LibHalDrive *drive)
01266 {
01267     return drive->type;
01268 }
01269 
01270 LibHalDriveBus
01271 libhal_drive_get_bus (LibHalDrive *drive)
01272 {
01273     return drive->bus;
01274 }
01275 
01276 LibHalDriveCdromCaps
01277 libhal_drive_get_cdrom_caps (LibHalDrive *drive)
01278 {
01279     return drive->cdrom_caps;
01280 }
01281 
01282 unsigned int
01283 libhal_drive_get_device_major (LibHalDrive *drive)
01284 {
01285     return drive->device_major;
01286 }
01287 
01288 unsigned int
01289 libhal_drive_get_device_minor (LibHalDrive *drive)
01290 {
01291     return drive->device_minor;
01292 }
01293 
01294 const char *
01295 libhal_drive_get_type_textual (LibHalDrive *drive)
01296 {
01297     return drive->type_textual;
01298 }
01299 
01300 const char *
01301 libhal_drive_get_device_file (LibHalDrive *drive)
01302 {
01303     return drive->device_file;
01304 }
01305 
01306 const char *
01307 libhal_drive_get_udi (LibHalDrive *drive)
01308 {
01309     return drive->udi;
01310 }
01311 
01312 const char *
01313 libhal_drive_get_serial (LibHalDrive *drive)
01314 {
01315     return drive->serial;
01316 }
01317 
01318 const char *
01319 libhal_drive_get_firmware_version (LibHalDrive *drive)
01320 {
01321     return drive->firmware_version;
01322 }
01323 
01324 const char *
01325 libhal_drive_get_model (LibHalDrive *drive)
01326 {
01327     return drive->model;
01328 }
01329 
01330 const char *
01331 libhal_drive_get_vendor (LibHalDrive *drive)
01332 {
01333     return drive->vendor;
01334 }
01335 
01336 /*****************************************************************************/
01337 
01338 const char *
01339 libhal_volume_get_udi (LibHalVolume *volume)
01340 {
01341     return volume->udi;
01342 }
01343 
01344 const char *
01345 libhal_volume_get_device_file (LibHalVolume *volume)
01346 {
01347     return volume->device_file;
01348 }
01349 
01350 unsigned int libhal_volume_get_device_major (LibHalVolume *volume)
01351 {
01352     return volume->device_major;
01353 }
01354 
01355 unsigned int libhal_volume_get_device_minor (LibHalVolume *volume)
01356 {
01357     return volume->device_minor;
01358 }
01359 
01360 const char *
01361 libhal_volume_get_fstype (LibHalVolume *volume)
01362 {
01363     return volume->fstype;
01364 }
01365 
01366 const char *
01367 libhal_volume_get_fsversion (LibHalVolume *volume)
01368 {
01369     return volume->fsversion;
01370 }
01371 
01372 LibHalVolumeUsage 
01373 libhal_volume_get_fsusage (LibHalVolume *volume)
01374 {
01375     return volume->fsusage;
01376 }
01377 
01378 dbus_bool_t 
01379 libhal_volume_is_mounted (LibHalVolume *volume)
01380 {
01381     return volume->is_mounted;
01382 }
01383 
01384 dbus_bool_t 
01385 libhal_volume_is_partition (LibHalVolume *volume)
01386 {
01387     return volume->is_partition;
01388 }
01389 
01390 dbus_bool_t
01391 libhal_volume_is_disc (LibHalVolume *volume)
01392 {
01393     return volume->is_disc;
01394 }
01395 
01396 unsigned int
01397 libhal_volume_get_partition_number (LibHalVolume *volume)
01398 {
01399     return volume->partition_number;
01400 }
01401 
01402 const char *
01403 libhal_volume_get_label (LibHalVolume *volume)
01404 {
01405     return volume->volume_label;
01406 }
01407 
01408 const char *
01409 libhal_volume_get_mount_point (LibHalVolume *volume)
01410 {
01411     return volume->mount_point;
01412 }
01413 
01414 const char *
01415 libhal_volume_get_uuid (LibHalVolume *volume)
01416 {
01417     return volume->uuid;
01418 }
01419 
01420 dbus_bool_t
01421 libhal_volume_disc_has_audio (LibHalVolume *volume)
01422 {
01423     return volume->disc_has_audio;
01424 }
01425 
01426 dbus_bool_t
01427 libhal_volume_disc_has_data (LibHalVolume *volume)
01428 {
01429     return volume->disc_has_data;
01430 }
01431 
01432 dbus_bool_t
01433 libhal_volume_disc_is_blank (LibHalVolume *volume)
01434 {
01435     return volume->disc_is_blank;
01436 }
01437 
01438 dbus_bool_t
01439 libhal_volume_disc_is_rewritable (LibHalVolume *volume)
01440 {
01441     return volume->disc_is_rewritable;
01442 }
01443 
01444 dbus_bool_t
01445 libhal_volume_disc_is_appendable (LibHalVolume *volume)
01446 {
01447     return volume->disc_is_appendable;
01448 }
01449 
01450 LibHalVolumeDiscType
01451 libhal_volume_get_disc_type (LibHalVolume *volume)
01452 {
01453     return volume->disc_type;
01454 }
01455 
01456 char ** 
01457 libhal_drive_find_all_volumes (LibHalContext *hal_ctx, LibHalDrive *drive, int *num_volumes)
01458 {
01459     int i;
01460     char **udis;
01461     int num_udis;
01462     const char *drive_udi;
01463     char **result;
01464     DBusError error;
01465 
01466     LIBHAL_CHECK_LIBHALCONTEXT(hal_ctx, NULL);
01467 
01468     udis = NULL;
01469     result = NULL;
01470     *num_volumes = 0;
01471 
01472     drive_udi = libhal_drive_get_udi (drive);
01473     if (drive_udi == NULL)
01474         goto out;
01475 
01476     /* get initial list... */
01477     dbus_error_init (&error);
01478     if ((udis = libhal_manager_find_device_string_match (hal_ctx, "block.storage_device", 
01479                                  drive_udi, &num_udis, &error)) == NULL)
01480         goto out;
01481 
01482     result = malloc (sizeof (char *) * num_udis);
01483     if (result == NULL)
01484         goto out;
01485 
01486     /* ...and filter out the single UDI that is the drive itself */
01487     for (i = 0; i < num_udis; i++) {
01488         if (strcmp (udis[i], drive_udi) == 0)
01489             continue;
01490         result[*num_volumes] = strdup (udis[i]);
01491         *num_volumes = (*num_volumes) + 1;
01492     }
01493 
01494 out:
01495     libhal_free_string_array (udis);
01496     return result;
01497 }
01498 
01499 /*************************************************************************/
01500 
01501 char *
01502 libhal_drive_policy_default_get_mount_root (LibHalContext *hal_ctx)
01503 {
01504     DBusError error;
01505 
01506     LIBHAL_CHECK_LIBHALCONTEXT(hal_ctx, NULL);
01507 
01508     dbus_error_init (&error);
01509     return libhal_device_get_property_string (hal_ctx, "/org/freedesktop/Hal/devices/computer",
01510                           "storage.policy.default.mount_root", &error);
01511 }
01512 
01513 dbus_bool_t
01514 libhal_drive_policy_default_use_managed_keyword (LibHalContext *hal_ctx)
01515 {
01516     DBusError error;
01517 
01518     LIBHAL_CHECK_LIBHALCONTEXT(hal_ctx, FALSE);
01519 
01520     dbus_error_init (&error);
01521     return libhal_device_get_property_bool (hal_ctx, "/org/freedesktop/Hal/devices/computer",
01522                         "storage.policy.default.use_managed_keyword", &error);
01523 }
01524 
01525 char *
01526 libhal_drive_policy_default_get_managed_keyword_primary (LibHalContext *hal_ctx)
01527 {
01528     DBusError error;
01529 
01530     LIBHAL_CHECK_LIBHALCONTEXT(hal_ctx, NULL);
01531 
01532     dbus_error_init (&error);
01533     return libhal_device_get_property_string (hal_ctx, "/org/freedesktop/Hal/devices/computer",
01534                           "storage.policy.default.managed_keyword.primary", &error);
01535 }
01536 
01537 char *
01538 libhal_drive_policy_default_get_managed_keyword_secondary (LibHalContext *hal_ctx)
01539 {
01540     DBusError error;
01541 
01542     LIBHAL_CHECK_LIBHALCONTEXT(hal_ctx, NULL);
01543 
01544     dbus_error_init (&error);
01545     return libhal_device_get_property_string (hal_ctx, "/org/freedesktop/Hal/devices/computer",
01546                           "storage.policy.default.managed_keyword.secondary", &error);
01547 }
01548 
01549 /*************************************************************************/
01550 
01551 dbus_bool_t
01552 libhal_drive_policy_is_mountable (LibHalDrive *drive, LibHalStoragePolicy *policy)
01553 {
01554     printf ("should_mount=%d, no_partitions_hint=%d\n", drive->should_mount, drive->no_partitions_hint);
01555 
01556     return drive->should_mount && drive->no_partitions_hint;
01557 }
01558 
01559 const char *
01560 libhal_drive_policy_get_desired_mount_point (LibHalDrive *drive, LibHalStoragePolicy *policy)
01561 {
01562     return drive->desired_mount_point;
01563 }
01564 
01565 /* safely strcat() at most the remaining space in 'dst' */
01566 #define strcat_len(dst, src, dstmaxlen) do {    \
01567     dst[dstmaxlen - 1] = '\0'; \
01568     strncat (dst, src, dstmaxlen - strlen (dst) - 1); \
01569 } while(0)
01570 
01571 
01572 static void
01573 mopts_collect (LibHalContext *hal_ctx, const char *namespace, int namespace_len, 
01574            const char *udi, char *options_string, size_t options_max_len, dbus_bool_t only_collect_imply_opts)
01575 {
01576     LibHalPropertySet *properties;
01577     LibHalPropertySetIterator it;
01578     DBusError error;
01579 
01580     if(hal_ctx == 0) {
01581         fprintf (stderr,"%s %d : LibHalContext *ctx is NULL\n",__FILE__, __LINE__);
01582         return;
01583     }
01584 
01585     dbus_error_init (&error);
01586 
01587     /* first collect from root computer device */
01588     properties = libhal_device_get_all_properties (hal_ctx, udi, &error);
01589     if (properties == NULL)
01590         goto error;
01591     for (libhal_psi_init (&it, properties); libhal_psi_has_more (&it); libhal_psi_next (&it)) {
01592         int type;
01593         char *key;
01594         
01595         type = libhal_psi_get_type (&it);
01596         key = libhal_psi_get_key (&it);
01597         if (libhal_psi_get_type (&it) == LIBHAL_PROPERTY_TYPE_BOOLEAN &&
01598             strncmp (key, namespace, namespace_len - 1) == 0) {
01599             const char *option = key + namespace_len - 1;
01600             char *location;
01601             dbus_bool_t is_imply_opt;
01602 
01603             is_imply_opt = FALSE;
01604             if (strcmp (option, "user") == 0 ||
01605                 strcmp (option, "users") == 0 ||
01606                 strcmp (option, "defaults") == 0 ||
01607                 strcmp (option, "pamconsole") == 0)
01608                 is_imply_opt = TRUE;
01609 
01610             
01611             if (only_collect_imply_opts) {
01612                 if (!is_imply_opt)
01613                     continue;
01614             } else {
01615                 if (is_imply_opt)
01616                     continue;
01617             }
01618 
01619             if (libhal_psi_get_bool (&it)) {
01620                 /* see if option is already there */
01621                 location = strstr (options_string, option);
01622                 if (location == NULL) {
01623                     if (strlen (options_string) > 0)
01624                         strcat_len (options_string, ",", options_max_len);
01625                     strcat_len (options_string, option, options_max_len);
01626                 }
01627             } else {
01628                 /* remove option if already there */
01629                 location = strstr (options_string, option);
01630                 if (location != NULL) {
01631                     char *end;
01632 
01633                     end = strchr (location, ',');
01634                     if (end == NULL) {
01635                         location[0] = '\0';
01636                     } else {
01637                         strcpy (location, end + 1); /* skip the extra comma */
01638                     }
01639                 }
01640 
01641             }
01642         }
01643     }
01644 error:
01645     libhal_free_property_set (properties);
01646 }
01647 
01648 
01649 const char *
01650 libhal_drive_policy_get_mount_options (LibHalDrive *drive, LibHalStoragePolicy *policy)
01651 {
01652     const char *result;
01653     char stor_mount_option_default_begin[] = "storage.policy.default.mount_option.";
01654     char stor_mount_option_begin[] = "storage.policy.mount_option.";
01655 
01656     result = NULL;
01657     drive->mount_options[0] = '\0';
01658 
01659     /* collect options != ('pamconsole', 'user', 'users', 'defaults' options that imply other options)  */
01660     mopts_collect (drive->hal_ctx, stor_mount_option_default_begin, sizeof (stor_mount_option_default_begin),
01661                "/org/freedesktop/Hal/devices/computer", drive->mount_options, MOUNT_OPTIONS_SIZE, TRUE);
01662     mopts_collect (drive->hal_ctx, stor_mount_option_begin, sizeof (stor_mount_option_begin),
01663                drive->udi, drive->mount_options, MOUNT_OPTIONS_SIZE, TRUE);
01664     /* ensure ('pamconsole', 'user', 'users', 'defaults' options that imply other options), are first */
01665     mopts_collect (drive->hal_ctx, stor_mount_option_default_begin, sizeof (stor_mount_option_default_begin),
01666                "/org/freedesktop/Hal/devices/computer", drive->mount_options, MOUNT_OPTIONS_SIZE, FALSE);
01667     mopts_collect (drive->hal_ctx, stor_mount_option_begin, sizeof (stor_mount_option_begin),
01668                drive->udi, drive->mount_options, MOUNT_OPTIONS_SIZE, FALSE);
01669 
01670     result = drive->mount_options;
01671 
01672     return result;
01673 }
01674 
01675 const char *
01676 libhal_drive_policy_get_mount_fs (LibHalDrive *drive, LibHalStoragePolicy *policy)
01677 {
01678     return drive->mount_filesystem;
01679 }
01680 
01681 
01682 dbus_bool_t
01683 libhal_volume_policy_is_mountable (LibHalDrive *drive, LibHalVolume *volume, LibHalStoragePolicy *policy)
01684 {
01685     return drive->should_mount && volume->should_mount;
01686 }
01687 
01688 const char *libhal_volume_policy_get_desired_mount_point (LibHalDrive *drive, LibHalVolume *volume, LibHalStoragePolicy *policy)
01689 {
01690     return volume->desired_mount_point;
01691 }
01692 
01693 const char *libhal_volume_policy_get_mount_options (LibHalDrive *drive, LibHalVolume *volume, LibHalStoragePolicy *policy)
01694 {
01695     const char *result;
01696     char stor_mount_option_default_begin[] = "storage.policy.default.mount_option.";
01697     char vol_mount_option_begin[] = "volume.policy.mount_option.";
01698 
01699     result = NULL;
01700     volume->mount_options[0] = '\0';
01701 
01702     /* ensure ('pamconsole', 'user', 'users', 'defaults' options that imply other options), are first */
01703     mopts_collect (drive->hal_ctx, stor_mount_option_default_begin, sizeof (stor_mount_option_default_begin),
01704                "/org/freedesktop/Hal/devices/computer", volume->mount_options, MOUNT_OPTIONS_SIZE, TRUE);
01705     mopts_collect (drive->hal_ctx, vol_mount_option_begin, sizeof (vol_mount_option_begin),
01706                volume->udi, volume->mount_options, MOUNT_OPTIONS_SIZE, TRUE);
01707     /* collect options != ('pamconsole', 'user', 'users', 'defaults' options that imply other options)  */
01708     mopts_collect (drive->hal_ctx, stor_mount_option_default_begin, sizeof (stor_mount_option_default_begin),
01709                "/org/freedesktop/Hal/devices/computer", volume->mount_options, MOUNT_OPTIONS_SIZE, FALSE);
01710     mopts_collect (drive->hal_ctx, vol_mount_option_begin, sizeof (vol_mount_option_begin),
01711                volume->udi, volume->mount_options, MOUNT_OPTIONS_SIZE, FALSE);
01712 
01713     result = volume->mount_options;
01714 
01715     return result;
01716 }
01717 
01718 const char *libhal_volume_policy_get_mount_fs (LibHalDrive *drive, LibHalVolume *volume, LibHalStoragePolicy *policy)
01719 {
01720     return volume->mount_filesystem;
01721 }
01722 
01723 dbus_bool_t       
01724 libhal_drive_no_partitions_hint (LibHalDrive *drive)
01725 {
01726     return drive->no_partitions_hint;
01727 }
01728 

Generated on Wed Feb 22 07:57:03 2006 for HAL by  doxygen 1.4.5