summaryrefslogtreecommitdiffstats
path: root/src
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
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')
-rw-r--r--src/Makefile.am8
-rw-r--r--src/db-artwork-parser.c48
-rw-r--r--src/db-artwork-writer.c10
-rw-r--r--src/db-image-parser.c20
-rw-r--r--src/db-image-parser.h5
-rw-r--r--src/hal-common.c95
-rw-r--r--src/hal-common.h95
-rw-r--r--src/ipod-device.c1832
-rw-r--r--src/ipod-device.h196
-rw-r--r--src/itdb.h29
-rw-r--r--src/itdb_artwork.c31
-rw-r--r--src/itdb_device.c431
-rw-r--r--src/itdb_device.h126
-rw-r--r--src/itdb_itunesdb.c298
-rw-r--r--src/itdb_private.h2
-rw-r--r--src/itdb_track.c24
-rw-r--r--src/ithumb-writer.c77
17 files changed, 909 insertions, 2418 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index dfc0a66..11feb18 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -18,14 +18,12 @@ libgpod_la_SOURCES = \
db-itunes-parser.h \
db-artwork-writer.c \
ithumb-writer.c \
- ipod-device.c \
- ipod-device.h \
- hal-common.c \
- hal-common.h \
+ itdb_device.c \
+ itdb_device.h \
glib-compat.h
-libgpod_la_headers = itdb.h ipod-device.h
+libgpod_la_headers = itdb.h
libgpod_la_noinst_headers = itdb_private.h hal-common.h
libgpod_la_LDFLAGS = -version-info $(LIBGPOD_CURRENT):$(LIBGPOD_REVISION):$(LIBGPOD_AGE) \
-no-undefined
diff --git a/src/db-artwork-parser.c b/src/db-artwork-parser.c
index 8731050..0599b78 100644
--- a/src/db-artwork-parser.c
+++ b/src/db-artwork-parser.c
@@ -27,6 +27,8 @@
#endif
#include <string.h>
+#include <sys/stat.h>
+#include <sys/types.h>
#include "itdb.h"
#include "db-artwork-debug.h"
@@ -440,21 +442,38 @@ parse_mhfd (DBParseContext *ctx, Itdb_iTunesDB *db, GError **error)
G_GNUC_INTERNAL char *
ipod_db_get_artwork_db_path (const char *mount_point)
{
- gchar *filename;
- const char *paths[] = {"iPod_Control", "Artwork", "ArtworkDB", NULL};
- filename = itdb_resolve_path (mount_point, paths);
+ gchar *filename=NULL;
+
+ /* fail silently if no mount point given */
+ if (!mount_point) return NULL;
+
+ filename = itdb_get_artworkdb_path (mount_point);
/* itdb_resolve_path() only returns existing paths */
if (!filename)
{
- gchar *path;
- paths[2] = NULL;
- path = itdb_resolve_path (mount_point, (const char **)paths);
- if (path)
+ gchar *artwork_dir;
+
+ artwork_dir = itdb_get_artwork_dir (mount_point);
+ if (!artwork_dir)
+ {
+ /* attempt to create Artwork dir */
+ gchar *control_dir = itdb_get_control_dir (mount_point);
+ gchar *dir;
+ if (control_dir)
+ {
+ dir = g_build_filename (control_dir, "Artwork", NULL);
+ mkdir (dir, 0777);
+ g_free (dir);
+ g_free (control_dir);
+ }
+ }
+ if (artwork_dir)
{
- filename = g_build_filename (path, "ArtworkDB", NULL);
+ filename = g_build_filename (artwork_dir,
+ "ArtworkDB", NULL);
+ g_free (artwork_dir);
}
- g_free (path);
}
return filename;
@@ -471,15 +490,15 @@ ipod_db_get_photo_db_path (const char *mount_point)
}
static gboolean
-ipod_supports_cover_art (IpodDevice *ipod)
+ipod_supports_cover_art (Itdb_Device *device)
{
- const IpodArtworkFormat *formats;
+ const Itdb_ArtworkFormat *formats;
- if (ipod == NULL) {
+ if (device == NULL) {
return FALSE;
}
- g_object_get (G_OBJECT (ipod), "artwork-formats", &formats, NULL);
+ formats = itdb_device_get_artwork_formats (device);
if (formats == NULL) {
return FALSE;
}
@@ -502,12 +521,13 @@ ipod_parse_artwork_db (Itdb_iTunesDB *db)
char *filename;
g_return_val_if_fail (db, -1);
+ g_return_val_if_fail (db->device, -1);
if (!ipod_supports_cover_art (db->device)) {
return -1;
}
ctx = NULL;
- filename = ipod_db_get_artwork_db_path (db->mountpoint);
+ filename = ipod_db_get_artwork_db_path (itdb_get_mountpoint (db));
if (filename == NULL) {
goto error;
}
diff --git a/src/db-artwork-writer.c b/src/db-artwork-writer.c
index 65fc089..b890495 100644
--- a/src/db-artwork-writer.c
+++ b/src/db-artwork-writer.c
@@ -444,7 +444,7 @@ write_mhii (Itdb_Track *song, iPodBuffer *buffer)
for (it = song->artwork->thumbnails; it != NULL; it = it->next) {
iPodBuffer *sub_buffer;
Itdb_Thumb *thumb;
- const IpodArtworkFormat *img_info;
+ const Itdb_ArtworkFormat *img_info;
mhii->num_children = GINT_TO_LE (num_children);
mhii->total_len = GINT_TO_LE (total_bytes);
@@ -453,7 +453,7 @@ write_mhii (Itdb_Track *song, iPodBuffer *buffer)
return -1;
}
thumb = (Itdb_Thumb *)it->data;
- img_info = ipod_get_artwork_info_from_type (
+ img_info = itdb_get_artwork_info_from_type (
song->itdb->device, thumb->type);
if (img_info == NULL) {
return -1;
@@ -543,7 +543,7 @@ static int
write_mhif (Itdb_iTunesDB *db, iPodBuffer *buffer, enum iPodThumbnailType type)
{
MhifHeader *mhif;
- const IpodArtworkFormat *img_info;
+ const Itdb_ArtworkFormat *img_info;
mhif = (MhifHeader *)init_header (buffer, "mhif", sizeof (MhifHeader));
if (mhif == NULL) {
@@ -551,7 +551,7 @@ write_mhif (Itdb_iTunesDB *db, iPodBuffer *buffer, enum iPodThumbnailType type)
}
mhif->total_len = mhif->header_len;
- img_info = ipod_get_artwork_info_from_type (db->device, type);
+ img_info = itdb_get_artwork_info_from_type (db->device, type);
if (img_info == NULL) {
return -1;
}
@@ -748,7 +748,7 @@ ipod_write_artwork_db (Itdb_iTunesDB *db)
/* Now we can update the ArtworkDB file */
id_max = ipod_artwork_db_set_ids (db);
- filename = ipod_db_get_artwork_db_path (db->mountpoint);
+ filename = ipod_db_get_artwork_db_path (itdb_get_mountpoint (db));
if (filename == NULL) {
/* FIXME: the iTunesDB will be inconsistent wrt artwork_count
* it might be better to 0 out this field in all tracks
diff --git a/src/db-image-parser.c b/src/db-image-parser.c
index ba4cda5..296d82c 100644
--- a/src/db-image-parser.c
+++ b/src/db-image-parser.c
@@ -29,20 +29,22 @@
#include <glib.h>
#include <glib-object.h>
+#include "itdb_device.h"
#include "db-artwork-parser.h"
#include "db-image-parser.h"
#include <glib/gi18n-lib.h>
static int
-image_type_from_corr_id (IpodDevice *ipod, int corr_id)
+image_type_from_corr_id (Itdb_Device *device, int corr_id)
{
- const IpodArtworkFormat *formats;
+ const Itdb_ArtworkFormat *formats;
- if (ipod == NULL) {
+ if (device == NULL) {
return -1;
}
- g_object_get (G_OBJECT (ipod), "artwork-formats", &formats, NULL);
+ formats = itdb_device_get_artwork_formats (device);
+
if (formats == NULL) {
return -1;
}
@@ -58,16 +60,16 @@ image_type_from_corr_id (IpodDevice *ipod, int corr_id)
}
-G_GNUC_INTERNAL const IpodArtworkFormat *
-ipod_get_artwork_info_from_type (IpodDevice *ipod, int image_type)
+G_GNUC_INTERNAL const Itdb_ArtworkFormat *
+itdb_get_artwork_info_from_type (Itdb_Device *device, int image_type)
{
- const IpodArtworkFormat *formats;
+ const Itdb_ArtworkFormat *formats;
- if (ipod == NULL) {
+ if (device == NULL) {
return NULL;
}
- g_object_get (G_OBJECT (ipod), "artwork-formats", &formats, NULL);
+ formats = itdb_device_get_artwork_formats (device);
if (formats == NULL) {
return NULL;
}
diff --git a/src/db-image-parser.h b/src/db-image-parser.h
index 3e42c62..a8e2fe5 100644
--- a/src/db-image-parser.h
+++ b/src/db-image-parser.h
@@ -26,6 +26,7 @@
#define IMAGE_PARSER_H
#include "db-itunes-parser.h"
+#include "itdb_device.h"
#include "itdb.h"
#define RED_BITS 5
@@ -45,7 +46,7 @@ G_GNUC_INTERNAL Itdb_Thumb *ipod_image_new_from_mhni (MhniHeader *mhni,
G_GNUC_INTERNAL int itdb_write_ithumb_files (Itdb_iTunesDB *db);
-G_GNUC_INTERNAL const IpodArtworkFormat *ipod_get_artwork_info_from_type (
- IpodDevice *ipod, int image_type);
+G_GNUC_INTERNAL const Itdb_ArtworkFormat *itdb_get_artwork_info_from_type (
+ Itdb_Device *ipod, int image_type);
#endif
diff --git a/src/hal-common.c b/src/hal-common.c
deleted file mode 100644
index d2bbd5d..0000000
--- a/src/hal-common.c
+++ /dev/null
@@ -1,95 +0,0 @@
-/* Time-stamp: <2005-12-10 00:22:44 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)
-| - provide some dummy libhal functions to make libhal-independence
-| of ipod-device.c easier.
-|
-| Because of these changes only a limited amount of functionality is
-| available. See ipod-device.h for summary.
-|
-|
-|
-|
-| $Id$
-*/
-/* ex: set ts=4: */
-/***************************************************************************
-* hal-common.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
- */
-
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
-
-#include "itdb_private.h"
-#include "hal-common.h"
-
-#ifndef HAVE_LIBHAL
-gchar **libhal_manager_find_device_string_match (LibHalContext *hal_ctx,
- const gchar *type,
- const gchar *str,
- gint *vol_count,
- void *error)
-{
-/* gchar **volumes = g_new0 (gchar *, 2);
- volumes[0] = g_strdup (type);*/
- gchar **volumes = NULL;
- *vol_count = 0;
- return volumes;
-}
-void libhal_free_string_array (gchar **volumes)
-{
-/* g_strfreev (volumes);*/
-}
-gboolean libhal_device_property_exists (LibHalContext *hal_ctx,
- const gchar *vol,
- const gchar *prop,
- void *error)
-{
- return FALSE;
-}
-gboolean libhal_device_get_property_bool (LibHalContext *hal_ctx,
- const gchar *vol,
- const gchar *prop,
- void *error)
-{
- return FALSE;
-}
-void libhal_ctx_shutdown (LibHalContext *hal_ctx, void *error) {}
-void libhal_ctx_free (LibHalContext *hal_ctx) {}
-#endif
diff --git a/src/hal-common.h b/src/hal-common.h
deleted file mode 100644
index 8cdbe2b..0000000
--- a/src/hal-common.h
+++ /dev/null
@@ -1,95 +0,0 @@
-/* Time-stamp: <2005-10-10 01:23:30 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 #if HAVE_LIBHAL sections)
-| - provide some dummy libhal functions to make libhal-independence
-| of ipod-device.c easier.
-|
-| Because of these changes only a limited amount of functionality is
-| available. See ipod-device.h for summary.
-|
-|
-|
-|
-| $Id$
-*/
-/* ex: set ts=4: */
-/***************************************************************************
-* hal-common.h
-* 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
- */
-
-#ifndef HAL_COMMON_H
-#define HAL_COMMON_H
-
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
-
-#include <glib.h>
-#include <glib-object.h>
-
-#ifdef HAVE_LIBHAL
-
-#include <libhal.h>
-#include <dbus/dbus.h>
-#include <dbus/dbus-glib.h>
-
-dbus_bool_t hal_mainloop_integration(LibHalContext *ctx, DBusError *error);
-void ipod_device_set_global_main_context(GMainContext *ctx);
-
-#else
-typedef void LibHalContext;
-G_GNUC_INTERNAL gchar **libhal_manager_find_device_string_match (LibHalContext *hal_ctx,
- const gchar *dev,
- const gchar *str,
- gint *vol_count,
- void *error);
-G_GNUC_INTERNAL void libhal_free_string_array (gchar **volumes);
-G_GNUC_INTERNAL gboolean libhal_device_property_exists (LibHalContext *hal_ctx,
- const gchar *vol,
- const gchar *prop,
- void *error);
-G_GNUC_INTERNAL gboolean libhal_device_get_property_bool (LibHalContext *hal_ctx,
- const gchar *vol,
- const gchar *prop,
- void *error);
-G_GNUC_INTERNAL void libhal_ctx_shutdown (LibHalContext *hal_ctx, void *error);
-G_GNUC_INTERNAL void libhal_ctx_free (LibHalContext *hal_ctx);
-#endif
-
-
-#endif /* HAL_COMMON_H */
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);
-}
diff --git a/src/ipod-device.h b/src/ipod-device.h
deleted file mode 100644
index 416c13e..0000000
--- a/src/ipod-device.h
+++ /dev/null
@@ -1,196 +0,0 @@
-/* Time-stamp: <2005-10-10 01:23:28 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)
-| - publicly available functions were renamed from ipod_device_...()
-| to itdb_device_...()
-|
-| Because of these changes only a limited amount of functionality is
-| available if libhal is not present. In particular the following
-| functions are non-functional:
-|
-| GList *ipod_device_list_devices(void);
-| GList *ipod_device_list_device_udis(void);
-| guint ipod_device_eject(IpodDevice *device, GError **error);
-| guint ipod_device_reboot(IpodDevice *device, GError **error_out);
-|
-| Only the following properties are available:
-|
-|
-| device-model
-| device-model-string
-| device-generation
-| advertised-capacity
-| is-new
-| can-write
-| serial-number
-| firmware-version
-| device-name
-| user-name
-| host-name
-|
-|
-| $Id$
-*/
-/* ex: set ts=4: */
-/***************************************************************************
-* ipod-device.h
-* 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
- */
-
-#ifndef IPOD_DEVICE_H
-#define IPOD_DEVICE_H
-
-#include <glib.h>
-#include <glib-object.h>
-
-G_BEGIN_DECLS
-
-#define TYPE_IPOD_DEVICE (ipod_device_get_type ())
-#define IPOD_DEVICE(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), TYPE_IPOD_DEVICE, IpodDevice))
-#define IPOD_DEVICE_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), TYPE_IPOD_DEVICE, IpodDeviceClass))
-#define IS_IPOD_DEVICE(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), TYPE_IPOD_DEVICE))
-#define IS_IPOD_DEVICE_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), TYPE_IPOD_DEVICE))
-#define IPOD_DEVICE_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), TYPE_IPOD_DEVICE, IpodDeviceClass))
-
-typedef struct IpodDevicePrivate IpodDevicePrivate;
-
-typedef struct {
- GObject parent;
- IpodDevicePrivate *priv;
-} IpodDevice;
-
-typedef struct {
- GObjectClass parent_class;
-} IpodDeviceClass;
-
-enum {
- UNKNOWN_GENERATION,
- FIRST_GENERATION,
- SECOND_GENERATION,
- THIRD_GENERATION,
- FOURTH_GENERATION,
- FIFTH_GENERATION
-};
-
-enum {
- MODEL_TYPE_INVALID,
- MODEL_TYPE_UNKNOWN,
- MODEL_TYPE_COLOR,
- MODEL_TYPE_COLOR_U2,
- MODEL_TYPE_REGULAR,
- MODEL_TYPE_REGULAR_U2,
- MODEL_TYPE_MINI,
- MODEL_TYPE_MINI_BLUE,
- MODEL_TYPE_MINI_PINK,
- MODEL_TYPE_MINI_GREEN,
- MODEL_TYPE_MINI_GOLD,
- MODEL_TYPE_SHUFFLE,
- MODEL_TYPE_NANO_WHITE,
- MODEL_TYPE_NANO_BLACK,
- MODEL_TYPE_VIDEO_WHITE,
- MODEL_TYPE_VIDEO_BLACK
-};
-
-enum {
- EJECT_OK,
- EJECT_ERROR,
- EJECT_BUSY
-};
-
-enum {
- PROP_IPOD_0,
- PROP_HAL_VOLUME_ID,
- PROP_HAL_CONTEXT,
- PROP_MOUNT_POINT,
- PROP_DEVICE_PATH,
- PROP_CONTROL_PATH,
- PROP_DEVICE_MODEL,
- PROP_DEVICE_MODEL_STRING,
- PROP_DEVICE_GENERATION,
- PROP_ADVERTISED_CAPACITY,
- PROP_DEVICE_NAME,
- PROP_USER_NAME,
- PROP_HOST_NAME,
- PROP_VOLUME_SIZE,
- PROP_VOLUME_AVAILABLE,
- PROP_VOLUME_USED,
- PROP_IS_IPOD,
- PROP_IS_NEW,
- PROP_SERIAL_NUMBER,
- PROP_MODEL_NUMBER,
- PROP_FIRMWARE_VERSION,
- PROP_VOLUME_UUID,
- PROP_VOLUME_LABEL,
- PROP_CAN_WRITE,
- PROP_ARTWORK_FORMAT
-};
-
-enum {
- ERROR_SAVE
-};
-
-enum {
- IPOD_COVER_SMALL,
- IPOD_COVER_LARGE,
- IPOD_PHOTO_SMALL,
- IPOD_PHOTO_LARGE,
- IPOD_PHOTO_FULL_SCREEN,
- IPOD_PHOTO_TV_SCREEN
-};
-
-
-typedef struct {
- gint type;
- gint16 width;
- gint16 height;
- gint16 correlation_id;
-} IpodArtworkFormat;
-
-
-GType itdb_device_get_type(void);
-IpodDevice *itdb_device_new(const gchar *mount_point);
-gboolean itdb_device_rescan_disk(IpodDevice *device);
-guint itdb_device_eject(IpodDevice *device, GError **error);
-guint itdb_device_reboot(IpodDevice *device, GError **error_out);
-void itdb_device_debug(IpodDevice *device);
-gboolean itdb_device_save(IpodDevice *device, GError **error);
-GList *itdb_device_list_devices(void);
-GList *itdb_device_list_device_udis(void);
-
-G_END_DECLS
-
-#endif /* IPOD_DEVICE_H */
diff --git a/src/itdb.h b/src/itdb.h
index 731e04f..51cea19 100644
--- a/src/itdb.h
+++ b/src/itdb.h
@@ -1,4 +1,4 @@
-/* Time-stamp: <2006-03-13 23:01:23 jcs>
+/* Time-stamp: <2006-03-16 23:50:32 jcs>
|
| Copyright (C) 2002-2005 Jorg Schuler <jcsjcs at users sourceforge net>
| Part of the gtkpod project.
@@ -40,8 +40,6 @@
# include <config.h>
#endif
-#include "ipod-device.h"
-
#include <sys/types.h>
#include <time.h>
#include <glib.h>
@@ -56,6 +54,7 @@ G_BEGIN_DECLS
typedef void (* ItdbUserDataDestroyFunc) (gpointer userdata);
typedef gpointer (* ItdbUserDataDuplicateFunc) (gpointer userdata);
+typedef struct _Itdb_Device Itdb_Device;
typedef struct _Itdb_Artwork Itdb_Artwork;
typedef struct _Itdb_Thumb Itdb_Thumb;
typedef struct _SPLPref SPLPref;
@@ -394,12 +393,8 @@ struct _Itdb_iTunesDB
GList *tracks;
GList *playlists;
gchar *filename; /* filename of iTunesDB */
- gchar *mountpoint; /* mountpoint of iPod (if available) */
- IpodDevice *device;
- gint musicdirs; /* number of /iPod_Control/Music/F.. dirs */
+ Itdb_Device *device;/* iPod device info */
guint32 version;
- gboolean reversed; /* this iTunesDB has to be written in reversed
- endian order (e.g. mobile phone iTunesDBs) */
guint64 id;
/* below is for use by application */
guint64 usertype;
@@ -746,8 +741,22 @@ void itdb_filename_fs2ipod (gchar *filename);
void itdb_filename_ipod2fs (gchar *ipod_file);
gchar *itdb_filename_on_ipod (Itdb_Track *track);
void itdb_set_mountpoint (Itdb_iTunesDB *itdb, const gchar *mp);
+const gchar *itdb_get_mountpoint (Itdb_iTunesDB *itdb);
gchar *itdb_get_control_dir (const gchar *mountpoint);
gchar *itdb_get_itunes_dir (const gchar *mountpoint);
+gchar *itdb_get_music_dir (const gchar *mountpoint);
+gchar *itdb_get_artwork_dir (const gchar *mountpoint);
+gchar *itdb_get_device_dir (const gchar *mountpoint);
+gchar *itdb_get_itunesdb_path (const gchar *mountpoint);
+gchar *itdb_get_artworkdb_path (const gchar *mountpoint);
+gchar *itdb_get_path (const gchar *dir, const gchar *file);
+
+/* itdb_device functions */
+Itdb_Device *itdb_device_new (void);
+void itdb_device_free (Itdb_Device *device);
+void itdb_device_set_mountpoint (Itdb_Device *device, const gchar *mp);
+gboolean itdb_device_read_sysinfo (Itdb_Device *device);
+gchar *itdb_device_get_sysinfo (Itdb_Device *device, const gchar *field);
/* track functions */
Itdb_Track *itdb_track_new (void);
@@ -825,12 +834,12 @@ void itdb_artwork_remove_thumbnails (Itdb_Artwork *artwork);
/* itdb_thumb_... */
/* the following funciton returns a pointer to a GdkPixbuf if
gdk-pixbuf is installed -- a NULL pointer otherwise. */
-gpointer itdb_thumb_get_gdk_pixbuf (IpodDevice *device,
+gpointer itdb_thumb_get_gdk_pixbuf (Itdb_Device *device,
Itdb_Thumb *thumb);
Itdb_Thumb *itdb_thumb_duplicate (Itdb_Thumb *thumb);
void itdb_thumb_free (Itdb_Thumb *thumb);
Itdb_Thumb *itdb_thumb_new (void);
-gchar *itdb_thumb_get_filename (IpodDevice *device, Itdb_Thumb *thumb);
+gchar *itdb_thumb_get_filename (Itdb_Device *device, Itdb_Thumb *thumb);
/* time functions */
diff --git a/src/itdb_artwork.c b/src/itdb_artwork.c
index 8142403..a233486 100644
--- a/src/itdb_artwork.c
+++ b/src/itdb_artwork.c
@@ -1,4 +1,4 @@
-/* Time-stamp: <2005-12-11 16:27:33 jcs>
+/* Time-stamp: <2006-03-16 22:30:22 jcs>
|
| Copyright (C) 2002-2005 Jorg Schuler <jcsjcs at users sourceforge net>
| Part of the gtkpod project.
@@ -178,10 +178,9 @@ Itdb_Thumb *itdb_artwork_get_thumb_by_type (Itdb_Artwork *artwork,
the original file.
g_free() when not needed any more.
*/
-gchar *itdb_thumb_get_filename (IpodDevice *device, Itdb_Thumb *thumb)
+gchar *itdb_thumb_get_filename (Itdb_Device *device, Itdb_Thumb *thumb)
{
- gchar *paths[] = {"iPod_Control", "Artwork", NULL, NULL};
- gchar *filename, *mountpoint;
+ gchar *artwork_dir, *filename=NULL;
g_return_val_if_fail (device, NULL);
g_return_val_if_fail (thumb, NULL);
@@ -196,18 +195,18 @@ gchar *itdb_thumb_get_filename (IpodDevice *device, Itdb_Thumb *thumb)
return NULL;
}
- g_object_get (G_OBJECT (device),
- "mount-point", &mountpoint,
- NULL);
-
- if (!mountpoint)
+ if (!device->mountpoint)
{
g_print (_("Mountpoint not set.\n"));
return NULL;
}
- paths[2] = thumb->filename+1;
- filename = itdb_resolve_path (mountpoint, (const char **)paths);
+ artwork_dir = itdb_get_artwork_dir (device->mountpoint);
+ if (artwork_dir)
+ {
+ filename = itdb_get_path (artwork_dir, thumb->filename+1);
+ g_free (artwork_dir);
+ }
return filename;
}
@@ -245,7 +244,7 @@ unpack_RGB_565 (guint16 *pixels, guint bytes_len)
static guchar *
-get_pixel_data (IpodDevice *device, Itdb_Thumb *thumb)
+get_pixel_data (Itdb_Device *device, Itdb_Thumb *thumb)
{
gchar *filename = NULL;
guchar *result = NULL;
@@ -305,7 +304,7 @@ get_pixel_data (IpodDevice *device, Itdb_Thumb *thumb)
}
static guchar *
-itdb_thumb_get_rgb_data (IpodDevice *device, Itdb_Thumb *thumb)
+itdb_thumb_get_rgb_data (Itdb_Device *device, Itdb_Thumb *thumb)
{
void *pixels565;
guchar *pixels;
@@ -340,12 +339,12 @@ itdb_thumb_get_rgb_data (IpodDevice *device, Itdb_Thumb *thumb)
The returned GdkPixbuf must be freed with gdk_pixbuf_unref() after
use. */
gpointer
-itdb_thumb_get_gdk_pixbuf (IpodDevice *device, Itdb_Thumb *thumb)
+itdb_thumb_get_gdk_pixbuf (Itdb_Device *device, Itdb_Thumb *thumb)
{
#if HAVE_GDKPIXBUF
GdkPixbuf *pixbuf=NULL;
guchar *pixels;
- const IpodArtworkFormat *img_info=NULL;
+ const Itdb_ArtworkFormat *img_info=NULL;
g_return_val_if_fail (thumb, NULL);
@@ -358,7 +357,7 @@ itdb_thumb_get_gdk_pixbuf (IpodDevice *device, Itdb_Thumb *thumb)
*/
if (device != NULL)
{
- img_info = ipod_get_artwork_info_from_type (device, thumb->type);
+ img_info = itdb_get_artwork_info_from_type (device, thumb->type);
}
if (thumb->size == 0)
diff --git a/src/itdb_device.c b/src/itdb_device.c
new file mode 100644
index 0000000..c0fe191
--- /dev/null
+++ b/src/itdb_device.c
@@ -0,0 +1,431 @@
+/* Time-stamp: <2006-03-17 00:02:22 jcs>
+|
+| Copyright (C) 2002-2005 Jorg Schuler <jcsjcs at users sourceforge net>
+| Part of the gtkpod project.
+|
+| URL: http://www.gtkpod.org/
+| URL: http://gtkpod.sourceforge.net/
+|
+| Part of this code is based on ipod-device.c from the libipoddevice
+| project (http://64.14.94.162/index.php/Libipoddevice).
+|
+| The code contained in this file is free software; you can redistribute
+| it and/or modify it under the terms of the GNU Lesser General Public
+| License as published by the Free Software Foundation; either version
+| 2.1 of the License, or (at your option) any later version.
+|
+| This file 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
+| Lesser General Public License for more details.
+|
+| You should have received a copy of the GNU Lesser General Public
+| License along with this code; if not, write to the Free Software
+| Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+| USA
+|
+| iTunes and iPod are trademarks of Apple
+|
+| This product is not supported/written/published by Apple!
+|
+| $Id$
+*/
+
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+#include "itdb_device.h"
+
+#define GB 1024
+
+static const Itdb_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}
+};
+
+#if 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
+};
+#endif
+
+static const Itdb_ArtworkFormat 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 Itdb_ArtworkFormat 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 Itdb_ArtworkFormat 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 Itdb_ArtworkFormat *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) */
+};
+
+
+/* Reset or create the SysInfo hash table */
+static void itdb_device_reset_sysinfo (Itdb_Device *device)
+{
+ if (device->sysinfo)
+ g_hash_table_destroy (device->sysinfo);
+ device->sysinfo = g_hash_table_new_full (g_str_hash, g_str_equal,
+ g_free, g_free);
+}
+
+
+/* Create new Itdb_Device structure */
+Itdb_Device *itdb_device_new ()
+{
+ Itdb_Device *dev;
+
+ dev = g_new0 (Itdb_Device, 1);
+ itdb_device_reset_sysinfo (dev);
+ return dev;
+}
+
+/* Free memory used by @device */
+void itdb_device_free (Itdb_Device *device)
+{
+ if (device)
+ {
+ g_free (device->mountpoint);
+ if (device->sysinfo)
+ g_hash_table_destroy (device->sysinfo);
+ g_free (device);
+ }
+}
+
+
+/* Set mountpoint and read SysInfo file */
+void itdb_device_set_mountpoint (Itdb_Device *device, const gchar *mp)
+{
+ g_return_if_fail (device);
+
+ g_free (device->mountpoint);
+ device->mountpoint = g_strdup (mp);
+ if (mp)
+ itdb_device_read_sysinfo (device);
+}
+
+
+/* Read SysInfo file and store information in device->sysinfo for
+ * later use.
+ *
+ * Return value: TRUE if file could be read, FALSE otherwise */
+gboolean itdb_device_read_sysinfo (Itdb_Device *device)
+{
+ const gchar *p_sysinfo[] = {"SysInfo", NULL};
+ gchar *dev_path, *sysinfo_path;
+ FILE *fd;
+ gboolean result = FALSE;
+ gchar buf[1024];
+
+ g_return_val_if_fail (device, FALSE);
+ g_return_val_if_fail (device->mountpoint, FALSE);
+
+ itdb_device_reset_sysinfo (device);
+
+ g_return_val_if_fail (device->sysinfo, FALSE);
+
+ dev_path = itdb_get_device_dir (device->mountpoint);
+
+ if (!dev_path) return FALSE;
+
+ sysinfo_path = itdb_resolve_path (dev_path, p_sysinfo);
+
+ if (sysinfo_path)
+ {
+ fd = fopen (sysinfo_path, "r");
+ if (fd)
+ {
+ result = TRUE;
+ while(fgets(buf, sizeof(buf), fd))
+ {
+ gchar *ptr;
+ gint len = strlen (buf);
+ /* suppress newline at end of line */
+ if ((len>0) && (buf[len-1]==0x0a))
+ {
+ buf[len-1] = 0;
+ --len;
+ }
+ ptr = strchr (buf, ':');
+ if (ptr && (ptr!=buf))
+ {
+ gchar *key, *value;
+ *ptr = 0;
+ ++ptr;
+ key = g_strdup (buf);
+ g_strstrip (ptr);
+ value = g_strdup (ptr);
+ g_hash_table_insert (device->sysinfo, key, value);
+ }
+ }
+ fclose (fd);
+ }
+ g_free (sysinfo_path);
+ }
+ g_free (dev_path);
+ return result;
+}
+
+
+/* Retrieve specified field from the SysInfo file.
+ *
+ * Return value: g_free() after use
+ */
+gchar *itdb_device_get_sysinfo (Itdb_Device *device, const gchar *field)
+{
+ g_return_val_if_fail (device, NULL);
+ g_return_val_if_fail (device->sysinfo, NULL);
+ g_return_val_if_fail (field, NULL);
+
+ return g_strdup (g_hash_table_lookup (device->sysinfo, field));
+}
+
+
+/* Return Itdb_IpodModel entry for this iPod */
+G_GNUC_INTERNAL const Itdb_IpodModel *
+itdb_device_get_ipod_model (Itdb_Device *device)
+{
+ gint i;
+ gchar *model_num, *p;
+
+ model_num = itdb_device_get_sysinfo (device, "ModelNumStr");
+
+ if (!model_num)
+ return &ipod_model_table[0];
+
+ 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 &ipod_model_table[i];
+ }
+ }
+ g_free(model_num);
+ return &ipod_model_table[1];
+}
+
+
+/* Return supported artwork formats supported by this iPod */
+G_GNUC_INTERNAL const Itdb_ArtworkFormat *
+itdb_device_get_artwork_formats (Itdb_Device *device)
+{
+ const Itdb_IpodModel *model;
+
+ g_return_val_if_fail (device, NULL);
+
+ model = itdb_device_get_ipod_model (device);
+
+ g_return_val_if_fail (model, NULL);
+
+ return ipod_artwork_info_table[model->model_type];
+}
+
+
+/* Determine the number of F.. directories in iPod_Control/Music.
+
+ If device->musicdirs is already set, simply return the previously
+ determined number. Otherwise count the directories first and set
+ itdb->musicdirs. */
+G_GNUC_INTERNAL gint
+itdb_device_musicdirs_number (Itdb_Device *device)
+{
+ gchar *dir_filename = NULL;
+ gint dir_num;
+
+ g_return_val_if_fail (device, 0);
+
+ if (device->musicdirs <= 0)
+ {
+ gchar *music_dir = itdb_get_music_dir (device->mountpoint);
+ if (!music_dir) return 0;
+ /* count number of dirs */
+ for (dir_num=0; ;++dir_num)
+ {
+ gchar dir_num_str[5];
+
+ g_snprintf (dir_num_str, 5, "F%02d", dir_num);
+
+ dir_filename = itdb_get_path (music_dir, dir_num_str);
+
+ if (!dir_filename) break;
+ g_free (dir_filename);
+ }
+ device->musicdirs = dir_num;
+ g_free (music_dir);
+ }
+ return device->musicdirs;
+}
+
+
+/* Attempt to guess the endianess used by this iPod.
+ *
+ * It will overwrite the previous setting.
+ *
+ */
+
+G_GNUC_INTERNAL void
+itdb_device_autodetect_endianess (Itdb_Device *device)
+{
+ g_return_if_fail (device);
+
+ /* endianess_set will be set to FALSE. This field is only set to
+ TRUE when importing an iTunesDB. */
+ device->endianess_set = FALSE;
+ /* default: non-reversed */
+ device->endianess_reversed = FALSE;
+
+ if (device->mountpoint)
+ {
+ gchar *control_dir = itdb_get_control_dir (device->mountpoint);
+
+ if (control_dir)
+ {
+ gchar *cd_l = g_ascii_strdown (control_dir, -1);
+ if (strstr (cd_l, "itunes/itunes_control") ==
+ (cd_l + strlen (cd_l) - strlen ("itunes/itunes_control")))
+ {
+ device->endianess_reversed = TRUE;
+ }
+ g_free (cd_l);
+ g_free (control_dir);
+ }
+ }
+}
diff --git a/src/itdb_device.h b/src/itdb_device.h
new file mode 100644
index 0000000..5755d3c
--- /dev/null
+++ b/src/itdb_device.h
@@ -0,0 +1,126 @@
+/* Time-stamp: <2006-03-16 23:02:20 jcs>
+|
+| Copyright (C) 2002-2005 Jorg Schuler <jcsjcs at users sourceforge net>
+| Part of the gtkpod project.
+|
+| URL: http://www.gtkpod.org/
+| URL: http://gtkpod.sourceforge.net/
+|
+| Most of the code in this file has been ported from the perl
+| script "mktunes.pl" (part of the gnupod-tools collection) written
+| by Adrian Ulrich <pab at blinkenlights.ch>.
+|
+| gnupod-tools: http://www.blinkenlights.ch/cgi-bin/fm.pl?get=ipod
+|
+| The code contained in this file is free software; you can redistribute
+| it and/or modify it under the terms of the GNU Lesser General Public
+| License as published by the Free Software Foundation; either version
+| 2.1 of the License, or (at your option) any later version.
+|
+| This file 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
+| Lesser General Public License for more details.
+|
+| You should have received a copy of the GNU Lesser General Public
+| License along with this code; if not, write to the Free Software
+| Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+|
+| iTunes and iPod are trademarks of Apple
+|
+| This product is not supported/written/published by Apple!
+|
+| $Id$
+*/
+
+#ifndef __ITDB_DEVICE_H__
+#define __ITDB_DEVICE_H__
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "itdb.h"
+
+#include <glib.h>
+
+G_BEGIN_DECLS
+
+typedef struct _Itdb_IpodModel Itdb_IpodModel;
+typedef struct _Itdb_ArtworkFormat Itdb_ArtworkFormat;
+
+struct _Itdb_Device
+{
+ gchar *mountpoint; /* mountpoint of the iPod */
+ gint musicdirs; /* number of /iPod_Control/Music/F.. dirs */
+ gboolean endianess_set; /* the endianess_reversed flag has been
+ detected or set */
+ gboolean endianess_reversed; /* this iTunesDB has to be written in
+ reversed endian order (e.g. mobile phone
+ iTunesDBs) */
+ GHashTable *sysinfo; /* hash with value/key pairs of all entries
+ in Device/SysInfo */
+};
+
+struct _Itdb_ArtworkFormat
+{
+ gint type;
+ gint16 width;
+ gint16 height;
+ gint16 correlation_id;
+};
+
+struct _Itdb_IpodModel {
+ const gchar *model_number;
+ const guint64 capacity;
+ guint model_type;
+ guint generation;
+};
+
+typedef enum {
+ UNKNOWN_GENERATION,
+ FIRST_GENERATION,
+ SECOND_GENERATION,
+ THIRD_GENERATION,
+ FOURTH_GENERATION,
+ FIFTH_GENERATION
+} Itdb_Generation;
+
+typedef enum {
+ MODEL_TYPE_INVALID,
+ MODEL_TYPE_UNKNOWN,
+ MODEL_TYPE_COLOR,
+ MODEL_TYPE_COLOR_U2,
+ MODEL_TYPE_REGULAR,
+ MODEL_TYPE_REGULAR_U2,
+ MODEL_TYPE_MINI,
+ MODEL_TYPE_MINI_BLUE,
+ MODEL_TYPE_MINI_PINK,
+ MODEL_TYPE_MINI_GREEN,
+ MODEL_TYPE_MINI_GOLD,
+ MODEL_TYPE_SHUFFLE,
+ MODEL_TYPE_NANO_WHITE,
+ MODEL_TYPE_NANO_BLACK,
+ MODEL_TYPE_VIDEO_WHITE,
+ MODEL_TYPE_VIDEO_BLACK
+} Itdb_ModelType;
+
+
+enum {
+ IPOD_COVER_SMALL,
+ IPOD_COVER_LARGE,
+ IPOD_PHOTO_SMALL,
+ IPOD_PHOTO_LARGE,
+ IPOD_PHOTO_FULL_SCREEN,
+ IPOD_PHOTO_TV_SCREEN
+};
+
+G_GNUC_INTERNAL const Itdb_ArtworkFormat *itdb_device_get_artwork_formats (Itdb_Device *device);
+G_GNUC_INTERNAL const Itdb_IpodModel *itdb_device_get_ipod_model (Itdb_Device *device);
+G_GNUC_INTERNAL gint itdb_device_musicdirs_number (Itdb_Device *device);
+G_GNUC_INTERNAL void itdb_device_autodetect_endianess (Itdb_Device *device);
+
+
+G_END_DECLS
+
+#endif
diff --git a/src/itdb_itunesdb.c b/src/itdb_itunesdb.c
index 2d91de3..7577da8 100644
--- a/src/itdb_itunesdb.c
+++ b/src/itdb_itunesdb.c
@@ -1,4 +1,4 @@
-/* Time-stamp: <2006-03-14 01:25:03 jcs>
+/* Time-stamp: <2006-03-17 00:02:22 jcs>
|
| Copyright (C) 2002-2005 Jorg Schuler <jcsjcs at users sourceforge net>
| Part of the gtkpod project.
@@ -120,8 +120,10 @@
#include <errno.h>
#include <stdio.h>
#include "itdb_private.h"
+#include "itdb_device.h"
#include "db-artwork-parser.h"
#include <glib/gi18n-lib.h>
+#include <glib-object.h>
#define ITUNESDB_DEBUG 0
#define ITUNESDB_MHIT_DEBUG 0
@@ -1054,10 +1056,7 @@ void itdb_free (Itdb_iTunesDB *itdb)
(GFunc)(itdb_track_free), NULL);
g_list_free (itdb->tracks);
g_free (itdb->filename);
- g_free (itdb->mountpoint);
- if (itdb->device != NULL) {
- g_object_unref (G_OBJECT (itdb->device));
- }
+ itdb_device_free (itdb->device);
if (itdb->userdata && itdb->userdata_destroy)
(*itdb->userdata_destroy) (itdb->userdata);
g_free (itdb);
@@ -1117,6 +1116,7 @@ Itdb_iTunesDB *itdb_new (void)
g_once (&g_type_init_once, (GThreadFunc)g_type_init, NULL);
itdb = g_new0 (Itdb_iTunesDB, 1);
+ itdb->device = itdb_device_new ();
itdb->version = 0x09;
itdb->id = ((guint64)g_random_int () << 32) |
((guint64)g_random_int ());
@@ -2526,7 +2526,8 @@ static gboolean parse_fimp (FImport *fimp)
}
/* copy the 'reversed endian flag' */
- fimp->itdb->reversed = cts->reversed;
+ fimp->itdb->device->endianess_set = TRUE;
+ fimp->itdb->device->endianess_reversed = cts->reversed;
parse_tracks (fimp, mhsd_1);
if (fimp->error) return FALSE;
@@ -2569,6 +2570,24 @@ static void error_no_itunes_dir (const gchar *mp, GError **error)
}
/* Set @error with standard error message */
+static void error_no_music_dir (const gchar *mp, GError **error)
+{
+ gchar *str;
+
+ g_return_if_fail (mp);
+ g_return_if_fail (error);
+
+ str = g_build_filename (mp, "iPod_Control", "Music", NULL);
+ g_set_error (error,
+ ITDB_FILE_ERROR,
+ ITDB_FILE_ERROR_NOTFOUND,
+ _("Music directory not found: '%s' (or similar)."),
+ str);
+ g_free (str);
+}
+
+#if 0
+/* Set @error with standard error message */
static void error_no_control_dir (const gchar *mp, GError **error)
{
gchar *str;
@@ -2584,7 +2603,7 @@ static void error_no_control_dir (const gchar *mp, GError **error)
str);
g_free (str);
}
-
+#endif
/* Parse the Itdb_iTunesDB.
Returns a pointer to the Itdb_iTunesDB struct holding the tracks and the
@@ -4079,6 +4098,7 @@ gboolean itdb_write_file (Itdb_iTunesDB *itdb, const gchar *filename,
gboolean result = TRUE;;
g_return_val_if_fail (itdb, FALSE);
+ g_return_val_if_fail (itdb->device, FALSE);
g_return_val_if_fail (filename || itdb->filename, FALSE);
if (!filename) filename = itdb->filename;
@@ -4097,8 +4117,10 @@ gboolean itdb_write_file (Itdb_iTunesDB *itdb, const gchar *filename,
fexp->wcontents = wcontents_new (filename);
cts = fexp->wcontents;
- /* copy endianess flag */
- cts->reversed = itdb->reversed;
+ /* set endianess flag */
+ if (!itdb->device->endianess_set)
+ itdb_device_autodetect_endianess (itdb->device);
+ cts->reversed = itdb->device->endianess_reversed;
reassign_ids (fexp);
@@ -4158,7 +4180,7 @@ gboolean itdb_write (Itdb_iTunesDB *itdb, GError **error)
gboolean result = FALSE;
g_return_val_if_fail (itdb, FALSE);
- g_return_val_if_fail (itdb->mountpoint, FALSE);
+ g_return_val_if_fail (itdb_get_mountpoint (itdb), FALSE);
/* First, let's try to write the .ithmb files containing the artwork data
* since this operation modifies the 'artwork_count' and 'artwork_size'
@@ -4168,11 +4190,11 @@ gboolean itdb_write (Itdb_iTunesDB *itdb, GError **error)
*/
- itunes_path = itdb_get_itunes_dir (itdb->mountpoint);
+ itunes_path = itdb_get_itunes_dir (itdb_get_mountpoint (itdb));
if(!itunes_path)
{
- error_no_itunes_dir (itdb->mountpoint, error);
+ error_no_itunes_dir (itdb_get_mountpoint (itdb), error);
return FALSE;
}
@@ -4184,7 +4206,7 @@ gboolean itdb_write (Itdb_iTunesDB *itdb, GError **error)
g_free (itunes_path);
if (result == TRUE)
- result = itdb_rename_files (itdb->mountpoint, error);
+ result = itdb_rename_files (itdb_get_mountpoint (itdb), error);
/* make sure all buffers are flushed as some people tend to
disconnect as soon as gtkpod returns */
@@ -4317,22 +4339,21 @@ All integers in the iTunesSD file are in BIG endian form...
gboolean itdb_shuffle_write (Itdb_iTunesDB *itdb, GError **error)
{
gchar *itunes_filename, *itunes_path;
- const gchar *db[] = {"iPod_Control","iTunes",NULL};
gboolean result = FALSE;
g_return_val_if_fail (itdb, FALSE);
- g_return_val_if_fail (itdb->mountpoint, FALSE);
+ g_return_val_if_fail (itdb_get_mountpoint (itdb), FALSE);
- itunes_path = itdb_resolve_path (itdb->mountpoint, db);
+ itunes_path = itdb_get_itunes_dir (itdb_get_mountpoint (itdb));
if(!itunes_path)
{
- gchar *str = g_build_filename (itdb->mountpoint,
- db[0], db[1], db[2], NULL);
+ gchar *str = g_build_filename (itdb_get_mountpoint (itdb),
+ "iPod_Control", "iTunes", NULL);
g_set_error (error,
ITDB_FILE_ERROR,
ITDB_FILE_ERROR_NOTFOUND,
- _("Path not found: '%s'."),
+ _("Path not found: '%s' (or similar)."),
str);
g_free (str);
return FALSE;
@@ -4346,7 +4367,7 @@ gboolean itdb_shuffle_write (Itdb_iTunesDB *itdb, GError **error)
g_free(itunes_path);
if (result == TRUE)
- result = itdb_rename_files (itdb->mountpoint, error);
+ result = itdb_rename_files (itdb_get_mountpoint (itdb), error);
/* make sure all buffers are flushed as some people tend to
disconnect as soon as gtkpod returns */
@@ -4612,17 +4633,18 @@ void itdb_filename_ipod2fs (gchar *ipod_file)
void itdb_set_mountpoint (Itdb_iTunesDB *itdb, const gchar *mp)
{
g_return_if_fail (itdb);
+ g_return_if_fail (itdb->device);
- g_free (itdb->mountpoint);
- itdb->mountpoint = g_strdup (mp);
- if (itdb->device)
- {
- g_object_unref (G_OBJECT (itdb->device));
- itdb->device = NULL;
- }
- if (mp)
- itdb->device = itdb_device_new (mp);
- itdb->musicdirs = 0;
+ itdb_device_set_mountpoint (itdb->device, mp);
+ itdb->device->musicdirs = 0;
+}
+
+/* Retrieve a reference to the mountpoint */
+const gchar *itdb_get_mountpoint (Itdb_iTunesDB *itdb)
+{
+ g_return_val_if_fail (itdb, NULL);
+ g_return_val_if_fail (itdb->device, NULL);
+ return itdb->device->mountpoint;
}
@@ -4633,41 +4655,14 @@ void itdb_set_mountpoint (Itdb_iTunesDB *itdb, const gchar *mp)
itdb->musicdirs. */
gint itdb_musicdirs_number (Itdb_iTunesDB *itdb)
{
- gchar *dest_components[] = {"Music", NULL, NULL};
- gchar *dir_filename = NULL;
- gint dir_num;
-
g_return_val_if_fail (itdb, 0);
- g_return_val_if_fail (itdb->mountpoint, 0);
+ g_return_val_if_fail (itdb->device, 0);
- if (itdb->musicdirs <= 0)
- {
- gchar *control_dir = itdb_get_control_dir (itdb->mountpoint);
- if (!control_dir) return 0;
- /* count number of dirs */
- for (dir_num=0; ;++dir_num)
- {
- gchar dir_num_str[5];
-
- g_snprintf (dir_num_str, 5, "F%02d", dir_num);
- dest_components[1] = dir_num_str;
-
- dir_filename =
- itdb_resolve_path (control_dir,
- (const gchar **)dest_components);
-
- if (!dir_filename) break;
- g_free (dir_filename);
- }
- itdb->musicdirs = dir_num;
- g_free (control_dir);
- }
- return itdb->musicdirs;
+ return itdb_device_musicdirs_number (itdb->device);
}
-
/* Copy one track to the iPod. The PC filename is @filename
and is taken literally.
@@ -4699,12 +4694,12 @@ gboolean itdb_cp_track_to_ipod (Itdb_Track *track,
g_return_val_if_fail (track, FALSE);
g_return_val_if_fail (track->itdb, FALSE);
- g_return_val_if_fail (track->itdb->mountpoint, FALSE);
+ g_return_val_if_fail (itdb_get_mountpoint (track->itdb), FALSE);
g_return_val_if_fail (filename, FALSE);
if(track->transferred) return TRUE; /* nothing to do */
- mountpoint = track->itdb->mountpoint;
+ mountpoint = itdb_get_mountpoint (track->itdb);
itdb = track->itdb;
/* If track->ipod_path exists, we use that one instead. */
@@ -4712,55 +4707,57 @@ gboolean itdb_cp_track_to_ipod (Itdb_Track *track,
if (!ipod_fullfile)
{
- gchar *dest_components[] = {"Music", NULL, NULL, NULL};
- gchar *parent_dir_filename, *control_dir;
+ gchar *dest_components[] = {NULL, NULL, NULL};
+ gchar *parent_dir_filename, *music_dir;
gchar *original_suffix;
gchar dir_num_str[5];
gint32 oops = 0;
gint32 rand = g_random_int_range (0, 899999); /* 0 to 900000 */
- control_dir = itdb_get_control_dir (mountpoint);
- if (!control_dir)
+ music_dir = itdb_get_music_dir (mountpoint);
+ if (!music_dir)
{
- error_no_control_dir (mountpoint, error);
+ error_no_music_dir (mountpoint, error);
return FALSE;
}
if (itdb_musicdirs_number (itdb) <= 0)
{
- gchar *str = g_build_filename (control_dir, "Music", NULL);
-
g_set_error (error,
ITDB_FILE_ERROR,
ITDB_FILE_ERROR_NOTFOUND,
- _("No 'F..' directories found in '%s' (or similar)."),
- str);
- g_free (str);
- g_free (control_dir);
+ _("No 'F..' directories found in '%s'."),
+ music_dir);
+ g_free (music_dir);
return FALSE;
}
- if (dir_num == -1) dir_num = g_random_int_range (0, itdb->musicdirs);
- else dir_num = (dir_num + 1) % itdb_musicdirs_number (itdb);
+ if (dir_num == -1)
+ {
+ dir_num = g_random_int_range (0, itdb_musicdirs_number (itdb));
+ }
+ else
+ {
+ dir_num = (dir_num + 1) % itdb_musicdirs_number (itdb);
+ }
g_snprintf (dir_num_str, 5, "F%02d", dir_num);
- dest_components[1] = dir_num_str;
+ dest_components[0] = dir_num_str;
parent_dir_filename =
- itdb_resolve_path (control_dir, (const gchar **)dest_components);
+ itdb_resolve_path (music_dir, (const gchar **)dest_components);
if(parent_dir_filename == NULL)
{
/* Can't find the F%02d directory */
- gchar *str = g_build_filename (control_dir,
- dest_components[0],
- dest_components[1], NULL);
+ gchar *str = g_build_filename (music_dir,
+ dest_components[0], NULL);
g_set_error (error,
ITDB_FILE_ERROR,
ITDB_FILE_ERROR_NOTFOUND,
_("Path not found: '%s'."),
str);
g_free (str);
- g_free (control_dir);
+ g_free (music_dir);
return FALSE;
}
@@ -4773,12 +4770,12 @@ gboolean itdb_cp_track_to_ipod (Itdb_Track *track,
do
{ /* we need to loop until we find an unused filename */
- dest_components[2] =
+ dest_components[1] =
g_strdup_printf("gtkpod%06d%s",
rand + oops, original_suffix);
ipod_fullfile = itdb_resolve_path (
parent_dir_filename,
- (const gchar **)&dest_components[2]);
+ (const gchar **)&dest_components[1]);
if(ipod_fullfile)
{ /* already exists -- try next */
g_free(ipod_fullfile);
@@ -4787,13 +4784,13 @@ gboolean itdb_cp_track_to_ipod (Itdb_Track *track,
else
{ /* found unused file -- build filename */
ipod_fullfile = g_build_filename (parent_dir_filename,
- dest_components[2], NULL);
+ dest_components[1], NULL);
}
- g_free (dest_components[2]);
+ g_free (dest_components[1]);
++oops;
} while (!ipod_fullfile);
g_free(parent_dir_filename);
- g_free (control_dir);
+ g_free (music_dir);
}
/* now extract filepath for track->ipod_path from ipod_fullfile */
/* ipod_path must begin with a '/' */
@@ -4850,9 +4847,9 @@ gchar *itdb_filename_on_ipod (Itdb_Track *track)
g_return_val_if_fail (track, NULL);
g_return_val_if_fail (track->itdb, NULL);
- if (!track->itdb->mountpoint) return NULL;
+ if (!itdb_get_mountpoint (track->itdb)) return NULL;
- mp = track->itdb->mountpoint;
+ mp = itdb_get_mountpoint (track->itdb);
if(track->ipod_path && *track->ipod_path)
{
@@ -4991,7 +4988,7 @@ gboolean itdb_cp (const gchar *from_file, const gchar *to_file,
* passing a pointer to the itdb because this function may be used
* without relation to a particular itdb.
*
- * Return value: path to the control dir or NULL of none exists. Must
+ * Return value: path to the control dir or NULL of non-existent. Must
* g_free() after use.
*/
gchar *itdb_get_control_dir (const gchar *mountpoint)
@@ -5013,29 +5010,140 @@ gchar *itdb_get_control_dir (const gchar *mountpoint)
return result;
}
-/* Retrieve the iTunes directory (containing the iTunesDB) by first
- * calling itdb_get_control_dir() and then adding 'iTunes'
+/* Retrieve the directory @dir by first calling itdb_get_control_dir()
+ * and then adding @dir
*
- * Return value: path to the iTunes directory or NULL of non
- * exists. Must g_free() after use.
+ * Return value: path to @dir or NULL if non-existent. Must g_free()
+ * after use.
*/
-gchar *itdb_get_itunes_dir (const gchar *mountpoint)
+static gchar *itdb_get_dir (const gchar *mountpoint, const gchar *dir)
{
- const gchar *p_itunes[] = {"iTunes", NULL};
gchar *control_dir;
gchar *result = NULL;
g_return_val_if_fail (mountpoint, NULL);
+ g_return_val_if_fail (dir, NULL);
control_dir = itdb_get_control_dir (mountpoint);
if (control_dir)
{
- result = itdb_resolve_path (control_dir, p_itunes);
+ const gchar *p_dir[] = {NULL, NULL};
+ p_dir[0] = dir;
+ result = itdb_resolve_path (control_dir, p_dir);
g_free (control_dir);
}
return result;
}
+/* Retrieve a path to the @file in @dir
+ *
+ * Return value: path to the @file or NULL if non-existent.
+ */
+gchar *itdb_get_path (const gchar *dir, const gchar *file)
+{
+ const gchar *p_file[] = {NULL, NULL};
+
+ g_return_val_if_fail (dir, NULL);
+
+ p_file[0] = dir;
+
+ return itdb_resolve_path (dir, p_file);
+}
+
+/* Retrieve the iTunes directory (containing the iTunesDB) by first
+ * calling itdb_get_control_dir() and then adding 'iTunes'
+ *
+ * Return value: path to the iTunes directory or NULL of non-existent.
+ * Must g_free() after use.
+ */
+gchar *itdb_get_itunes_dir (const gchar *mountpoint)
+{
+ g_return_val_if_fail (mountpoint, NULL);
+
+ return itdb_get_dir (mountpoint, "iTunes");
+}
+
+/* Retrieve the Music directory (containing the Fnn dirs) by first
+ * calling itdb_get_control_dir() and then adding 'Music'
+ *
+ * Return value: path to the Music directory or NULL of
+ * non-existent. Must g_free() after use.
+ */
+gchar *itdb_get_music_dir (const gchar *mountpoint)
+{
+ g_return_val_if_fail (mountpoint, NULL);
+
+ return itdb_get_dir (mountpoint, "Music");
+}
+
+/* Retrieve the Device directory (containing the SysInfo file) by
+ * first calling itdb_get_control_dir() and then adding 'Device'
+ *
+ * Return value: path to the Device directory or NULL of
+ * non-existent. Must g_free() after use.
+ */
+gchar *itdb_get_device_dir (const gchar *mountpoint)
+{
+ g_return_val_if_fail (mountpoint, NULL);
+
+ return itdb_get_dir (mountpoint, "Device");
+}
+
+/* Retrieve the Artwork directory (containing the SysInfo file) by
+ * first calling itdb_get_control_dir() and then adding 'Artwork'
+ *
+ * Return value: path to the Artwork directory or NULL of
+ * non-existent. Must g_free() after use.
+ */
+gchar *itdb_get_artwork_dir (const gchar *mountpoint)
+{
+ g_return_val_if_fail (mountpoint, NULL);
+
+ return itdb_get_dir (mountpoint, "Artwork");
+}
+
+/* Retrieve a path to the iTunesDB
+ *
+ * Return value: path to the iTunesDB or NULL if non-existent.
+ */
+gchar *itdb_get_itunesdb_path (const gchar *mountpoint)
+{
+ gchar *itunes_dir, *path=NULL;
+
+ g_return_val_if_fail (mountpoint, NULL);
+
+ itunes_dir = itdb_get_itunes_dir (mountpoint);
+
+ if (itunes_dir)
+ {
+ path = itdb_get_path (itunes_dir, "iTunesDB");
+ g_free (itunes_dir);
+ }
+
+ return path;
+}
+
+/* Retrieve a path to the ArtworkDB
+ *
+ * Return value: path to the ArtworkDB or NULL if non-existent.
+ */
+gchar *itdb_get_artworkdb_path (const gchar *mountpoint)
+{
+ gchar *itunes_dir, *path=NULL;
+
+ g_return_val_if_fail (mountpoint, NULL);
+
+ itunes_dir = itdb_get_artwork_dir (mountpoint);
+
+ if (itunes_dir)
+ {
+ path = itdb_get_path (itunes_dir, "ArtworkDB");
+ g_free (itunes_dir);
+ }
+
+ return path;
+}
+
/*------------------------------------------------------------------*\
* *
diff --git a/src/itdb_private.h b/src/itdb_private.h
index 5eacc3d..c67647e 100644
--- a/src/itdb_private.h
+++ b/src/itdb_private.h
@@ -1,4 +1,4 @@
-/* Time-stamp: <2006-03-11 01:27:48 jcs>
+/* Time-stamp: <2006-03-15 00:11:00 jcs>
|
| Copyright (C) 2002-2005 Jorg Schuler <jcsjcs at users sourceforge net>
| Part of the gtkpod project.
diff --git a/src/itdb_track.c b/src/itdb_track.c
index a89ea4f..c85e207 100644
--- a/src/itdb_track.c
+++ b/src/itdb_track.c
@@ -1,4 +1,4 @@
-/* Time-stamp: <2005-12-04 19:10:42 jcs>
+/* Time-stamp: <2006-03-15 00:11:15 jcs>
|
| Copyright (C) 2002-2005 Jorg Schuler <jcsjcs at users sourceforge net>
| Part of the gtkpod project.
@@ -30,18 +30,24 @@
#include <config.h>
#include "itdb_private.h"
+#include "itdb_device.h"
#include <string.h>
-static gboolean is_video_ipod (IpodDevice *ipod)
+static gboolean is_video_ipod (Itdb_Device *device)
{
- guint model;
+ const Itdb_IpodModel *model;
- if (ipod == NULL) {
- return FALSE;
- }
- g_object_get (G_OBJECT (ipod), "device-model", &model, NULL);
- return ((model == MODEL_TYPE_VIDEO_WHITE)
- || (model == MODEL_TYPE_VIDEO_BLACK));
+ g_return_val_if_fail (device, FALSE);
+
+ model = itdb_device_get_ipod_model (device);
+
+ if (!model) return FALSE;
+
+ if ((model->model_type == MODEL_TYPE_VIDEO_WHITE) ||
+ (model->model_type == MODEL_TYPE_VIDEO_BLACK))
+ return TRUE;
+ else
+ return FALSE;
}
diff --git a/src/ithumb-writer.c b/src/ithumb-writer.c
index e6411b9..957aca8 100644
--- a/src/ithumb-writer.c
+++ b/src/ithumb-writer.c
@@ -45,7 +45,7 @@ struct _iThumbWriter {
off_t cur_offset;
FILE *f;
gchar *filename;
- IpodArtworkFormat *img_info;
+ Itdb_ArtworkFormat *img_info;
GHashTable *cache;
};
typedef struct _iThumbWriter iThumbWriter;
@@ -105,35 +105,40 @@ pack_RGB_565 (GdkPixbuf *pixbuf, int dst_width, int dst_height)
static char *
ipod_image_get_ithmb_filename (const char *mount_point, gint correlation_id, gint index)
{
- char *paths[] = {"iPod_Control", "Artwork", NULL, NULL};
- char *filename, *buf;
+ gchar *artwork_dir, *filename, *buf;
- buf = g_strdup_printf ("F%04u_%d.ithmb", correlation_id, index);
+ g_return_val_if_fail (mount_point, NULL);
+ artwork_dir = itdb_get_artwork_dir (mount_point);
+ if (!artwork_dir)
+ {
+ /* attempt to create Artwork dir */
+ gchar *control_dir = itdb_get_control_dir (mount_point);
+ gchar *dir;
+ if (!control_dir)
+ { /* give up */
+ return NULL;
+ }
+ dir = g_build_filename (control_dir, "Artwork", NULL);
+ mkdir (dir, 0777);
+ g_free (dir);
+ g_free (control_dir);
+
+ /* try again */
+ artwork_dir = itdb_get_artwork_dir (mount_point);
+ if (!artwork_dir)
+ { /* give up */
+ return NULL;
+ }
+ }
- paths[2] = buf;
+ buf = g_strdup_printf ("F%04u_%d.ithmb", correlation_id, index);
- filename = itdb_resolve_path (mount_point, (const char **)paths);
+ filename = itdb_get_path (artwork_dir, buf);
- /* itdb_resolve_path() only returns existing paths */
+ /* itdb_get_path() only returns existing paths */
if (!filename)
{
- gchar *path;
- paths[2] = NULL;
- path = itdb_resolve_path (mount_point, (const char **)paths);
- if (path == NULL)
- { /* attempt to create directory */
- gchar *pth = g_build_filename (mount_point,
- paths[0], paths[1], NULL);
- mkdir (pth, 0777);
- g_free (pth);
- path = itdb_resolve_path (mount_point,
- (const char **)paths);
- }
- if (path)
- {
- filename = g_build_filename (path, buf, NULL);
- }
- g_free (path);
+ filename = g_build_filename (artwork_dir, buf, NULL);
}
g_free (buf);
@@ -239,14 +244,14 @@ write_thumbnail (gpointer _writer, gpointer _artwork)
}
static iThumbWriter *
-ithumb_writer_new (const char *mount_point, const IpodArtworkFormat *info)
+ithumb_writer_new (const char *mount_point, const Itdb_ArtworkFormat *info)
{
char *filename;
iThumbWriter *writer;
writer = g_new0 (iThumbWriter, 1);
- writer->img_info = g_memdup (info, sizeof (IpodArtworkFormat));
+ writer->img_info = g_memdup (info, sizeof (Itdb_ArtworkFormat));
writer->cache = g_hash_table_new_full (g_str_hash, g_str_equal,
g_free, NULL);
@@ -499,7 +504,7 @@ static gboolean ithumb_rearrange_thumbnail_file (gpointer _key,
*/
static gboolean
ithmb_rearrange_existing_thumbnails (Itdb_iTunesDB *itdb,
- const IpodArtworkFormat *info)
+ const Itdb_ArtworkFormat *info)
{
GList *gl;
GHashTable *filenamehash;
@@ -507,10 +512,15 @@ ithmb_rearrange_existing_thumbnails (Itdb_iTunesDB *itdb,
GList *thumbs;
gint i;
gchar *filename;
+ const gchar *mountpoint;
g_return_val_if_fail (itdb, FALSE);
g_return_val_if_fail (info, FALSE);
- g_return_val_if_fail (itdb->mountpoint, FALSE);
+ g_return_val_if_fail (itdb->device, FALSE);
+
+ mountpoint = itdb_get_mountpoint (itdb);
+
+ g_return_val_if_fail (mountpoint, FALSE);
filenamehash = g_hash_table_new_full (g_str_hash, g_str_equal,
g_free, NULL);
@@ -545,7 +555,7 @@ ithmb_rearrange_existing_thumbnails (Itdb_iTunesDB *itdb,
for (i=0; i<10; ++i)
{
- filename = ipod_image_get_ithmb_filename (itdb->mountpoint,
+ filename = ipod_image_get_ithmb_filename (mountpoint,
info->correlation_id,
i);
if (g_file_test (filename, G_FILE_TEST_EXISTS))
@@ -574,13 +584,13 @@ itdb_write_ithumb_files (Itdb_iTunesDB *db)
#ifdef HAVE_GDKPIXBUF
GList *writers;
GList *it;
- gchar *mount_point;
- const IpodArtworkFormat *format;
+ const gchar *mount_point;
+ const Itdb_ArtworkFormat *format;
/* g_print ("%s\n", G_GNUC_FUNCTION);*/
g_return_val_if_fail (db, -1);
- mount_point = db->mountpoint;
+ mount_point = itdb_get_mountpoint (db);
/* FIXME: support writing to directory rather than writing to
iPod */
if (mount_point == NULL)
@@ -590,8 +600,7 @@ itdb_write_ithumb_files (Itdb_iTunesDB *db)
return -1;
}
- g_object_get (G_OBJECT (db->device), "artwork-formats",
- &format, NULL);
+ format = itdb_device_get_artwork_formats (db->device);
if (format == NULL) {
return -1;
}