GSList* get_volumes_mounted_on_drive(LibHalContext* ctx, LibHalDrive* drive) { /* FIXME: This sucks - HAL doesn't report mounted volumes correctly */ GSList* volume_list = NULL; int num_vols = 0; char** vol_udis = libhal_drive_find_all_volumes(ctx, drive, &num_vols); if(num_vols <= 0 || vol_udis == NULL) goto out; int i=0; for(i=0; i < num_vols; i++) { LibHalVolume* current; if(!vol_udis[i]) break; current = libhal_volume_from_udi(ctx, vol_udis[i]); if(!current) continue; if(libhal_volume_is_mounted(current)) volume_list = g_slist_prepend(volume_list, g_strdup(vol_udis[i])); libhal_volume_free(current); } libhal_free_string_array(vol_udis); out: return volume_list; }
// Helper function. creates a CStorageDevice from a HAL udi bool CHALManager::DeviceFromVolumeUdi(const char *udi, CStorageDevice *device) { if (g_HalManager.m_Context == NULL) return false; LibHalVolume *tempVolume; LibHalDrive *tempDrive; bool Created = false; tempVolume = libhal_volume_from_udi(g_HalManager.m_Context, udi); if (tempVolume) { const char *DriveUdi = libhal_volume_get_storage_device_udi(tempVolume); tempDrive = libhal_drive_from_udi(g_HalManager.m_Context, DriveUdi); if (tempDrive) { char * FriendlyName = libhal_device_get_property_string(g_HalManager.m_Context, udi, "info.product", NULL); device->FriendlyName = FriendlyName; libhal_free_string(FriendlyName); char *block = libhal_device_get_property_string(g_HalManager.m_Context, udi, "block.device", NULL); device->DevID = block; libhal_free_string(block); device->HotPlugged = (bool)libhal_drive_is_hotpluggable(tempDrive); device->Type = libhal_drive_get_type(tempDrive); device->Mounted = (bool)libhal_volume_is_mounted(tempVolume); device->MountPoint = libhal_volume_get_mount_point(tempVolume); if (device->Mounted) URIUtils::AddSlashAtEnd(device->MountPoint); device->Label = libhal_volume_get_label(tempVolume); device->UUID = libhal_volume_get_uuid(tempVolume); device->FileSystem = libhal_volume_get_fstype(tempVolume); device->HalIgnore = libhal_device_get_property_bool(g_HalManager.m_Context, udi, "volume.ignore", NULL); ApproveDevice(device); libhal_drive_free(tempDrive); Created = true; } else CLog::Log(LOGERROR, "HAL: Couldn't create a Drive even if we had a volume - %s", udi); libhal_volume_free(tempVolume); } return Created; }
static int pusb_volume_mount(t_pusb_options *opts, LibHalVolume **volume, LibHalContext *ctx) { char command[1024]; char tempname[32]; const char *devname; const char *udi; const char *fs; snprintf(tempname, sizeof(tempname), "pam_usb%d", getpid()); if (!(devname = libhal_volume_get_device_file(*volume))) { log_error("Unable to retrieve device filename\n"); return (0); } fs = libhal_volume_get_fstype(*volume); log_debug("Attempting to mount device %s with label %s\n", devname, tempname); if (!fs) snprintf(command, sizeof(command), "pmount -A -s %s %s", devname, tempname); else snprintf(command, sizeof(command), "pmount -A -s -t %s %s %s", fs, devname, tempname); log_debug("Executing \"%s\"\n", command); if (system(command) != 0) { log_error("Mount failed\n"); return (0); } udi = libhal_volume_get_udi(*volume); if (!udi) { log_error("Unable to retrieve volume UDI\n"); return (0); } udi = strdup(udi); libhal_volume_free(*volume); *volume = libhal_volume_from_udi(ctx, udi); free((char *)udi); log_debug("Mount succeeded.\n"); return (1); }
static LibHalVolume *pusb_volume_probe(t_pusb_options *opts, LibHalContext *ctx) { LibHalVolume *volume = NULL; int maxtries = 0; int i; if (!*(opts->device.volume_uuid)) { log_debug("No UUID configured for device\n"); return (NULL); } log_debug("Searching for volume with uuid %s\n", opts->device.volume_uuid); maxtries = ((opts->probe_timeout * 1000000) / 250000); for (i = 0; i < maxtries; ++i) { char *udi = NULL; if (i == 1) log_info("Probing volume (this could take a while)...\n"); udi = pusb_hal_find_item(ctx, "volume.uuid", opts->device.volume_uuid, NULL); if (!udi) { usleep(250000); continue; } volume = libhal_volume_from_udi(ctx, udi); libhal_free_string(udi); if (!libhal_volume_should_ignore(volume)) return (volume); libhal_volume_free(volume); usleep(250000); } return (NULL); }
GSList* build_volume_list(LibHalContext* ctx, enum FormatVolumeType type, GHashTable* icon_cache, int icon_width, int icon_height) { const char* capability = ""; char** device_udis; int i, device_udi_count = 0; GSList* device_list = NULL; DBusError error; switch(type) { case FORMATVOLUMETYPE_VOLUME: capability = "volume"; break; case FORMATVOLUMETYPE_DRIVE: capability = "storage"; break; } /* Pull the storage (or volume) list from HAL */ dbus_error_init (&error); if ( (device_udis = libhal_find_device_by_capability (ctx, capability, &device_udi_count, &error) ) == NULL) { LIBHAL_FREE_DBUS_ERROR (&error); goto out; } /* if we use libhal_device_get-property() instead of * libhal_volume_get_mount_mount_point() we have to setup DBusError and * some other things, the problem is do we like to have (null) in the gui * when libhal-storage cannot discover where a partition is mounted? * if so we can remove the DBusError code and use the libhal-storage func * to retrive the mount point. * (or maybe we can check if is_partition == null and then don't strdup * it. * It returns null when a device is marked as swap or mounted via * cryptdisk or even if it's not listed in /etc/fstab */ /* Now we use libhal-storage to get the info */ FormatVolume* current; const char* icon_path; for(i=0; i < device_udi_count; i++) { current = g_new0(FormatVolume, 1); g_debug("udi: %s", device_udis[i]); current->udi = g_strdup(device_udis[i]); switch(type) { case FORMATVOLUMETYPE_VOLUME: current->volume = libhal_volume_from_udi(ctx, device_udis[i]); if(!current->volume) { g_free(current); continue; } /* FIXME: This tastes like wrong */ current->icon = NULL; current->friendly_name = get_friendly_volume_info(ctx, current->volume); current->drive_udi = g_strdup(libhal_volume_get_storage_device_udi(current->volume)); current->mountpoint = g_strdup(libhal_volume_get_mount_point(current->volume)); break; case FORMATVOLUMETYPE_DRIVE: current->drive = libhal_drive_from_udi(ctx, device_udis[i]); if(!current->drive) { g_free(current); continue; } g_debug("Icon drive: %s; Icon volume: %s", libhal_drive_get_dedicated_icon_drive(current->drive), libhal_drive_get_dedicated_icon_volume(current->drive)); icon_path = libhal_drive_get_dedicated_icon_drive(current->drive); current->icon = load_icon_from_cache(icon_path, icon_cache, icon_width, icon_height); current->friendly_name = get_friendly_drive_info(current->drive); break; } /* Do some last minute sanity checks */ if(!current->friendly_name) current->friendly_name = ""; device_list = g_slist_prepend(device_list, current); } if(device_udis) libhal_free_string_array(device_udis); out: return device_list; }
static void thunar_vfs_volume_manager_hal_device_added (LibHalContext *context, const gchar *udi) { ThunarVfsVolumeManagerHal *manager_hal = libhal_ctx_get_user_data (context); ThunarVfsVolumeHal *volume_hal; LibHalVolume *hv; LibHalDrive *hd; const gchar *drive_udi; _thunar_vfs_return_if_fail (THUNAR_VFS_IS_VOLUME_MANAGER_HAL (manager_hal)); _thunar_vfs_return_if_fail (manager_hal->context == context); /* check if we have a volume here */ hv = libhal_volume_from_udi (context, udi); /* HAL might want us to ignore this volume for some reason */ if (G_UNLIKELY (hv != NULL && libhal_volume_should_ignore (hv))) { libhal_volume_free (hv); return; } /* emit the "device-added" signal (to support thunar-volman) */ g_signal_emit_by_name (G_OBJECT (manager_hal), "device-added", udi); if (G_LIKELY (hv != NULL)) { /* check if we have a mountable file system here */ if (libhal_volume_get_fsusage (hv) == LIBHAL_VOLUME_USAGE_MOUNTABLE_FILESYSTEM) { /* determine the UDI of the drive to which this volume belongs */ drive_udi = libhal_volume_get_storage_device_udi (hv); if (G_LIKELY (drive_udi != NULL)) { /* determine the drive for the volume */ hd = libhal_drive_from_udi (context, drive_udi); if (G_LIKELY (hd != NULL)) { /* check if we already have a volume object for the UDI */ volume_hal = thunar_vfs_volume_manager_hal_get_volume_by_udi (manager_hal, udi); if (G_LIKELY (volume_hal == NULL)) { /* otherwise, we allocate a new volume object */ volume_hal = g_object_new (THUNAR_VFS_TYPE_VOLUME_HAL, NULL); volume_hal->udi = g_strdup (udi); } /* update the volume object with the new data from the HAL volume/drive */ thunar_vfs_volume_hal_update (volume_hal, context, hv, hd); /* add the volume object to our list if we allocated a new one */ if (g_list_find (THUNAR_VFS_VOLUME_MANAGER (manager_hal)->volumes, volume_hal) == NULL) { /* add the volume to the volume manager */ thunar_vfs_volume_manager_add (THUNAR_VFS_VOLUME_MANAGER (manager_hal), THUNAR_VFS_VOLUME (volume_hal)); /* release the reference on the volume */ g_object_unref (G_OBJECT (volume_hal)); } /* release the HAL drive */ libhal_drive_free (hd); } } } /* release the HAL volume */ libhal_volume_free (hv); } else { /* but maybe we have a floppy disk drive here */ hd = libhal_drive_from_udi (context, udi); if (G_UNLIKELY (hd == NULL)) return; /* check if we have a floppy disk drive */ if (G_LIKELY (libhal_drive_get_type (hd) == LIBHAL_DRIVE_TYPE_FLOPPY)) { /* check if we already have a volume object for the UDI */ volume_hal = thunar_vfs_volume_manager_hal_get_volume_by_udi (manager_hal, udi); if (G_LIKELY (volume_hal == NULL)) { /* otherwise, we allocate a new volume object */ volume_hal = g_object_new (THUNAR_VFS_TYPE_VOLUME_HAL, NULL); volume_hal->udi = g_strdup (udi); } /* update the volume object with the new data from the HAL volume/drive */ thunar_vfs_volume_hal_update (volume_hal, context, NULL, hd); /* add the volume object to our list if we allocated a new one */ if (g_list_find (THUNAR_VFS_VOLUME_MANAGER (manager_hal)->volumes, volume_hal) == NULL) { /* add the volume to the volume manager */ thunar_vfs_volume_manager_add (THUNAR_VFS_VOLUME_MANAGER (manager_hal), THUNAR_VFS_VOLUME (volume_hal)); /* release the reference on the volume */ g_object_unref (G_OBJECT (volume_hal)); } } /* release the HAL drive */ libhal_drive_free (hd); } }
static void thunar_vfs_volume_manager_hal_update_volume_by_udi (ThunarVfsVolumeManagerHal *manager_hal, const gchar *udi) { ThunarVfsVolumeHal *volume_hal; LibHalVolume *hv = NULL; LibHalDrive *hd = NULL; const gchar *drive_udi; /* check if we have a volume for the UDI */ volume_hal = thunar_vfs_volume_manager_hal_get_volume_by_udi (manager_hal, udi); if (G_UNLIKELY (volume_hal == NULL)) return; /* check if we have a volume here */ hv = libhal_volume_from_udi (manager_hal->context, udi); if (G_UNLIKELY (hv == NULL)) { /* check if we have a drive here */ hd = libhal_drive_from_udi (manager_hal->context, udi); if (G_UNLIKELY (hd == NULL)) { /* the device is no longer a drive or volume, so drop it */ thunar_vfs_volume_manager_hal_device_removed (manager_hal->context, udi); return; } /* update the drive with the new HAL drive/volume */ thunar_vfs_volume_hal_update (volume_hal, manager_hal->context, NULL, hd); /* release the drive */ libhal_drive_free (hd); } else { /* determine the UDI of the drive to which this volume belongs */ drive_udi = libhal_volume_get_storage_device_udi (hv); if (G_LIKELY (drive_udi != NULL)) { /* determine the drive for the volume */ hd = libhal_drive_from_udi (manager_hal->context, drive_udi); } /* check if we have the drive for the volume */ if (G_LIKELY (hd != NULL)) { /* update the volume with the new HAL drive/volume */ thunar_vfs_volume_hal_update (volume_hal, manager_hal->context, hv, hd); /* release the drive */ libhal_drive_free (hd); } else { /* unable to determine the drive, volume gone? */ thunar_vfs_volume_manager_hal_device_removed (manager_hal->context, udi); } /* release the volume */ libhal_volume_free (hv); } }
int main (int argc, char *argv[]) { char *udi; char *device; const char *drive_udi; LibHalDrive *drive; LibHalVolume *volume; DBusError error; LibHalContext *hal_ctx = NULL; DBusConnection *system_bus = NULL; #ifdef HAVE_POLKIT LibPolKitContext *pol_ctx = NULL; #endif char *invoked_by_uid; char *invoked_by_syscon_name; device = getenv ("HAL_PROP_BLOCK_DEVICE"); if (device == NULL) usage (); udi = getenv ("HAL_PROP_INFO_UDI"); if (udi == NULL) usage (); invoked_by_uid = getenv ("HAL_METHOD_INVOKED_BY_UID"); invoked_by_syscon_name = getenv ("HAL_METHOD_INVOKED_BY_SYSTEMBUS_CONNECTION_NAME"); dbus_error_init (&error); if ((hal_ctx = libhal_ctx_init_direct (&error)) == NULL) { printf ("Cannot connect to hald\n"); LIBHAL_FREE_DBUS_ERROR (&error); usage (); } dbus_error_init (&error); system_bus = dbus_bus_get (DBUS_BUS_SYSTEM, &error); if (system_bus == NULL) { printf ("Cannot connect to the system bus\n"); LIBHAL_FREE_DBUS_ERROR (&error); usage (); } #ifdef HAVE_POLKIT pol_ctx = libpolkit_new_context (system_bus); if (pol_ctx == NULL) { printf ("Cannot get libpolkit context\n"); unknown_zpool_error ("Cannot get libpolkit context"); } #endif /* should be a volume */ if ((volume = libhal_volume_from_udi (hal_ctx, udi)) == NULL) { unknown_zpool_error ("Invalid volume"); } if ((drive_udi = libhal_volume_get_storage_device_udi (volume)) == NULL ) { unknown_zpool_error ("Cannot get drive udi"); } if ((drive = libhal_drive_from_udi (hal_ctx, drive_udi)) == NULL) { unknown_zpool_error ("Cannot get drive from udi"); } if ((libhal_volume_get_fstype (volume) == NULL) || (strcmp (libhal_volume_get_fstype (volume), "zfs") != 0)) { unknown_zpool_error ("Not a zpool"); } if ((libhal_volume_get_label (volume) == NULL) || (strlen (libhal_volume_get_label (volume)) == 0)) { unknown_zpool_error ("Invalid zpool name"); } handle_zpool (hal_ctx, #ifdef HAVE_POLKIT pol_ctx, #endif ZPOOL_SUBCMD, libhal_volume_get_label (volume), device, invoked_by_uid, invoked_by_syscon_name, system_bus); return 0; }
/* Callback function, called when a new device has been inserted. */ static void device_added(LibHalContext *context, const char *did) { const char *dudi, *fstype; char *dev, *mountp, *mountable, *label, *locked_reason; LibHalVolume *volume; LibHalDrive *drive; struct device_t *device; if (libhal_device_property_exists(context, did, "info.locked", (DBusError *)NULL) && libhal_device_get_property_bool(context, did, "info.locked", (DBusError *)NULL)) { if (debug_mode_flag) { locked_reason = libhal_device_get_property_string( context, did, "info.locked.reason", (DBusError *)NULL); if (locked_reason) { if (debug_mode_flag) printf("%s%d: %s\n", __FILE__, __LINE__, locked_reason); libhal_free_string(locked_reason); } } return; } if (!libhal_device_query_capability(context, did, "volume", (DBusError *)NULL)) return; label = libhal_device_get_property_string(context, did, "volume.label", (DBusError *)NULL); if (!(mountable = libhal_device_get_property_string( context, did, "volume.fsusage", (DBusError *)NULL)) || strcmp(mountable, "filesystem")) goto out; if (!(volume = libhal_volume_from_udi(context, did))) goto out; if (!(dudi = libhal_volume_get_storage_device_udi(volume))) goto out; if (!(drive = libhal_drive_from_udi(context, dudi))) goto out; if (!libhal_drive_is_hotpluggable(drive) && !libhal_drive_uses_removable_media(drive)) goto out; if (!(fstype = libhal_volume_get_fstype(volume))) goto out; if (!(dev = libhal_device_get_property_string(context, did, "block.device", (DBusError *)NULL))) goto out; mountp = get_mount_point(dev, label); if (!mountp) goto out; device = get_device(mountp, did, dev, label, fstype, volume, drive); if(!is_mounted(device)) { free_device(device); goto out; } if (!device) goto out; consider_fstab(device); device->hook = malloc(2*sizeof(char*)); if(!file_exists(HOOK_PATH)) { device->hook[0] = get_hook(device, "mount"); device->hook[1] = get_hook(device, "umount"); } else { device->hook[0] = NULL; device->hook[1] = NULL; } if (file_exists(device->mountp) < 0) mkdir(device->mountp, 0750); do_mount(device) < 0 ? free_device(device) : add_to_device_list(device); if (device) { if (!add_fstab_entry(device)) device->should_remove_entry = 1; if (debug_mode_flag) debug_dump_device(device); } if (device->hook[0]) run_hook(0, device); out: if (mountable) libhal_free_string(mountable); if (label) libhal_free_string(label); }