/* * ipod.c - Find an iPod mount point using HAL * * (C)2004 Justin Wake * * Licensed under the GNU GPL v2. See COPYING. * */ #include "config.h" #include "evolution-ipod-sync.h" #include /** * Ensure that HAL is running before we try to use it. * From gnome-volume-manager's src/properties.c */ gboolean check_hal (void) { LibHalContext *ctx; char **devices; int num; DBusConnection *conn; conn = dbus_bus_get (DBUS_BUS_SYSTEM, NULL); ctx = libhal_ctx_new (); libhal_ctx_set_dbus_connection (ctx, conn); if (!libhal_ctx_init(ctx, NULL)) return FALSE; devices = libhal_get_all_devices (ctx, &num, NULL); if (!devices) { libhal_ctx_shutdown (ctx, NULL); return FALSE; } libhal_free_string_array (devices); libhal_ctx_shutdown (ctx, NULL); return TRUE; } #define MOUNT "/bin/mount" #define UMOUNT "/bin/umount" /** * Try to mount a given device. */ static gboolean try_mount (char *device) { char *argv[3]; GError *err = NULL; gint exit_status; argv[0] = MOUNT; argv[1] = device; argv[2] = NULL; if (!g_spawn_sync (g_get_home_dir (), argv, NULL, 0, NULL, NULL, NULL, NULL, &exit_status, &err)) { warn ("try_mount failed: %s", err->message); return FALSE; } return (exit_status == 0); } /** * Try to unmount a given device. */ gboolean try_umount (char *device) { char *argv[3]; GError *err = NULL; gint exit_status; argv[0] = UMOUNT; argv[1] = device; argv[2] = NULL; sync (); if (!g_spawn_sync (g_get_home_dir (), argv, NULL, 0, NULL, NULL, NULL, NULL, &exit_status, &err)) { warn ("try_umount failed: %s", err->message); return FALSE; } return (exit_status == 0); } /** * See if a given mount point contains an iPod. * * Do this by checking for the presence of an iTunes * database at /iPod_Control/iTunes/. */ static gboolean is_ipod (char *mount_point) { gboolean ret = FALSE; char *itunes_path; itunes_path = g_build_path (G_DIR_SEPARATOR_S, mount_point, "iPod_Control", "iTunes", NULL); if (!g_file_test (itunes_path, G_FILE_TEST_IS_DIR)) goto out; ret = TRUE; out: g_free (itunes_path); return ret; } /** * Try to find a mount point for an iPod. */ char * find_ipod_mount_point (LibHalContext *ctx) { char **apple_devices = NULL; char **volumes = NULL; char *udi, *udi2, *device, *fsusage, *mount_point = NULL; char *retval = NULL; int apple_count = 0; int volume_count = 0; int has_fs = 0; int i, j; /* First, we look for things made by Apple. */ apple_devices = libhal_manager_find_device_string_match (ctx, "info.vendor", "Apple", &apple_count, NULL); for (i = 0; i < apple_count; i++) { udi = apple_devices[i]; volumes = NULL; volumes = libhal_manager_find_device_string_match (ctx, "info.parent", udi, &volume_count, NULL); for (j = 0; j < volume_count; j++) { udi2 = volumes[j]; /* Only interested if it has a filesystem. */ has_fs = 0; if (!libhal_device_property_exists (ctx, udi2, "volume.is_filesystem", NULL) || !libhal_device_get_property_bool (ctx, udi2, "volume.is_filesystem", NULL)) { has_fs = 1; } fsusage = libhal_device_get_property_string (ctx, udi2, "volume.fsusage", NULL); if (strncmp (fsusage, "filesystem", 10) == 0) { has_fs = 1; } libhal_free_string (fsusage); if (has_fs == 0) continue; device = libhal_device_get_property_string (ctx, udi2, "block.device", NULL); /* Let's see if it's mounted. */ if (!libhal_device_property_exists (ctx, udi2, "volume.is_mounted", NULL) || !libhal_device_get_property_bool (ctx, udi2, "volume.is_mounted", NULL)) { /* It isn't, so let's attempt to mount it */ if (device != NULL) { try_mount (device); } } if (!libhal_device_property_exists (ctx, udi2, "volume.mount_point", NULL)) { libhal_free_string (device); continue; } libhal_free_string (device); mount_point = libhal_device_get_property_string (ctx, udi2, "volume.mount_point", NULL); if (is_ipod (mount_point)) { goto out; } libhal_free_string (mount_point); mount_point = NULL; } } out: if (volumes != NULL) libhal_free_string_array (volumes); if (apple_devices != NULL) libhal_free_string_array (apple_devices); if (mount_point != NULL) { retval = g_strdup (mount_point); libhal_free_string (mount_point); } return (retval); }