diff options
Diffstat (limited to 'plugins/ipod-sync/ipod.c')
-rw-r--r-- | plugins/ipod-sync/ipod.c | 237 |
1 files changed, 237 insertions, 0 deletions
diff --git a/plugins/ipod-sync/ipod.c b/plugins/ipod-sync/ipod.c new file mode 100644 index 0000000000..1cff429c22 --- /dev/null +++ b/plugins/ipod-sync/ipod.c @@ -0,0 +1,237 @@ +/* + * ipod.c - Find an iPod mount point using HAL + * + * (C)2004 Justin Wake <jwake@iinet.net.au> + * + * Licensed under the GNU GPL v2. See COPYING. + * + */ + +#include "config.h" +#include "evolution-ipod-sync.h" +#include <unistd.h> + +/** + * 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 <mount_point>/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); +} |