summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJorg Schuler <jcsjcs@users.sourceforge.net>2007-09-24 15:01:53 +0000
committerJorg Schuler <jcsjcs@users.sourceforge.net>2007-09-24 15:01:53 +0000
commit823e79e0c187c0581fc35e2a81c771dfd14ca8ee (patch)
tree66d7836369283bfb446a703d020b45f4ef0d0d86
parent361b8c45dec96359bd44db935f5fd9fb728a9e21 (diff)
downloadlibgpod-823e79e0c187c0581fc35e2a81c771dfd14ca8ee.tar.gz
libgpod-823e79e0c187c0581fc35e2a81c771dfd14ca8ee.tar.xz
libgpod-823e79e0c187c0581fc35e2a81c771dfd14ca8ee.zip
Forgot to add itdb_sysinfo.c
git-svn-id: https://gtkpod.svn.sf.net/svnroot/gtkpod/libgpod/trunk@1699 f01d2545-417e-4e96-918e-98f8d0dbbcb6
-rw-r--r--ChangeLog1
-rw-r--r--src/itdb_sysinfo.c269
2 files changed, 270 insertions, 0 deletions
diff --git a/ChangeLog b/ChangeLog
index 5cd1fa0..2ec7ef7 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -5,6 +5,7 @@
* src/itdb_itunesdb.c (mk_mhbd): write extended header needed
for new iPod Nanos (3G Video) and iPod Classics.
+ src/itdb_sysinfo.c
src/itdb_device.c
src/itdb_device.h: Code to parse SysInfoExtended and SysInfo
for the FireWireGUID. You must either copy the iPod
diff --git a/src/itdb_sysinfo.c b/src/itdb_sysinfo.c
new file mode 100644
index 0000000..45a4057
--- /dev/null
+++ b/src/itdb_sysinfo.c
@@ -0,0 +1,269 @@
+/*
+| Copyright (C) 2002-2007 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 <string.h>
+
+#include <glib.h>
+
+#include "itdb_device.h"
+
+enum ParsingState {
+ LOOKING_FOR_KEY_TAG,
+ PARSING_KEY_TAG,
+ LOOKING_FOR_FW_DATA,
+ PARSING_FW_DATA,
+ DONE
+};
+
+struct _SysInfoParseContext {
+ enum ParsingState state;
+ char *text;
+ Itdb_Device *device;
+};
+typedef struct _SysInfoParseContext SysInfoParseContext;
+
+
+static void parse_start_element (GMarkupParseContext *context,
+ const gchar *element_name,
+ const gchar **attribute_names,
+ const gchar **attribute_values,
+ gpointer user_data,
+ GError **error)
+{
+ SysInfoParseContext *sysinfo = (SysInfoParseContext *)user_data;
+
+#ifdef DEBUG
+ g_print ("start: %s\n", element_name);
+#endif
+ switch (sysinfo->state) {
+ case DONE:
+ break;
+ case LOOKING_FOR_FW_DATA:
+ if (strcmp (element_name, "string") == 0) {
+ sysinfo->state = PARSING_FW_DATA;
+ break;
+ }
+ /* Fallback to default case if we didn't find the tag we expected */
+ case LOOKING_FOR_KEY_TAG:
+ default:
+ if (strcmp (element_name, "key") == 0) {
+ sysinfo->state = PARSING_KEY_TAG;
+ } else {
+ sysinfo->state = LOOKING_FOR_KEY_TAG;
+ }
+ break;
+ }
+}
+
+static void parse_end_element (GMarkupParseContext *context,
+ const gchar *element_name,
+ gpointer user_data,
+ GError **error)
+{
+ SysInfoParseContext *sysinfo = (SysInfoParseContext *)user_data;
+
+#ifdef DEBUG
+ g_print ("end: %s\n", element_name);
+#endif
+
+ switch (sysinfo->state) {
+ case PARSING_KEY_TAG:
+ if (sysinfo->text == NULL) {
+ sysinfo->state = LOOKING_FOR_KEY_TAG;
+ break;
+ }
+ if (strcmp (sysinfo->text, "FireWireGUID") == 0) {
+ sysinfo->state = LOOKING_FOR_FW_DATA;
+ } else {
+ sysinfo->state = LOOKING_FOR_KEY_TAG;
+ }
+ g_free (sysinfo->text);
+ sysinfo->text = NULL;
+ break;
+ case PARSING_FW_DATA:
+ if (sysinfo->text == NULL) {
+ sysinfo->state = LOOKING_FOR_KEY_TAG;
+ }
+ /* Use FirewireGuid instead of FireWireGUID to be coherent with what
+ * the SysInfo file used to contain
+ */
+ g_hash_table_insert (sysinfo->device->sysinfo,
+ g_strdup ("FirewireGuid"),
+ sysinfo->text);
+ sysinfo->text = NULL;
+ sysinfo->state = DONE;
+ break;
+ case LOOKING_FOR_KEY_TAG:
+ case LOOKING_FOR_FW_DATA:
+ case DONE:
+ break;
+
+ }
+}
+
+static void parse_text (GMarkupParseContext *context,
+ const gchar *text,
+ gsize text_len,
+ gpointer user_data,
+ GError **error)
+{
+#ifdef DEBUG
+ char *str = g_strndup (text, text_len);
+ g_print ("text: %s\n", str);
+ g_free (str);
+#endif
+
+ SysInfoParseContext *sysinfo = (SysInfoParseContext *)user_data;
+ switch (sysinfo->state) {
+ case DONE:
+ break;
+ case PARSING_FW_DATA:
+ case PARSING_KEY_TAG:
+ g_free (sysinfo->text);
+ sysinfo->text = g_strndup (text, text_len);
+ break;
+ default:
+ g_free (sysinfo->text);
+ sysinfo->text = NULL;
+ break;
+ }
+}
+
+static void parse_error (GMarkupParseContext *context,
+ GError *error,
+ gpointer user_data)
+{
+ gint line;
+ gint row;
+ g_markup_parse_context_get_position (context, &line, &row);
+ g_warning ("error at line %i row %i", line, row);
+}
+
+static char *
+get_sysinfo_extended_path (Itdb_Device *device)
+{
+ const gchar *p_sysinfo[] = {"SysInfoExtended", NULL};
+ gchar *dev_path, *sysinfo_path;
+
+ dev_path = itdb_get_device_dir (device->mountpoint);
+
+ if (!dev_path) {
+ return NULL;
+ }
+
+ sysinfo_path = itdb_resolve_path (dev_path, p_sysinfo);
+ g_free (dev_path);
+ return sysinfo_path;
+}
+
+static void init_gmarkup_parser (GMarkupParser *parser)
+{
+ parser->start_element = parse_start_element;
+ parser->end_element = parse_end_element;
+ parser->text = parse_text;
+ parser->error = parse_error;
+}
+
+
+static gboolean parse_sysinfo_xml (Itdb_Device *device,
+ const char *xml, gsize len,
+ GError **error)
+{
+ GMarkupParseContext *ctx;
+ GMarkupParser parser = {0, };
+ gboolean success;
+
+ SysInfoParseContext sysinfo = {0, };
+ sysinfo.state = LOOKING_FOR_KEY_TAG;
+ sysinfo.device = device;
+
+ init_gmarkup_parser (&parser);
+ ctx = g_markup_parse_context_new (&parser, 0, &sysinfo, NULL);
+ success = g_markup_parse_context_parse (ctx, xml, len, error);
+ if (!success) {
+ g_markup_parse_context_free (ctx);
+ return FALSE;
+ }
+ success = g_markup_parse_context_end_parse (ctx, error);
+ if (!success) {
+ g_markup_parse_context_free (ctx);
+ return FALSE;
+ }
+ g_markup_parse_context_free (ctx);
+
+ return TRUE;
+}
+
+/**
+ * itdb_device_read_sysinfo_xml:
+ * @device: an #Itdb_Device
+ * @error: return location for a #GError or NULL
+ *
+ * Parses a SysInfoExtended file located in iPod_Control/Device on the
+ * passed-in @device. This file contains a detailed description of the iPod
+ * capabilities/characteristics. In particular, it contains the iPod Firewire
+ * ID which is necessary to build the checksum of the iTunesDB.
+ * That file is automatically parsed when @device mount point is set
+ * if it can be found.
+ *
+ * If a SysInfoExtended file could be successfully read, TRUE is returned.
+ * Otherwise it returns FALSE and sets @error.
+ *
+ * Return value: TRUE on success, FALSE if an error occurred
+ *
+ **/
+gboolean
+itdb_device_read_sysinfo_xml (Itdb_Device *device, GError **error)
+{
+ gboolean success;
+ char *sysinfo_path;
+ char *xml_data;
+ gsize len;
+
+ sysinfo_path = get_sysinfo_extended_path (device);
+ if (sysinfo_path == NULL) {
+ g_set_error (error, ITDB_FILE_ERROR, ITDB_FILE_ERROR_NOTFOUND,
+ "Couldn't find SysInfoExtended file");
+ return FALSE;
+ }
+ success = g_file_get_contents (sysinfo_path, &xml_data, &len, error);
+ g_free (sysinfo_path);
+
+ if (!success) {
+ return FALSE;
+ }
+
+ success = parse_sysinfo_xml (device, xml_data, len, error);
+ g_free (xml_data);
+
+ return success;
+}