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

libhal-storage.c

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

Generated on Thu Nov 17 13:49:51 2005 for HAL by  doxygen 1.4.4