summaryrefslogtreecommitdiffstats
path: root/src/ipod-device.c
diff options
context:
space:
mode:
authorJorg Schuler <jcsjcs@users.sourceforge.net>2006-03-16 15:34:34 +0000
committerJorg Schuler <jcsjcs@users.sourceforge.net>2006-03-16 15:34:34 +0000
commitace89adce995bd158ef49390a6438c093bf306b3 (patch)
treec5a18421b35013c3fcd1ac5dbe72daa649a30b2b /src/ipod-device.c
parent86f4c354d7fa66d864b434169c633f85ed516e5c (diff)
downloadlibgpod-ace89adce995bd158ef49390a6438c093bf306b3.tar.gz
libgpod-ace89adce995bd158ef49390a6438c093bf306b3.tar.xz
libgpod-ace89adce995bd158ef49390a6438c093bf306b3.zip
* itdb_device.[ch]: rewrote ipod-device.c, removed all hal-code,
removed all code irrelevant to writing the iTunesDB and ArtworkDB. * autodetect iControl directory now also works for ArtworkDB. * db-artwork-parser.c (ipod_db_get_artwork_db_path): create Artwork directory if not already present. * itdb.h: Itdb_iTunesDB: moved mountpoint and musicdirs into private Itdb_Device. Use itdb_set_mountpoint() and itdb_get_mountpoint() to access the mountpoint. git-svn-id: https://gtkpod.svn.sf.net/svnroot/gtkpod/libgpod/trunk@1220 f01d2545-417e-4e96-918e-98f8d0dbbcb6
Diffstat (limited to 'src/ipod-device.c')
-rw-r--r--src/ipod-device.c1832
1 files changed, 0 insertions, 1832 deletions
diff --git a/src/ipod-device.c b/src/ipod-device.c
deleted file mode 100644
index 411b182..0000000
--- a/src/ipod-device.c
+++ /dev/null
@@ -1,1832 +0,0 @@
-/* Time-stamp: <2006-03-09 21:50:38 jcs>
-|
-| Copyright (C) 2005 Jorg Schuler <jcsjcs at users sourceforge net>
-| Part of the gtkpod project.
-|
-| URL: http://www.gtkpod.org/
-| URL: http://gtkpod.sourceforge.net/
-|
-|
-| The source is taken from libipoddevice, CVS version October 8 2005
-| (http://64.14.94.162/index.php/Libipoddevice).
-|
-| I decided not to make libgpod dependent on libipoddevice because
-| the latter depends on libraries not widely available yet (libhal >=
-| 0.5.2, glib >= 2.8). It is planned to replace these files with a
-| libipoddevice dependence at some later time.
-|
-| The following changes were done:
-|
-| - libhal becomes optional (see #ifdef HAVE_LIBHAL sections)
-| - g_mkdir_with_parents() is provided if not available (glib < 2.8)
-| - publicly available functions were renamed from ipod_device_...()
-| to itdb_device_...()
-|
-| Because of these changes only a limited amount of functionality is
-| available. See ipod-device.h for summary.
-|
-|
-|
-|
-| $Id$
-*/
-/* ex: set ts=4: */
-/***************************************************************************
-* ipod-device.c
-* Copyright (C) 2005 Novell
-* Written by Aaron Bockover <aaron@aaronbock.net>
-****************************************************************************/
-
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of version 2.1 of the GNU Lesser General Public
- * License as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Lesser Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
- * USA
- */
-
-
-/* JCS: Change from ipod_device... to itdb_device for public functions */
-#define ipod_device_get_type itdb_device_get_type
-#define ipod_device_new itdb_device_new
-#define ipod_device_rescan_disk itdb_device_rescan_disk
-#define ipod_device_eject itdb_device_eject
-#define ipod_device_reboot itdb_device_reboot
-#define ipod_device_debug itdb_device_debug
-#define ipod_device_save itdb_device_save
-#define ipod_device_list_devices itdb_device_list_devices
-#define ipod_device_list_device_udis itdb_device_list_device_udis
-
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
-#include "glib-compat.h"
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <fcntl.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <string.h>
-#include <ctype.h>
-#include <errno.h>
-
-#include "hal-common.h"
-#include "ipod-device.h"
-
-#define GB 1024
-
-typedef struct _IpodModel {
- const gchar *model_number;
- const guint64 capacity;
- guint model_type;
- guint generation;
-} IpodModel;
-
-
-static const IpodModel ipod_model_table [] = {
- /* Handle idiots who hose their iPod file system, or
- lucky people with iPods we don't yet know about*/
- {"Invalid", 0, MODEL_TYPE_INVALID, UNKNOWN_GENERATION},
- {"Unknown", 0, MODEL_TYPE_UNKNOWN, UNKNOWN_GENERATION},
-
- /* First Generation */
- {"8513", 5 * GB, MODEL_TYPE_REGULAR, FIRST_GENERATION},
- {"8541", 5 * GB, MODEL_TYPE_REGULAR, FIRST_GENERATION},
- {"8697", 5 * GB, MODEL_TYPE_REGULAR, FIRST_GENERATION},
- {"8709", 10 * GB, MODEL_TYPE_REGULAR, FIRST_GENERATION},
-
- /* Second Generation */
- {"8737", 10 * GB, MODEL_TYPE_REGULAR, SECOND_GENERATION},
- {"8740", 10 * GB, MODEL_TYPE_REGULAR, SECOND_GENERATION},
- {"8738", 20 * GB, MODEL_TYPE_REGULAR, SECOND_GENERATION},
- {"8741", 20 * GB, MODEL_TYPE_REGULAR, SECOND_GENERATION},
-
- /* Third Generation */
- {"8976", 10 * GB, MODEL_TYPE_REGULAR, THIRD_GENERATION},
- {"8946", 15 * GB, MODEL_TYPE_REGULAR, THIRD_GENERATION},
- {"9460", 15 * GB, MODEL_TYPE_REGULAR, THIRD_GENERATION},
- {"9244", 20 * GB, MODEL_TYPE_REGULAR, THIRD_GENERATION},
- {"8948", 30 * GB, MODEL_TYPE_REGULAR, THIRD_GENERATION},
- {"9245", 40 * GB, MODEL_TYPE_REGULAR, THIRD_GENERATION},
-
-
- /* Fourth Generation */
- {"9282", 20 * GB, MODEL_TYPE_REGULAR, FOURTH_GENERATION},
- {"9787", 25 * GB, MODEL_TYPE_REGULAR_U2, FOURTH_GENERATION},
- {"9268", 40 * GB, MODEL_TYPE_REGULAR, FOURTH_GENERATION},
- {"A079", 20 * GB, MODEL_TYPE_COLOR, FOURTH_GENERATION},
- {"A127", 20 * GB, MODEL_TYPE_COLOR_U2, FOURTH_GENERATION},
- {"9830", 60 * GB, MODEL_TYPE_COLOR, FOURTH_GENERATION},
-
- /* First Generation Mini */
- {"9160", 4 * GB, MODEL_TYPE_MINI, FIRST_GENERATION},
- {"9436", 4 * GB, MODEL_TYPE_MINI_BLUE, FIRST_GENERATION},
- {"9435", 4 * GB, MODEL_TYPE_MINI_PINK, FIRST_GENERATION},
- {"9434", 4 * GB, MODEL_TYPE_MINI_GREEN, FIRST_GENERATION},
- {"9437", 4 * GB, MODEL_TYPE_MINI_GOLD, FIRST_GENERATION},
-
- /* Second Generation Mini */
- {"9800", 4 * GB, MODEL_TYPE_MINI, SECOND_GENERATION},
- {"9802", 4 * GB, MODEL_TYPE_MINI_BLUE, SECOND_GENERATION},
- {"9804", 4 * GB, MODEL_TYPE_MINI_PINK, SECOND_GENERATION},
- {"9806", 4 * GB, MODEL_TYPE_MINI_GREEN, SECOND_GENERATION},
- {"9801", 6 * GB, MODEL_TYPE_MINI, SECOND_GENERATION},
- {"9803", 6 * GB, MODEL_TYPE_MINI_BLUE, SECOND_GENERATION},
- {"9805", 6 * GB, MODEL_TYPE_MINI_PINK, SECOND_GENERATION},
- {"9807", 6 * GB, MODEL_TYPE_MINI_GREEN, SECOND_GENERATION},
-
- /* Photo / Fourth Generation */
- {"9829", 30 * GB, MODEL_TYPE_COLOR, FOURTH_GENERATION},
- {"9585", 40 * GB, MODEL_TYPE_COLOR, FOURTH_GENERATION},
- {"9586", 60 * GB, MODEL_TYPE_COLOR, FOURTH_GENERATION},
- {"9830", 60 * GB, MODEL_TYPE_COLOR, FOURTH_GENERATION},
-
- /* Shuffle / Fourth Generation */
- {"9724", GB / 2, MODEL_TYPE_SHUFFLE, FOURTH_GENERATION},
- {"9725", GB, MODEL_TYPE_SHUFFLE, FOURTH_GENERATION},
-
- /* Nano / Fifth Generation */
- {"A350", GB * 1, MODEL_TYPE_NANO_WHITE, FIFTH_GENERATION},
- {"A352", GB * 1, MODEL_TYPE_NANO_BLACK, FIFTH_GENERATION},
- {"A004", GB * 2, MODEL_TYPE_NANO_WHITE, FIFTH_GENERATION},
- {"A099", GB * 2, MODEL_TYPE_NANO_BLACK, FIFTH_GENERATION},
- {"A005", GB * 4, MODEL_TYPE_NANO_WHITE, FIFTH_GENERATION},
- {"A107", GB * 4, MODEL_TYPE_NANO_BLACK, FIFTH_GENERATION},
-
- /* Video / Fifth Generation */
- {"A002", GB * 30, MODEL_TYPE_VIDEO_WHITE, FIFTH_GENERATION},
- {"A146", GB * 30, MODEL_TYPE_VIDEO_BLACK, FIFTH_GENERATION},
- {"A003", GB * 60, MODEL_TYPE_VIDEO_WHITE, FIFTH_GENERATION},
- {"A147", GB * 60, MODEL_TYPE_VIDEO_BLACK, FIFTH_GENERATION},
-
- /* HP iPods, need contributions for this table */
- {"E436", 40 * GB, MODEL_TYPE_REGULAR, FOURTH_GENERATION},
- {"S492", 30 * GB, MODEL_TYPE_COLOR, FOURTH_GENERATION},
-
- {NULL, 0, 0, 0}
-};
-
-static const gchar *ipod_model_name_table [] = {
- "Invalid",
- "Unknown",
- "Color",
- "Color U2",
- "Grayscale",
- "Grayscale U2",
- "Mini (Silver)",
- "Mini (Blue)",
- "Mini (Pink)",
- "Mini (Green)",
- "Mini (Gold)",
- "Shuffle",
- "Nano (White)",
- "Nano (Black)",
- "Video (White)",
- "Video (Black)",
- NULL
-};
-
-static const IpodArtworkFormat ipod_color_artwork_info[] = {
- {IPOD_COVER_SMALL, 56, 56, 1017},
- {IPOD_COVER_LARGE, 140, 140, 1016},
- {IPOD_PHOTO_SMALL, 42, 30, 1009},
- {IPOD_PHOTO_LARGE, 130, 88, 1015},
- {IPOD_PHOTO_FULL_SCREEN, 220, 176, 1013},
- {IPOD_PHOTO_TV_SCREEN, 720, 480, 1019},
- {-1, -1, -1, -1}
-};
-
-static const IpodArtworkFormat ipod_nano_artwork_info[] = {
- {IPOD_COVER_SMALL, 42, 42, 1031},
- {IPOD_COVER_LARGE, 100, 100, 1027},
- {IPOD_PHOTO_LARGE, 42, 37, 1032},
- {IPOD_PHOTO_FULL_SCREEN, 176, 132, 1023},
- {-1, -1, -1, -1}
-};
-
-static const IpodArtworkFormat ipod_video_artwork_info[] = {
- {IPOD_COVER_SMALL, 100, 100, 1028},
- {IPOD_COVER_LARGE, 200, 200, 1029},
- {IPOD_PHOTO_SMALL, 50, 41, 1036},
- {IPOD_PHOTO_LARGE, 130, 88, 1015},
- {IPOD_PHOTO_FULL_SCREEN, 320, 240, 1024},
- {IPOD_PHOTO_TV_SCREEN, 720, 480, 1019},
- {-1, -1, -1, -1}
-};
-
-/* This will be indexed using a value from the MODEL_TYPE enum */
-static const IpodArtworkFormat *ipod_artwork_info_table[] = {
- NULL, /* Invalid */
- NULL, /* Unknown */
- ipod_color_artwork_info, /* Color */
- ipod_color_artwork_info, /* Color U2 */
- NULL, /* Grayscale */
- NULL, /* Grayscale U2 */
- NULL, /* Mini (Silver) */
- NULL, /* Mini (Blue) */
- NULL, /* Mini (Pink) */
- NULL, /* Mini (Green) */
- NULL, /* Mini (Gold) */
- NULL, /* Shuffle */
- ipod_nano_artwork_info, /* Nano (White) */
- ipod_nano_artwork_info, /* Nano (Black) */
- ipod_video_artwork_info, /* Video (White) */
- ipod_video_artwork_info /* Video (Black) */
-};
-
-
-#define g_free_if_not_null(o) \
- if(o != NULL) { \
- g_free(o); \
- o = NULL; \
- }
-
-static const gchar *sysinfo_field_names [] = {
- "pszSerialNumber",
- "ModelNumStr",
- "visibleBuildID",
- NULL
-};
-
-static gchar *sysinfo_arr_get_dup(gchar *arr[], const gchar *key)
-{
- gint i = 0;
-
- for(i = 0; sysinfo_field_names[i] != NULL; i++) {
- if(g_strcasecmp(sysinfo_field_names[i], key) == 0)
- return g_strdup(arr[i]);
- }
-
- return NULL;
-}
-
-
-#if ((GLIB_MAJOR_VERSION <= 2) && (GLIB_MINOR_VERSION < 8))
-/**
- * g_mkdir_with_parents:
- * @pathname: a pathname in the GLib file name encoding
- * @mode: permissions to use for newly created directories
- *
- * Create a directory if it doesn't already exist. Create intermediate
- * parent directories as needed, too.
- *
- * Returns: 0 if the directory already exists, or was successfully
- * created. Returns -1 if an error occurred, with errno set.
- *
- * Since: 2.8 (copied from GLIB version 2.8 - JCS)
- */
-static int
-g_mkdir_with_parents (const gchar *pathname,
- int mode)
-{
- gchar *fn, *p;
-
- if (pathname == NULL || *pathname == '\0')
- {
- errno = EINVAL;
- return -1;
- }
-
- fn = g_strdup (pathname);
-
- if (g_path_is_absolute (fn))
- p = (gchar *) g_path_skip_root (fn);
- else
- p = fn;
-
- do
- {
- while (*p && !G_IS_DIR_SEPARATOR (*p))
- p++;
-
- if (!*p)
- p = NULL;
- else
- *p = '\0';
-
- if (!g_file_test (fn, G_FILE_TEST_EXISTS))
- {
- if (g_mkdir (fn, mode) == -1)
- {
- int errno_save = errno;
- g_free (fn);
- errno = errno_save;
- return -1;
- }
- }
- else if (!g_file_test (fn, G_FILE_TEST_IS_DIR))
- {
- g_free (fn);
- errno = ENOTDIR;
- return -1;
- }
- if (p)
- {
- *p++ = G_DIR_SEPARATOR;
- while (*p && G_IS_DIR_SEPARATOR (*p))
- p++;
- }
- }
- while (p);
-
- g_free (fn);
-
- return 0;
-}
-#endif
-
-
-static void ipod_device_class_init(IpodDeviceClass *klass);
-static void ipod_device_init(IpodDevice *sp);
-static void ipod_device_finalize(GObject *object);
-
-static gchar *ipod_device_read_device_info_string(FILE *fd);
-static void ipod_device_write_device_info_string(gchar *str, FILE *fd);
-
-static gboolean ipod_device_reload(IpodDevice *device);
-static void ipod_device_construct_paths(IpodDevice *device);
-static gboolean ipod_device_info_load(IpodDevice *device);
-static guint ipod_device_detect_model(IpodDevice *device);
-static gboolean ipod_device_detect_volume_info(IpodDevice *device);
-static LibHalContext *ipod_device_hal_initialize(void);
-static void ipod_device_detect_volume_used(IpodDevice *device);
-static guint64 ipod_device_dir_size(const gchar *path);
-static gboolean ipod_device_read_sysinfo(IpodDevice *device);
-static gboolean ipod_device_detect_writeable(IpodDevice *device);
-static void ipod_device_restore_reboot_preferences(IpodDevice *device);
-
-struct IpodDevicePrivate {
- LibHalContext *hal_context;
-
- /* Paths */
- gchar *device_path;
- gchar *mount_point;
- gchar *control_path;
- gchar *hal_volume_id;
-
- gchar *adv_capacity;
- guint model_index;
-
- /* DeviceInfo Fields (All Devices) */
- gchar *device_name;
- gchar *user_name;
- gchar *host_name;
-
- /* Volume Size/Usage */
- guint64 volume_size;
- guint64 volume_available;
- guint64 volume_used;
-
- /* System Info */
- gchar *serial_number;
- gchar *model_number;
- gchar *firmware_version;
-
- gchar *volume_uuid;
- gchar *volume_label;
-
- /* Fresh from the factory/restore? */
- gboolean is_new;
-
- /* Safety */
- gboolean is_ipod;
- gboolean can_write;
-};
-
-static GObjectClass *parent_class = NULL;
-
-/* GObject Class Specific Methods */
-
-GType
-ipod_device_get_type()
-{
- static GType type = 0;
-
- if(type == 0) {
- static const GTypeInfo our_info = {
- sizeof (IpodDeviceClass),
- NULL,
- NULL,
- (GClassInitFunc)ipod_device_class_init,
- NULL,
- NULL,
- sizeof (IpodDevice),
- 0,
- (GInstanceInitFunc)ipod_device_init,
- };
-
- type = g_type_register_static(G_TYPE_OBJECT,
- "IpodDevice", &our_info, 0);
- }
-
- return type;
-}
-
-static void
-ipod_device_get_property(GObject *object, guint prop_id,
- GValue *value, GParamSpec *pspec)
-{
- IpodDevice *device = IPOD_DEVICE(object);
-
- switch(prop_id) {
- case PROP_HAL_CONTEXT:
- g_value_set_pointer(value, device->priv->hal_context);
- break;
- case PROP_HAL_VOLUME_ID:
- g_value_set_string(value, device->priv->hal_volume_id);
- break;
- case PROP_MOUNT_POINT:
- g_value_set_string(value, device->priv->mount_point);
- break;
- case PROP_DEVICE_PATH:
- g_value_set_string(value, device->priv->device_path);
- break;
- case PROP_CONTROL_PATH:
- g_value_set_string(value, device->priv->control_path);
- break;
- case PROP_DEVICE_MODEL:
- g_value_set_uint(value,
- ipod_model_table[device->priv->model_index].model_type);
- break;
- case PROP_DEVICE_MODEL_STRING:
- g_value_set_string(value,
- ipod_model_name_table[ipod_model_table[
- device->priv->model_index].model_type]);
- break;
- case PROP_DEVICE_GENERATION:
- g_value_set_uint(value,
- ipod_model_table[device->priv->model_index].generation);
- break;
- case PROP_ADVERTISED_CAPACITY:
- g_value_set_string(value, device->priv->adv_capacity);
- break;
- case PROP_DEVICE_NAME:
- g_value_set_string(value, device->priv->device_name);
- break;
- case PROP_USER_NAME:
- g_value_set_string(value, device->priv->user_name);
- break;
- case PROP_HOST_NAME:
- g_value_set_string(value, device->priv->host_name);
- break;
- case PROP_VOLUME_SIZE:
- g_value_set_uint64(value, device->priv->volume_size);
- break;
- case PROP_VOLUME_AVAILABLE:
- g_value_set_uint64(value, device->priv->volume_available);
- break;
- case PROP_VOLUME_USED:
- g_value_set_uint64(value, device->priv->volume_used);
- break;
- case PROP_IS_IPOD:
- g_value_set_boolean(value, device->priv->is_ipod);
- break;
- case PROP_IS_NEW:
- g_value_set_boolean(value, device->priv->is_new);
- break;
- case PROP_SERIAL_NUMBER:
- g_value_set_string(value, device->priv->serial_number);
- break;
- case PROP_MODEL_NUMBER:
- g_value_set_string(value, device->priv->model_number);
- break;
- case PROP_FIRMWARE_VERSION:
- g_value_set_string(value, device->priv->firmware_version);
- break;
- case PROP_VOLUME_UUID:
- g_value_set_string(value, device->priv->volume_uuid);
- break;
- case PROP_VOLUME_LABEL:
- g_value_set_string(value, device->priv->volume_label);
- break;
- case PROP_CAN_WRITE:
- g_value_set_boolean(value, device->priv->can_write);
- break;
- case PROP_ARTWORK_FORMAT:
- g_value_set_pointer(value,
- (gpointer)ipod_artwork_info_table[ipod_model_table[
- device->priv->model_index].model_type]);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
- break;
- }
-}
-
-static void
-ipod_device_set_property(GObject *object, guint prop_id,
- const GValue *value, GParamSpec *pspec)
-{
- IpodDevice *device = IPOD_DEVICE(object);
- const gchar *str;
- gchar **volumes;
- gint volume_count;
-
- g_return_if_fail (device);
-
- switch(prop_id) {
- case PROP_MOUNT_POINT:
- case PROP_DEVICE_PATH:
- case PROP_HAL_VOLUME_ID:
- str = g_value_get_string(value);
- volumes = NULL;
- if (device->priv->hal_context)
- {
- volumes = libhal_manager_find_device_string_match(
- device->priv->hal_context, "block.device", str,
- &volume_count, NULL);
- if(volume_count == 0)
- {
- libhal_free_string_array(volumes);
- volumes = libhal_manager_find_device_string_match(
- device->priv->hal_context, "volume.mount_point",
- str, &volume_count, NULL);
- }
- if(volume_count >= 1)
- {
- str = volumes[0];
- }
- }
-#ifdef HAVE_LIBHAL
- g_free_if_not_null(device->priv->hal_volume_id);
- device->priv->hal_volume_id = g_strdup (str);
-#else
-/* JCS for libgpod */
- g_free (device->priv->mount_point);
- device->priv->mount_point = g_strdup (str);
-/* end JCS for libgpod */
-#endif
- if (volumes)
- libhal_free_string_array(volumes);
- device->priv->is_ipod = ipod_device_reload(device);
- break;
- case PROP_DEVICE_NAME:
- str = g_value_get_string(value);
- g_free_if_not_null(device->priv->device_name);
- device->priv->device_name = g_strdup(str);
- break;
- case PROP_USER_NAME:
- str = g_value_get_string(value);
- g_free_if_not_null(device->priv->user_name);
- device->priv->user_name = g_strdup(str);
- break;
- case PROP_HOST_NAME:
- str = g_value_get_string(value);
- g_free_if_not_null(device->priv->host_name);
- device->priv->host_name = g_strdup(str);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
- break;
- }
-}
-
-static void
-ipod_device_class_init(IpodDeviceClass *klass)
-{
- GParamSpec *hal_context_param;
- GParamSpec *hal_volume_id_param;
- GParamSpec *mount_point_param;
- GParamSpec *device_path_param;
- GParamSpec *control_path_param;
- GParamSpec *device_model_param;
- GParamSpec *device_model_string_param;
- GParamSpec *device_name_param;
- GParamSpec *user_name_param;
- GParamSpec *host_name_param;
- GParamSpec *volume_size_param;
- GParamSpec *volume_available_param;
- GParamSpec *volume_used_param;
- GParamSpec *is_ipod_param;
- GParamSpec *is_new_param;
- GParamSpec *serial_number_param;
- GParamSpec *model_number_param;
- GParamSpec *firmware_version_param;
- GParamSpec *volume_uuid_param;
- GParamSpec *volume_label_param;
- GParamSpec *can_write_param;
- GParamSpec *device_generation_param;
- GParamSpec *advertised_capacity_param;
- GParamSpec *artwork_format_param;
-
- GObjectClass *class = G_OBJECT_CLASS(klass);
-
- parent_class = g_type_class_peek_parent(klass);
- class->finalize = ipod_device_finalize;
-
- hal_context_param = g_param_spec_pointer("hal-context", "HAL Context",
- "LibHalContext handle", G_PARAM_READABLE);
-
- hal_volume_id_param = g_param_spec_string("hal-volume-id", "HAL Volume ID",
- "Volume ID of a device in HAL",
- NULL, G_PARAM_READWRITE);
-
- mount_point_param = g_param_spec_string("mount-point", "Mount Point",
- "Where iPod is mounted (parent of an iPod_Control directory)",
- NULL, G_PARAM_READWRITE);
-
- device_path_param = g_param_spec_string("device-path", "Device Path",
- "Path to raw iPod Device (/dev/sda2, for example)",
- NULL, G_PARAM_READWRITE);
-
- control_path_param = g_param_spec_string("control-path",
- "iPod_Control Path","Full path to iPod_Control",
- NULL, G_PARAM_READABLE);
-
- device_model_param = g_param_spec_uint("device-model", "Device Model",
- "Type of iPod (Regular, Photo, Shuffle)", 0, 2, 0, G_PARAM_READABLE);
-
- device_model_string_param = g_param_spec_string("device-model-string",
- "Device Model String", "String type of iPod (Regular, Shuffle)",
- NULL, G_PARAM_READABLE);
-
- device_name_param = g_param_spec_string("device-name", "Device Name",
- "The user-assigned name of their iPod", NULL, G_PARAM_READWRITE);
-
- user_name_param = g_param_spec_string("user-name", "User Name",
- "On Windows, Maybe Mac, the user account owning the iPod",
- NULL, G_PARAM_READWRITE);
-
- host_name_param = g_param_spec_string("host-name", "Host Name",
- "On Windows, Maybe Mac, the host/computer name owning the iPod",
- NULL, G_PARAM_READWRITE);
-
- volume_size_param = g_param_spec_uint64("volume-size", "Volume Size",
- "Total size of the iPod's hard drive", 0, G_MAXLONG, 0,
- G_PARAM_READABLE);
-
- volume_available_param = g_param_spec_uint64("volume-available",
- "Volume Available", "Available space on the iPod",
- 0, G_MAXLONG, 0, G_PARAM_READABLE);
-
- volume_used_param = g_param_spec_uint64("volume-used", "Volume Used",
- "How much space has been used", 0, G_MAXLONG, 0, G_PARAM_READABLE);
-
- is_ipod_param = g_param_spec_boolean("is-ipod", "Is iPod",
- "If all device checks are okay, then this is true",
- FALSE, G_PARAM_READABLE);
-
- is_new_param = g_param_spec_boolean("is-new", "Is iPod",
- "If device is fresh from factory/restore, this is true",
- FALSE, G_PARAM_READABLE);
-
- serial_number_param = g_param_spec_string("serial-number", "Serial Number",
- "Serial Number of the iPod",
- NULL, G_PARAM_READABLE);
-
- model_number_param = g_param_spec_string("model-number", "Model Number",
- "Model Number of the iPod",
- NULL, G_PARAM_READABLE);
-
- firmware_version_param = g_param_spec_string("firmware-version",
- "Firmware Version", "iPod Firmware Version",
- NULL, G_PARAM_READABLE);
-
- volume_uuid_param = g_param_spec_string("volume-uuid", "Volume UUID",
- "Volume UUID of the iPod",
- NULL, G_PARAM_READABLE);
-
- volume_label_param = g_param_spec_string("volume-label", "Volume Label",
- "Volume Label of the iPod",
- NULL, G_PARAM_READABLE);
-
- can_write_param = g_param_spec_boolean("can-write", "Can Write",
- "True if device can be written to (mounted read/write)",
- FALSE, G_PARAM_READABLE);
-
- advertised_capacity_param = g_param_spec_string("advertised-capacity",
- "Advertised Capacity", "Apple Marketed/Advertised Capacity String",
- NULL, G_PARAM_READABLE);
-
- device_generation_param = g_param_spec_uint("device-generation",
- "Generation", "Generation of the iPod",
- 0, G_MAXUINT, 0, G_PARAM_READABLE);
-
- artwork_format_param = g_param_spec_pointer("artwork-formats",
- "Artwork Format", "Support Artwork Formats", G_PARAM_READABLE);
-
- class->set_property = ipod_device_set_property;
- class->get_property = ipod_device_get_property;
- g_object_class_install_property(class, PROP_HAL_CONTEXT,
- hal_context_param);
-
- g_object_class_install_property(class, PROP_HAL_VOLUME_ID,
- hal_volume_id_param);
-
- g_object_class_install_property(class, PROP_MOUNT_POINT,
- mount_point_param);
-
- g_object_class_install_property(class, PROP_DEVICE_PATH,
- device_path_param);
-
- g_object_class_install_property(class, PROP_CONTROL_PATH,
- control_path_param);
-
- g_object_class_install_property(class, PROP_DEVICE_MODEL,
- device_model_param);
-
- g_object_class_install_property(class, PROP_DEVICE_MODEL_STRING,
- device_model_string_param);
-
- g_object_class_install_property(class, PROP_DEVICE_NAME,
- device_name_param);
-
- g_object_class_install_property(class, PROP_USER_NAME,
- user_name_param);
-
- g_object_class_install_property(class, PROP_HOST_NAME,
- host_name_param);
-
- g_object_class_install_property(class, PROP_VOLUME_SIZE,
- volume_size_param);
-
- g_object_class_install_property(class, PROP_VOLUME_AVAILABLE,
- volume_available_param);
-
- g_object_class_install_property(class, PROP_VOLUME_USED,
- volume_used_param);
-
- g_object_class_install_property(class, PROP_IS_IPOD, is_ipod_param);
-
- g_object_class_install_property(class, PROP_IS_NEW, is_new_param);
-
- g_object_class_install_property(class, PROP_SERIAL_NUMBER,
- serial_number_param);
-
- g_object_class_install_property(class, PROP_MODEL_NUMBER,
- model_number_param);
-
- g_object_class_install_property(class, PROP_FIRMWARE_VERSION,
- firmware_version_param);
-
- g_object_class_install_property(class, PROP_VOLUME_UUID,
- volume_uuid_param);
-
- g_object_class_install_property(class, PROP_VOLUME_LABEL,
- volume_label_param);
-
- g_object_class_install_property(class, PROP_CAN_WRITE,
- can_write_param);
-
- g_object_class_install_property(class, PROP_DEVICE_GENERATION,
- device_generation_param);
-
- g_object_class_install_property(class, PROP_ADVERTISED_CAPACITY,
- advertised_capacity_param);
-
- g_object_class_install_property(class, PROP_ARTWORK_FORMAT,
- artwork_format_param);
-
-}
-
-static void
-ipod_device_init(IpodDevice *device)
-{
- device->priv = g_new0(IpodDevicePrivate, 1);
-
- device->priv->hal_context = ipod_device_hal_initialize();
-
- device->priv->hal_volume_id = NULL;
- device->priv->mount_point = NULL;
- device->priv->device_path = NULL;
- device->priv->control_path = NULL;
- device->priv->device_name = NULL;
- device->priv->user_name = NULL;
- device->priv->host_name = NULL;
- device->priv->adv_capacity = NULL;
- device->priv->serial_number = NULL;
- device->priv->model_number = NULL;
- device->priv->firmware_version = NULL;
- device->priv->volume_uuid = NULL;
- device->priv->volume_label = NULL;
-
- device->priv->volume_size = 0;
- device->priv->volume_available = 0;
- device->priv->volume_used = 0;
-
- device->priv->is_new = FALSE;
- device->priv->can_write = FALSE;
-}
-
-static void
-ipod_device_finalize(GObject *object)
-{
- IpodDevice *device = IPOD_DEVICE(object);
-
- /* Free private members, etc. */
- g_free_if_not_null(device->priv->hal_volume_id);
- g_free_if_not_null(device->priv->device_path);
- g_free_if_not_null(device->priv->mount_point);
- g_free_if_not_null(device->priv->control_path);
- g_free_if_not_null(device->priv->device_name);
- g_free_if_not_null(device->priv->user_name);
- g_free_if_not_null(device->priv->host_name);
- g_free_if_not_null(device->priv->adv_capacity);
- g_free_if_not_null(device->priv->serial_number);
- g_free_if_not_null(device->priv->model_number);
- g_free_if_not_null(device->priv->firmware_version);
- g_free_if_not_null(device->priv->volume_uuid);
- g_free_if_not_null(device->priv->volume_label);
-
- if(device->priv->hal_context != NULL) {
- libhal_ctx_shutdown(device->priv->hal_context, NULL);
- libhal_ctx_free(device->priv->hal_context);
- }
- g_free(device->priv);
- G_OBJECT_CLASS(parent_class)->finalize(object);
-}
-
-/* PRIVATE METHODS */
-
-LibHalContext *
-ipod_device_hal_initialize()
-{
-#ifdef HAVE_LIBHAL
- LibHalContext *hal_context;
- DBusError error;
- DBusConnection *dbus_connection;
- char **devices;
- gint device_count;
-
- hal_context = libhal_ctx_new();
- if(hal_context == NULL)
- return NULL;
-
- dbus_error_init(&error);
- dbus_connection = dbus_bus_get(DBUS_BUS_SYSTEM, &error);
- if(dbus_error_is_set(&error)) {
- dbus_error_free(&error);
- libhal_ctx_free(hal_context);
- return NULL;
- }
-
- libhal_ctx_set_dbus_connection(hal_context, dbus_connection);
-
- if(!libhal_ctx_init(hal_context, &error)) {
- dbus_error_free(&error);
- libhal_ctx_free(hal_context);
- return NULL;
- }
-
- devices = libhal_get_all_devices(hal_context, &device_count, NULL);
- if(devices == NULL) {
- libhal_ctx_shutdown(hal_context, NULL);
- libhal_ctx_free(hal_context);
- hal_context = NULL;
- return NULL;
- }
-
- libhal_free_string_array(devices);
-
- return hal_context;
-#else
- return NULL;
-#endif
-}
-
-gboolean
-ipod_device_reload(IpodDevice *device)
-{
- g_return_val_if_fail(IS_IPOD_DEVICE(device), FALSE);
-
- device->priv->model_index = 0;
-
- if(!ipod_device_detect_volume_info(device))
- return FALSE;
-
- ipod_device_construct_paths(device);
-
- device->priv->is_new = !ipod_device_info_load(device);
-
- ipod_device_detect_volume_used(device);
- ipod_device_detect_writeable(device);
- ipod_device_read_sysinfo(device);
- ipod_device_detect_model(device);
- ipod_device_restore_reboot_preferences(device);
-
- return device->priv->model_index != 0;
-}
-
-void
-ipod_device_construct_paths(IpodDevice *device)
-{
- int len;
-
- g_return_if_fail(IS_IPOD_DEVICE(device));
- g_return_if_fail(device->priv->mount_point != NULL);
-
- len = strlen(device->priv->mount_point);
- if(device->priv->mount_point[len - 1] == '/')
- device->priv->mount_point[len - 1] = '\0';
-
- if(strlen(device->priv->mount_point) == 0)
- return;
-
- device->priv->control_path = g_strdup_printf("%s/%s",
- device->priv->mount_point, "iPod_Control/");
-}
-
-gchar *
-ipod_device_read_device_info_string(FILE *fd)
-{
- gshort length;
- gunichar2 *utf16;
- gchar *utf8;
-
- if (fread(&length, sizeof(gshort), 1, fd) != 1)
- return NULL;
-
- if(length <= 0)
- return NULL;
-
- utf16 = (gunichar2 *)g_malloc(length * sizeof(gunichar2));
- if (fread(utf16, sizeof(gunichar2), length, fd) != length)
- return NULL;
-
- if(utf16 == NULL)
- return NULL;
-
- utf8 = g_utf16_to_utf8(utf16, length, NULL, NULL, NULL);
-
- g_free(utf16);
- utf16 = NULL;
-
- return utf8;
-}
-
-void
-ipod_device_write_device_info_string(gchar *str, FILE *fd)
-{
- gunichar2 *unistr;
- gshort length;
- size_t res;
-
- if(str == NULL)
- return;
-
- length = strlen(str);
- unistr = g_utf8_to_utf16(str, length, NULL, NULL, NULL);
-
- length = length > 0x198 ? 0x198 : length;
-
- /* FIXME: we do not check if the write was successful */
- res = fwrite(&length, 2, 1, fd);
- res = fwrite(unistr, 2, length, fd);
-
- g_free(unistr);
-}
-
-gboolean
-ipod_device_read_sysinfo(IpodDevice *device)
-{
- gchar *field_values[sizeof(sysinfo_field_names) + 1];
- gchar *tmp, *path, buf[512];
- gint i, name_len;
- FILE *fd;
-
- g_return_val_if_fail(IS_IPOD_DEVICE(device), FALSE);
-
- path = g_strdup_printf("%sDevice/SysInfo",
- device->priv->control_path);
-
- fd = fopen(path, "r");
- if(fd == NULL) {
- g_free(path);
- return FALSE;
- }
-
- while(fgets(buf, sizeof(buf), fd)) {
- buf[strlen(buf) - 1] = '\0';
-
- for(i = 0; sysinfo_field_names[i] != NULL; i++) {
- name_len = strlen(sysinfo_field_names[i]);
- if(strncasecmp(buf, sysinfo_field_names[i], name_len) == 0) {
- field_values[i] = strdup(buf + name_len + 2);
- if(strncasecmp(field_values[i], "0x", 2) == 0) {
- if((tmp = strstr(field_values[i], "(")) != NULL) {
- field_values[i] = tmp + 1;
- field_values[i][strlen(field_values[i]) - 1] = '\0';
- }
- }
-
- field_values[i] = g_strdup(field_values[i]);
- }
- }
- }
-
- fclose(fd);
-
- device->priv->serial_number = sysinfo_arr_get_dup(field_values,
- "pszSerialNumber");
- device->priv->model_number = sysinfo_arr_get_dup(field_values,
- "ModelNumStr");
- device->priv->firmware_version = sysinfo_arr_get_dup(field_values,
- "visibleBuildID");
-
- g_free(path);
-
- return TRUE;
-}
-
-gboolean
-ipod_device_info_load(IpodDevice *device)
-{
- gchar *path;
- FILE *fd;
- gint intres;
-
- g_return_val_if_fail(IS_IPOD_DEVICE(device), FALSE);
-
- path = g_strdup_printf("%siTunes/DeviceInfo",
- device->priv->control_path);
-
- fd = fopen(path, "r");
- if(fd == NULL) {
- g_free(path);
- return FALSE;
- }
-
- device->priv->device_name = ipod_device_read_device_info_string(fd);
- if(device->priv->device_name == NULL)
- device->priv->device_name = g_strdup("iPod");
-
- intres=fseek(fd, 0x200, SEEK_SET);
- device->priv->user_name = ipod_device_read_device_info_string(fd);
-
- intres=fseek(fd, 0x400, SEEK_SET);
- device->priv->host_name = ipod_device_read_device_info_string(fd);
-
- fclose(fd);
- g_free(path);
-
- return TRUE;
-}
-
-gboolean
-ipod_device_detect_writeable(IpodDevice *device)
-{
- FILE *fp;
- gchar *itunes_dir, *music_dir, *itunesdb_path;
- struct stat finfo;
-
- g_return_val_if_fail(IS_IPOD_DEVICE(device), FALSE);
-
- device->priv->can_write = FALSE;
-
- itunes_dir = g_strdup_printf("%siTunes", device->priv->control_path);
-
- if(!g_file_test(itunes_dir, G_FILE_TEST_IS_DIR)) {
- if(g_mkdir_with_parents(itunes_dir, 0755) != 0) {
- g_free(itunes_dir);
- return FALSE;
- }
- }
-
- itunesdb_path = g_strdup_printf("%s/iTunesDB", itunes_dir);
-
- if((fp = fopen(itunesdb_path, "a+")) != NULL) {
- device->priv->can_write = TRUE;
- fclose(fp);
-
- memset(&finfo, 0, sizeof(finfo));
- if(stat(itunesdb_path, &finfo) == 0) {
- if(finfo.st_size == 0) {
- unlink(itunesdb_path);
- }
- }
- } else {
- g_free(itunes_dir);
- g_free(itunesdb_path);
- return FALSE;
- }
-
- music_dir = g_strdup_printf("%sMusic", device->priv->control_path);
-
- if(!g_file_test(music_dir, G_FILE_TEST_IS_DIR)) {
- device->priv->can_write = g_mkdir_with_parents(music_dir, 0755) == 0;
- }
-
- g_free(itunes_dir);
- g_free(itunesdb_path);
- g_free(music_dir);
-
- return device->priv->can_write;
-}
-
-static gint
-ipod_device_get_model_index_from_table(const gchar *_model_num)
-{
- gint i;
- gchar *model_num = g_strdup(_model_num);
- gchar *p = model_num;
-
- if(isalpha(model_num[0]))
- p++;
-
- for(i = 2; ipod_model_table[i].model_number != NULL; i++) {
- if(g_strncasecmp(p, ipod_model_table[i].model_number, 4) == 0) {
- g_free(model_num);
- return i;
- }
- }
-
- g_free(model_num);
- return 1;
-}
-
-guint
-ipod_device_detect_model(IpodDevice *device)
-{
- gint i;
- guint64 adv, act;
- gint cap;
-
- g_return_val_if_fail(IS_IPOD_DEVICE(device), 0);
-
- device->priv->model_index = 0;
-
- /* Shuffle! */
- if(device->priv->model_number == NULL) {
- for(i = 2; ipod_model_table[i].model_number != NULL; i++) {
- if(ipod_model_table[i].model_type != MODEL_TYPE_SHUFFLE)
- continue;
-
- cap = ipod_model_table[i].capacity;
- adv = cap * 1048576;
- act = device->priv->volume_size;
-
- if((adv - act) / 1048576 < 50) {
- device->priv->model_index = i;
- device->priv->model_number = g_strdup_printf("M%s",
- ipod_model_table[i].model_number);
-
- device->priv->adv_capacity = g_strdup_printf("%d %s",
- cap < 1024 ? cap : cap / 1024,
- cap < 1024 ? "MB" : "GB");
- break;
- }
- }
- } else {
- /* Anything Else */
- device->priv->model_index =
- ipod_device_get_model_index_from_table(device->priv->model_number);
-
- cap = ipod_model_table[device->priv->model_index].capacity;
-
- device->priv->adv_capacity = g_strdup_printf("%d %s",
- cap < 1024 ? cap : cap / 1024,
- cap < 1024 ? "MB" : "GB");
- }
-
- return device->priv->model_index;
-}
-
-void
-ipod_device_restore_reboot_preferences(IpodDevice *device)
-{
- gchar *backup_prefs, *prefs;
-
- backup_prefs = g_strdup_printf("%s/.Reboot_Preferences",
- device->priv->control_path);
- prefs = g_strdup_printf("%s/Device/Preferences",
- device->priv->control_path);
-
- g_return_if_fail(IS_IPOD_DEVICE(device));
-
- if(g_file_test(backup_prefs, G_FILE_TEST_EXISTS)) {
- unlink(prefs);
- g_rename(backup_prefs, prefs);
- }
-}
-
-gboolean
-ipod_device_detect_volume_info(IpodDevice *device)
-{
-#ifdef HAVE_LIBHAL
- LibHalContext *hal_context;
- gchar **volumes;
- gchar *hd_mount_point, *hd_device_path;
- gchar *hd_hal_id = NULL, *maybe_hd_hal_id = NULL;
- gint volume_count, i;
-
- g_return_val_if_fail(IS_IPOD_DEVICE(device), FALSE);
- hal_context = device->priv->hal_context;
-
- g_free_if_not_null(device->priv->device_path);
- g_free_if_not_null(device->priv->mount_point);
- device->priv->volume_size = 0;
-
- if(!libhal_device_exists(hal_context, device->priv->hal_volume_id, NULL)) {
- /* For testing/debugging... we don't have a real device, but
- the location may be a directory containing an iPod image */
- if(g_strncasecmp(device->priv->hal_volume_id, "/dev/", 5) == 0 ||
- device->priv->hal_volume_id[0] != '/')
- return FALSE;
-
- g_free_if_not_null(device->priv->mount_point);
- device->priv->mount_point = g_strdup(device->priv->hal_volume_id);
-
- g_free_if_not_null(device->priv->hal_volume_id);
- g_free_if_not_null(device->priv->device_path);
-
- /* Let's find out about the disk drive containing our image */
-
- volumes = libhal_manager_find_device_string_match(hal_context,
- "info.category", "volume", &volume_count, NULL);
-
- for(i = 0; i < volume_count; i++) {
- if(!libhal_device_property_exists(hal_context,
- volumes[i], "volume.is_mounted", NULL) ||
- !libhal_device_get_property_bool(hal_context,
- volumes[i], "volume.is_mounted", NULL)) {
- continue;
- }
-
- hd_mount_point = libhal_device_get_property_string(hal_context,
- volumes[i], "volume.mount_point", NULL);
-
- if(g_strncasecmp(hd_mount_point, device->priv->mount_point,
- strlen(hd_mount_point)) != 0)
- continue;
-
- if(g_strcasecmp(hd_mount_point, "/") == 0)
- maybe_hd_hal_id = volumes[i];
- else
- hd_hal_id = volumes[i];
- }
-
- if(hd_hal_id == NULL && maybe_hd_hal_id != NULL)
- hd_hal_id = maybe_hd_hal_id;
-
- if(hd_hal_id == NULL) {
- libhal_free_string_array(volumes);
- return FALSE;
- }
-
- if(!libhal_device_exists(hal_context, hd_hal_id, NULL)) {
- libhal_free_string_array(volumes);
- return FALSE;
- }
-
- hd_device_path = libhal_device_get_property_string(hal_context,
- hd_hal_id, "block.device", NULL);
-
- device->priv->hal_volume_id = g_strdup(hd_hal_id);
- device->priv->device_path = g_strdup(hd_device_path);
- device->priv->volume_size = libhal_device_get_property_uint64(
- hal_context, hd_hal_id, "volume.size", NULL);
-
- libhal_free_string_array(volumes);
-
- return TRUE;
- }
-
- if(!libhal_device_property_exists(hal_context,
- device->priv->hal_volume_id, "volume.is_mounted", NULL)
- || !libhal_device_get_property_bool(hal_context,
- device->priv->hal_volume_id, "volume.is_mounted", NULL)) {
- return FALSE;
- }
-
- if(libhal_device_property_exists(hal_context, device->priv->hal_volume_id,
- "block.device", NULL))
- device->priv->device_path = libhal_device_get_property_string(
- hal_context, device->priv->hal_volume_id, "block.device", NULL);
-
- if(libhal_device_property_exists(hal_context, device->priv->hal_volume_id,
- "volume.mount_point", NULL))
- device->priv->mount_point = libhal_device_get_property_string(
- hal_context, device->priv->hal_volume_id,
- "volume.mount_point", NULL);
-
- if(libhal_device_property_exists(hal_context, device->priv->hal_volume_id,
- "volume.size", NULL))
- device->priv->volume_size = libhal_device_get_property_uint64(
- hal_context, device->priv->hal_volume_id, "volume.size", NULL);
-
- if(libhal_device_property_exists(hal_context, device->priv->hal_volume_id,
- "volume.uuid", NULL)) {
- device->priv->volume_uuid = libhal_device_get_property_string(
- hal_context, device->priv->hal_volume_id,
- "volume.uuid", NULL);
-
- if(strlen(device->priv->volume_uuid) == 0) {
- g_free(device->priv->volume_uuid);
- device->priv->volume_uuid = NULL;
- }
- }
-
- if(libhal_device_property_exists(hal_context, device->priv->hal_volume_id,
- "volume.label", NULL))
- device->priv->volume_label = libhal_device_get_property_string(
- hal_context, device->priv->hal_volume_id,
- "volume.label", NULL);
-#endif
- return TRUE;
-}
-
-void
-ipod_device_detect_volume_used(IpodDevice *device)
-{
- device->priv->volume_used =
- ipod_device_dir_size(device->priv->mount_point);
- device->priv->volume_available = device->priv->volume_size -
- device->priv->volume_used;
-}
-
-static void
-_ipod_device_dir_size(const gchar *path, guint64 *total_size)
-{
- GDir *dir;
- const gchar *next_path;
- gchar *fullpath;
- struct stat finfo;
-
- if((dir = g_dir_open(path, 0, NULL)) == NULL)
- return;
-
- while((next_path = g_dir_read_name(dir)) != NULL) {
- fullpath = g_strdup_printf("%s/%s", path, next_path);
-
- if(g_file_test(fullpath, G_FILE_TEST_IS_DIR))
- _ipod_device_dir_size(fullpath, total_size);
- else
- *total_size += stat(fullpath, &finfo) == 0 ? finfo.st_size : 0;
-
- g_free(fullpath);
- fullpath = NULL;
- }
-
- g_dir_close(dir);
-}
-
-guint64
-ipod_device_dir_size(const gchar *path)
-{
- guint64 retsize, *size = g_new(guint64, 1);
- *size = 0;
- _ipod_device_dir_size(path, size);
- retsize = *size;
- g_free(size);
- return retsize;
-}
-
-#ifdef HAVE_LIBHAL
-static gboolean
-ipod_device_has_open_fd(IpodDevice *device)
-{
- GDir *dir, *fddir;
- gchar *fdpath, *fdidpath, *realpath;
- const gchar *procpath, *fdid;
-
- g_return_val_if_fail(IS_IPOD_DEVICE(device), FALSE);
-
- if((dir = g_dir_open("/proc", 0, NULL)) == NULL)
- return FALSE;
-
- while((procpath = g_dir_read_name(dir)) != NULL) {
- if(atoi(procpath) <= 0)
- continue;
-
- fdpath = g_strdup_printf("/proc/%s/fd", procpath);
-
- if(!g_file_test(fdpath, G_FILE_TEST_IS_DIR)) {
- g_free(fdpath);
- continue;
- }
-
- if((fddir = g_dir_open(fdpath, 0, NULL)) == NULL) {
- g_free(fdpath);
- continue;
- }
-
- while((fdid = g_dir_read_name(fddir)) != NULL) {
- fdidpath = g_strdup_printf("%s/%s", fdpath, fdid);
- realpath = g_file_read_link(fdidpath, NULL);
-
- if(realpath == NULL) {
- g_free(fdidpath);
- continue;
- }
-
- if(g_strncasecmp(realpath, device->priv->mount_point,
- strlen(device->priv->mount_point)) == 0) {
- g_dir_close(fddir);
- g_dir_close(dir);
- g_free(realpath);
- g_free(fdidpath);
- return TRUE;
- }
-
- g_free(realpath);
- g_free(fdidpath);
- }
-
- g_dir_close(fddir);
- }
-
- g_dir_close(dir);
-
- return FALSE;
-}
-
-/* modded from g-v-m */
-static int
-ipod_device_run_command(IpodDevice *device, const char *command,
- GError **error_out)
-{
- char *path;
- const char *inptr, *start;
- GError *error = NULL;
- GString *exec;
- char *argv[4];
- int status = 0;
-
- exec = g_string_new(NULL);
-
- /* perform s/%d/device/, s/%m/mount_point/ and s/%h/udi/ */
- start = inptr = command;
- while((inptr = strchr (inptr, '%')) != NULL) {
- g_string_append_len(exec, start, inptr - start);
- inptr++;
- switch (*inptr) {
- case 'd':
- g_string_append(exec, device->priv->device_path ?
- device->priv->device_path : "");
- break;
- case 'm':
- if(device->priv->mount_point) {
- path = g_shell_quote(device->priv->mount_point);
- g_string_append(exec, path);
- g_free(path);
- } else {
- g_string_append(exec, "\"\"");
- }
- break;
- case 'h':
- g_string_append(exec, device->priv->hal_volume_id);
- break;
- case '%':
- g_string_append_c(exec, '%');
- break;
- default:
- g_string_append_c(exec, '%');
- if(*inptr)
- g_string_append_c(exec, *inptr);
- break;
- }
-
- if(*inptr)
- inptr++;
- start = inptr;
- }
-
- g_string_append(exec, start);
-
- argv[0] = "/bin/sh";
- argv[1] = "-c";
- argv[2] = exec->str;
- argv[3] = NULL;
-
- g_spawn_sync(g_get_home_dir(), argv, NULL, 0, NULL,
- NULL, NULL, NULL, &status, &error);
-
- if(error != NULL)
- g_propagate_error(error_out, error);
-
- g_string_free(exec, TRUE);
-
- return status;
-}
-#endif
-
-/* PUBLIC METHODS */
-
-IpodDevice *
-ipod_device_new(const gchar *hal_volume_id)
-{
- IpodDevice *device = g_object_new(TYPE_IPOD_DEVICE,
- "hal-volume-id", hal_volume_id, NULL);
-
- if (device == NULL) {
- /* This can happen if one forgot to call g_type_init before
- * calling ipod_device_new
- */
- return NULL;
- }
-
- if(!device->priv->is_ipod) {
- g_object_unref(device);
- return NULL;
- }
-
- return device;
-}
-
-gboolean
-ipod_device_rescan_disk(IpodDevice *device)
-{
- g_return_val_if_fail(IS_IPOD_DEVICE(device), FALSE);
- ipod_device_detect_volume_used(device);
- return TRUE;
-}
-
-guint
-ipod_device_eject(IpodDevice *device, GError **error_out)
-{
-#ifdef HAVE_LIBHAL
- gint exit_status;
- GError *error = NULL;
-
- g_return_val_if_fail(IS_IPOD_DEVICE(device), EJECT_ERROR);
- g_return_val_if_fail(device->priv->is_ipod, EJECT_ERROR);
-
- if(ipod_device_has_open_fd(device))
- return EJECT_BUSY;
-
-#ifdef ASSUME_SUBMOUNT
- sync();
-
- exit_status = ipod_device_run_command(device, EJECT_COMMAND, &error);
- if(error) {
- g_propagate_error(error_out, error);
- return EJECT_ERROR;
- }
-
- return exit_status == 0 ? EJECT_OK : EJECT_ERROR;
-#endif
-
- exit_status = ipod_device_run_command(device, UNMOUNT_COMMAND, &error);
-
- if(!error && exit_status == 0) {
- exit_status = ipod_device_run_command(device, EJECT_COMMAND, &error);
- if(error) {
- g_propagate_error(error_out, error);
- return EJECT_ERROR;
- }
-
- return exit_status == 0 ? EJECT_OK : EJECT_ERROR;
- }
-
- if(error)
- g_propagate_error(error_out, error);
-
- return EJECT_ERROR;
-}
-
-guint
-ipod_device_reboot(IpodDevice *device, GError **error_out)
-{
- gchar *sysinfo, *prefs, *backup_prefs, *devpath;
- gboolean can_eject = TRUE;
-
- g_return_val_if_fail(IS_IPOD_DEVICE(device), EJECT_ERROR);
- g_return_val_if_fail(device->priv->is_ipod, EJECT_ERROR);
-
- devpath = g_strdup_printf("%s/Device/", device->priv->control_path);
- sysinfo = g_strdup_printf("%sSysInfo", devpath);
- prefs = g_strdup_printf("%sPreferences", devpath);
- backup_prefs = g_strdup_printf("%s/.Reboot_Preferences",
- device->priv->control_path);
-
- if(g_file_test(sysinfo, G_FILE_TEST_EXISTS))
- can_eject = unlink(sysinfo) == 0;
-
- if(g_file_test(prefs, G_FILE_TEST_EXISTS) && can_eject) {
- if(g_file_test(backup_prefs, G_FILE_TEST_EXISTS))
- unlink(backup_prefs);
-
- g_rename(prefs, backup_prefs);
- unlink(prefs);
-
- can_eject = TRUE;
- }
-
- if(can_eject)
- can_eject = rmdir(devpath) == 0;
-
- g_free(devpath);
- g_free(sysinfo);
- g_free(prefs);
- g_free(backup_prefs);
-
- if(can_eject)
- return ipod_device_eject(device, error_out);
-
- g_propagate_error(error_out, g_error_new(g_quark_from_string("UNLINK"),
- errno, "Could not remove file to initiate iPod reboot"));
-#endif
- return EJECT_ERROR;
-}
-
-static GList *
-_ipod_device_list_devices(gboolean create_device)
-{
- LibHalContext *hal_context;
- GList *finalDevices = NULL;
- gchar **ipods, **volumes;
- gint ipod_count, volume_count, i, j;
- IpodDevice *ipod;
- gboolean validIpod = FALSE;
-
- hal_context = ipod_device_hal_initialize();
- if(hal_context == NULL)
- return NULL;
-
- ipods = libhal_manager_find_device_string_match(hal_context,
- "info.product", "iPod", &ipod_count, NULL);
-
- for(i = 0; i < ipod_count; i++) {
- volumes = libhal_manager_find_device_string_match(hal_context,
- "info.parent", ipods[i], &volume_count, NULL);
-
- for(j = 0; j < volume_count; j++) {
- if(!libhal_device_property_exists(hal_context,
- volumes[j], "volume.is_mounted", NULL)
- || !libhal_device_get_property_bool(hal_context,
- volumes[j], "volume.is_mounted", NULL))
- continue;
-
- if(!create_device) {
- finalDevices = g_list_append(finalDevices,
- g_strdup(volumes[j]));
- continue;
- }
-
- if((ipod = ipod_device_new(volumes[j])) == NULL)
- continue;
-
- g_object_get(ipod, "is-ipod", &validIpod, NULL);
- if(validIpod)
- finalDevices = g_list_append(finalDevices, ipod);
- }
- }
-
- libhal_ctx_shutdown(hal_context, NULL);
- libhal_ctx_free(hal_context);
-
- return finalDevices;
-}
-
-GList *
-ipod_device_list_devices()
-{
- return _ipod_device_list_devices(TRUE);
-}
-
-GList *
-ipod_device_list_device_udis()
-{
- return _ipod_device_list_devices(FALSE);
-}
-
-gboolean
-ipod_device_save(IpodDevice *device, GError **error_out)
-{
- FILE *fd;
- gchar *path, *itunes_dir;
- gchar bs = 0;
- GError *error = NULL;
- size_t res;
- gint intres;
-
- g_return_val_if_fail(IS_IPOD_DEVICE(device), FALSE);
-
- itunes_dir = g_strdup_printf("%siTunes", device->priv->control_path);
- path = g_strdup_printf("%s/DeviceInfo", itunes_dir);
-
- if(!g_file_test(itunes_dir, G_FILE_TEST_IS_DIR)) {
- if(g_mkdir_with_parents(itunes_dir, 0744) != 0) {
- if(error_out != NULL) {
- error = g_error_new(g_quark_from_static_string("IPOD_DEVICE"),
- ERROR_SAVE, "Could not create iTunes Directory: %s",
- itunes_dir);
- g_propagate_error(error_out, error);
- }
-
- g_free(path);
- g_free(itunes_dir);
-
- return FALSE;
- }
- }
-
- fd = fopen(path, "w+");
- if(fd == NULL) {
- if(error_out != NULL) {
- error = g_error_new(g_quark_from_static_string("IPOD_DEVICE"),
- ERROR_SAVE, "Could not save DeviceInfo file: %s", path);
- g_propagate_error(error_out, error);
- }
-
- g_free(path);
- g_free(itunes_dir);
-
- return FALSE;
- }
-
- ipod_device_write_device_info_string(device->priv->device_name, fd);
-
- fseek(fd, 0x200, SEEK_SET);
- ipod_device_write_device_info_string(device->priv->user_name, fd);
-
- intres = fseek(fd, 0x400, SEEK_SET);
- ipod_device_write_device_info_string(device->priv->host_name, fd);
-
- intres = fseek(fd, 0X5FF, SEEK_SET);
- /* FIXME: we do not check if the write was successful */
- res = fwrite(&bs, 1, 1, fd);
-
- fclose(fd);
-
- g_free(path);
- g_free(itunes_dir);
-
- return TRUE;
-}
-
-void
-ipod_device_debug(IpodDevice *device)
-{
- static const gchar *generation_names [] = {
- "Unknown",
- "First",
- "Second",
- "Third",
- "Fourth"
- };
-
- gchar *device_path, *mount_point, *control_path, *hal_id;
- gchar *model_number, *adv_capacity, *model_string;
- guint model, generation;
- gboolean is_new, can_write;
- gchar *serial_number, *firmware_version;
- guint64 volume_size, volume_used, volume_available;
- gchar *volume_uuid, *volume_label;
- gchar *device_name, *user_name, *host_name;
-
- g_return_if_fail(IS_IPOD_DEVICE(device));
-
- g_object_get(device,
- "device-path", &device_path,
- "mount-point", &mount_point,
- "control-path", &control_path,
- "hal-volume-id", &hal_id,
- "model-number", &model_number,
- "device-model", &model,
- "device-model-string", &model_string,
- "device-generation", &generation,
- "advertised-capacity", &adv_capacity,
- "is-new", &is_new,
- "can-write", &can_write,
- "serial-number", &serial_number,
- "firmware-version", &firmware_version,
- "volume-size", &volume_size,
- "volume-used", &volume_used,
- "volume-available", &volume_available,
- "volume_uuid", &volume_uuid,
- "volume-label", &volume_label,
- "device-name", &device_name,
- "user-name", &user_name,
- "host-name", &host_name,
- NULL);
-
- g_printf("Path Info\n");
- g_printf(" Device Path: %s\n", device_path);
- g_printf(" Mount Point: %s\n", mount_point);
- g_printf(" Control Path: %s\n", control_path);
- g_printf(" HAL ID: %s\n", hal_id);
-
- g_printf("Device Info\n");
- g_printf(" Model Number: %s\n", model_number);
- g_printf(" Device Model: %s\n", model_string);
- g_printf(" iPod Generation: %s\n", generation_names[generation]);
- g_printf(" Adv. Capacity: %s\n", adv_capacity);
- g_printf(" Is New: %s\n", is_new ? "YES" : "NO");
- g_printf(" Writeable: %s\n", can_write ? "YES" : "NO");
- g_printf(" Serial Number: %s\n", serial_number);
- g_printf(" Firmware Version: %s\n", firmware_version);
- g_printf("Volume Info\n");
- g_printf(" Volume Size: %lld\n", (long long int)volume_size);
- g_printf(" Volume Used: %lld\n", (long long int)volume_used);
- g_printf(" Available %lld\n", (long long int)volume_available);
- g_printf(" UUID: %s\n", volume_uuid);
- g_printf(" Label %s\n", volume_label);
- g_printf("User-Provided Info\n");
- g_printf(" Device Name: %s\n", device_name);
- g_printf(" User Name: %s\n", user_name);
- g_printf(" Host Name: %s\n", host_name);
-
- g_printf("\n");
- fflush(stdout);
-}