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

libhal-storage.c

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

Generated on Mon Oct 3 16:10:49 2005 for HAL by  doxygen 1.4.4