rendered paste bodycommit 5be58b42bd9c401324849d958d6beb6871bcb55dAuthor: erik <erik@37441250-4157-47a9-a2c9-f9fe3212d2d3>Date: Wed Jun 6 16:23:41 2007 +0000 Added Songbird patches to libgpod. git-svn-id: http://publicsvn.songbirdnest.com/vendor/trunk/dependencies/vendor/libgpod@4910 37441250-4157-47a9-a2c9-f9fe3212d2d3diff --git a/src/itdb.h b/src/itdb.hindex 422dc95..e5e0c47 100644--- a/src/itdb.h+++ b/src/itdb.h@@ -66,6 +66,7 @@ typedef struct _Itdb_Playlist Itdb_Playlist; typedef struct _Itdb_PhotoAlbum Itdb_PhotoAlbum; typedef struct _Itdb_Track Itdb_Track; typedef struct _Itdb_IpodInfo Itdb_IpodInfo;+typedef struct _Itdb_Prefs Itdb_Prefs; /* ------------------------------------------------------------ *\@@ -799,6 +800,56 @@ struct _Itdb_Track /* (gtkpod note: don't forget to add fields read from the file to * copy_new_info() in file.c!) */ +/* default iPod preferences contents */+const static gchar default_prefs[] =+{+ 0x66, 0x72, 0x70, 0x64, 0x01, 0x00, 0x03, 0x00,+ 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0x6e, 0x39, 0x0e, 0x70,+ 0x8f, 0xdc, 0x6f, 0x76, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x6f, 0x39, 0x0e, 0x70, 0x8f, 0xdc, 0x6f, 0x76,+ 0x02, 0x00, 0x00, 0x00, 0x6e, 0x39, 0x0e, 0x70,+ 0x8f, 0xdc, 0x6f, 0x76, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x00+};++struct _Itdb_Prefs+{+ gchar *contents; /* preferences file contents */+ gint length; /* contents length */+ gboolean valid_file; /* true if valid preferences file read */+ guint8 ipod_set_up; /* Offset 0x08: 0x00 iPod has not been set up+ !0x00 iPod has been set up */+ guint8 music_mgmt_type; /* Offset 0x0A: 0x00 manual management+ !0x00 auto update */+ guint8 music_update_type; /* Offset 0x0B: 0x01 update all+ 0x02 update playlists */+ guint64 music_lib_link_id; /* Offset 0x0C: ID of music library linked to+ iPod */+};+ /* ------------------------------------------------------------ *\ *@@ -1003,6 +1057,17 @@ gboolean itdb_init_ipod (const gchar *mountpoint, const gchar *ipod_name, GError **error); +/* prefs functions */+Itdb_Prefs *itdb_prefs_new (void);+void itdb_prefs_free (Itdb_Prefs *prefs);+Itdb_Prefs *itdb_prefs_parse(Itdb_Device *device, GError **error);+gboolean itdb_prefs_write(Itdb_Device *device, Itdb_Prefs *prefs,+ GError **error);+gboolean itdb_update_playlists_read(Itdb_Device *device, guint64 **playlists,+ gint *num_playlists, GError **error);+gboolean itdb_update_playlists_write(Itdb_Device *device, guint64 *playlists,+ gint num_playlists, GError **error);+ G_END_DECLS #endifdiff --git a/src/itdb_itunesdb.c b/src/itdb_itunesdb.cindex f95d4ef..d7f3ea7 100644--- a/src/itdb_itunesdb.c+++ b/src/itdb_itunesdb.c@@ -5927,3 +5951,307 @@ static gboolean itdb_create_directories (Itdb_Device *device, GError **error) g_free (podpath); return result; }++/*zzz should put in itdb_prefs.c */++/**+ * itdb_prefs_new:+ *+ * Creates a new Itdb_Prefs.+ *+ * Return value: a newly created Itdb_Prefs to be freed with itdb_prefs_free()+ * when it's no longer needed+ **/+Itdb_Prefs *itdb_prefs_new (void)+{+ Itdb_Prefs *prefs = g_new0 (Itdb_Prefs, 1);+ prefs->contents = NULL;+ prefs->valid_file = FALSE;++ return prefs;+}++/** + * itdb_prefs_free:+ * @prefs: an #Itdb_Prefs+ *+ * Free the memory taken by @prefs. + **/+void itdb_prefs_free (Itdb_Prefs *prefs)+{+ if (prefs)+ {+ if (prefs->contents)+ g_free(prefs->contents);+ g_free (prefs);+ }+}++/**+ * itdb_prefs_parse:+ * @device: an #Itdb_Device+ * @error: return location for a #GError or NULL+ *+ * Parse the Itdb_Prefs of the iPod device @device+ *+ * Return value: a newly allocated #Itdb_Prefs struct holding the preference+ * settings of the iPod @device, NULL if the preferences file could not be read.+ * If non-NULL, the #Itdb_Prefs is to be freed with itdb_prefs_free() when it's+ * no longer needed+ **/+Itdb_Prefs *itdb_prefs_parse(Itdb_Device *device, GError **error)+{+ gchar *prefs_filename;+ gchar *itunes_dir;+ Itdb_Prefs *prefs = NULL;+ const gchar *p_prefspath[] = {"iTunesPrefs", NULL};+ gchar *contents = NULL;+ gsize length = 0;++ itunes_dir = itdb_get_itunes_dir (device->mountpoint);++ if (!itunes_dir)+ {+ error_no_itunes_dir (device->mountpoint, error);+ return NULL;+ }++ prefs = itdb_prefs_new ();++ prefs_filename = itdb_resolve_path(itunes_dir, p_prefspath);+ if (prefs_filename)+ {+ if (g_file_get_contents (prefs_filename, &contents, &length, error))+ prefs->valid_file = TRUE;+ g_free (prefs_filename);+ }++ /* if a complete, valid preferences file is not available, + * fill preferences contents in with default values */+ if (length < sizeof (default_prefs))+ {+ prefs->contents = g_malloc (sizeof (default_prefs));+ prefs->length = sizeof (default_prefs);+ bcopy (default_prefs, prefs->contents, sizeof (default_prefs));+ bcopy (contents, prefs->contents, length);+ g_free (contents);+ contents = prefs->contents;+ }+ else+ {+ prefs->contents = contents;+ prefs->length = length;+ }++ prefs->ipod_set_up = contents[0x08];+ prefs->music_mgmt_type = contents[0x0A];+ prefs->music_update_type = contents[0x0B];+ bcopy (&(contents[0x0C]), &(prefs->music_lib_link_id), 8);++ g_free (itunes_dir);+ return prefs;+}++/**+ * itdb_prefs_write:+ * @device: an #Itdb_Device+ * @prefs: the #Itdb_Prefs to write to the iPod+ * @error: return location for a #GError or NULL+ *+ * Write out an iPod preferences file.+ *+ * Return value: TRUE on success, FALSE on error, in which case @error is+ * set accordingly.+ *zzz should be able to create file if it doesn't exist.+ *zzz endianess?+ **/+gboolean itdb_prefs_write(Itdb_Device *device, Itdb_Prefs *prefs,+ GError **error)+{+ gchar *prefs_filename = NULL, *itunes_path = NULL;+ FILE *fd;+ gint length;+ gchar *contents = NULL;+ gboolean result = TRUE;++ g_return_val_if_fail (device, FALSE);+ g_return_val_if_fail (device->mountpoint, FALSE);+ g_return_val_if_fail (prefs, FALSE);++ itunes_path = itdb_get_itunes_dir (device->mountpoint);++ if(!itunes_path)+ {+ error_no_itunes_dir (device->mountpoint, error);+ return FALSE;+ }++ prefs_filename = g_build_filename (itunes_path, "iTunesPrefs", NULL);++ /* get the preferences contents */+ contents = prefs->contents;+ length = prefs->length;++ /* update the known preferences */+ contents[0x08] = prefs->ipod_set_up;+ contents[0x0A] = prefs->music_mgmt_type;+ contents[0x0B] = prefs->music_update_type;+ bcopy (&(prefs->music_lib_link_id), &(contents[0x0C]), 8);++ /* open the preferences file for writing */+ fd = fopen(prefs_filename, "wb");+ if (fd == NULL)+ {+ g_set_error (error,+ G_FILE_ERROR,+ g_file_error_from_errno (errno),+ _("Error opening '%s' for writing (%s)."),+ prefs_filename, g_strerror (errno));+ return FALSE;+ }++ /* write the preferences file */+ fwrite(contents, 1, length, fd);+ fclose(fd);++ if (prefs_filename)+ g_free (prefs_filename);+ if (itunes_path)+ g_free (itunes_path);++ /* make sure all buffers are flushed as some people tend to+ disconnect as soon as gtkpod returns */+ sync ();++ return result;+}++/**+ * itdb_update_playlists_read:+ * @device: an #Itdb_Device+ * @playlists: returned list of update playlist IDs+ * @num_playlists: returned number of update playlists+ * @error: return location for a #GError or NULL+ *+ * Read an iPod update playlists file.+ *+ * Return value: TRUE on success, FALSE on error, in which case @error is+ * set accordingly.+ *zzz endianess?+ **/+gboolean itdb_update_playlists_read(Itdb_Device *device, guint64 **playlists,+ gint *num_playlists, GError **error)+{+ gchar *playlists_filename = NULL, *itunes_path = NULL;+ gchar *itunes_dir;+ const gchar *p_playlistspath[] = {"iTunesPlaylists", NULL};+ gsize length;++ itunes_dir = itdb_get_itunes_dir (device->mountpoint);++ if (!itunes_dir)+ {+ error_no_itunes_dir (device->mountpoint, error);+ return FALSE;+ }++ playlists_filename = itdb_resolve_path(itunes_dir, p_playlistspath);+ if (playlists_filename)+ {+ if (g_file_get_contents (playlists_filename,+ (gchar **) playlists,+ &length,+ error))+ {+ *num_playlists = length / sizeof (guint64);+ }+ else+ {+ gchar *str = g_build_filename (device->mountpoint,+ p_playlistspath[0],+ NULL);+ g_set_error (error,+ ITDB_FILE_ERROR,+ ITDB_FILE_ERROR_NOTFOUND,+ _("Error reading file: '%s'."),+ str);+ g_free (str);+ }++ g_free (playlists_filename);+ }+ else+ {+ *num_playlists = 0;+ *playlists = NULL;+ }++ g_free (itunes_dir);+ return TRUE;+}++/**+ * itdb_update_playlists_write:+ * @device: an #Itdb_Device+ * @playlists: the list of update playlists to write to the iPod+ * @num_playlists: the number of playlists+ * @error: return location for a #GError or NULL+ *+ * Write out an iPod update playlists file.+ *+ * Return value: TRUE on success, FALSE on error, in which case @error is+ * set accordingly.+ *zzz endianess?+ **/+gboolean itdb_update_playlists_write(Itdb_Device *device, guint64 *playlists,+ gint num_playlists, GError **error)+{+ gchar *playlists_filename = NULL, *itunes_path = NULL;+ FILE *fd;+ int length;+ gboolean result = TRUE;++ g_return_val_if_fail (device, FALSE);+ g_return_val_if_fail (device->mountpoint, FALSE);+ g_return_val_if_fail (playlists, FALSE);++ itunes_path = itdb_get_itunes_dir (device->mountpoint);++ if(!itunes_path)+ {+ error_no_itunes_dir (device->mountpoint, error);+ return FALSE;+ }++ playlists_filename = g_build_filename (itunes_path,+ "iTunesPlaylists",+ NULL);++ /* open the playlists file for writing */+ fd = fopen(playlists_filename, "wb");+ if (fd == NULL)+ {+ g_set_error (error,+ G_FILE_ERROR,+ g_file_error_from_errno (errno),+ _("Error opening '%s' for writing (%s)."),+ playlists_filename, g_strerror (errno));+ return FALSE;+ }++ /* write the playlists file */+ fwrite(playlists, 1, num_playlists * sizeof (guint64), fd);+ fclose(fd);++ if (playlists_filename)+ g_free (playlists_filename);+ if (itunes_path)+ g_free (itunes_path);++ /* make sure all buffers are flushed as some people tend to+ disconnect as soon as gtkpod returns */+ sync ();++ return result;+}+