diff options
author | Jorg Schuler <jcsjcs@users.sourceforge.net> | 2007-09-24 15:01:53 +0000 |
---|---|---|
committer | Jorg Schuler <jcsjcs@users.sourceforge.net> | 2007-09-24 15:01:53 +0000 |
commit | 823e79e0c187c0581fc35e2a81c771dfd14ca8ee (patch) | |
tree | 66d7836369283bfb446a703d020b45f4ef0d0d86 | |
parent | 361b8c45dec96359bd44db935f5fd9fb728a9e21 (diff) | |
download | libgpod-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-- | ChangeLog | 1 | ||||
-rw-r--r-- | src/itdb_sysinfo.c | 269 |
2 files changed, 270 insertions, 0 deletions
@@ -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; +} |