diff options
-rw-r--r-- | ChangeLog | 13 | ||||
-rw-r--r-- | Makefile.am | 2 | ||||
-rw-r--r-- | configure.ac | 10 | ||||
-rw-r--r-- | tools/Makefile.am | 9 | ||||
-rw-r--r-- | tools/read-sysinfoextended-sgutils.c | 152 |
5 files changed, 184 insertions, 2 deletions
@@ -1,4 +1,15 @@ -2007-09-27 Christophe,,, <teuf@atchoum> +2007-09-27 Christophe Fergeau <teuf@gnome.org> + + * configure.ac: build tool to generate the iPod SysInfoExtended file + if sgutils is detected + * Makefile.am: + * tools/ + * tools/Makefile.am: changes to optionally build the sgutils-based tool + * tools/read-sysinfoextended-sgutils.c: (do_sg_inquiry), + (read_sysinfo_extended), (main): new file, reads the SysInfoExtended + file from the iPod using SCSI queries + +2007-09-27 Christophe Fergeau <teuf@gnome.org> * src/itdb_itunesdb.c: (calculate_db_checksum), (itdb_write_checksum): diff --git a/Makefile.am b/Makefile.am index cdc7beb..a01a801 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,4 +1,4 @@ -SUBDIRS=src tests po m4 docs bindings +SUBDIRS=src tools tests po m4 docs bindings # build documentation when doing a distcheck. DISTCHECK_CONFIGURE_FLAGS = --enable-gtk-doc diff --git a/configure.ac b/configure.ac index ef845fe..60fa565 100644 --- a/configure.ac +++ b/configure.ac @@ -60,6 +60,15 @@ PKG_CHECK_MODULES(LIBGPOD, glib-2.0 >= 2.4.0 gobject-2.0) LIBGPOD_CFLAGS="$LIBGPOD_CFLAGS -Wall" dnl ************************************************** +dnl * sgutils is necessary to get the xml device file from the ipod +dnl ************************************************** +AC_CHECK_LIB(sgutils, sg_ll_inquiry, + [SGUTILS_LIBS="-lsgutils"; have_sgutils=yes], + have_sgutils=no) +AC_SUBST(SGUTILS_LIBS) +AM_CONDITIONAL(HAVE_SGUTILS, test x"$have_sgutils" = xyes) + +dnl ************************************************** dnl * TagLib is only used by test-rebuild-db dnl ************************************************** PKG_CHECK_MODULES(TAGLIB, taglib, have_taglib=yes, have_taglib=no) @@ -200,6 +209,7 @@ docs/reference/version.xml m4/Makefile po/Makefile.in src/Makefile +tools/Makefile tests/Makefile libgpod-1.0.pc ]) diff --git a/tools/Makefile.am b/tools/Makefile.am new file mode 100644 index 0000000..bbd5159 --- /dev/null +++ b/tools/Makefile.am @@ -0,0 +1,9 @@ +if HAVE_SGUTILS + +bin_PROGRAMS=ipod-read-sysinfo-extended + +ipod_read_sysinfo_extended_SOURCES = read-sysinfoextended-sgutils.c +ipod_read_sysinfo_extended_CFLAGS=$(LIBGPOD_CFLAGS) $(SGUTILS_CFLAGS) -I$(top_srcdir)/src +ipod_read_sysinfo_extended_LDADD=$(LIBGPOD_LIBS) $(SGUTILS_LIBS) $(top_builddir)/src/libgpod.la + +endif
\ No newline at end of file diff --git a/tools/read-sysinfoextended-sgutils.c b/tools/read-sysinfoextended-sgutils.c new file mode 100644 index 0000000..268626f --- /dev/null +++ b/tools/read-sysinfoextended-sgutils.c @@ -0,0 +1,152 @@ +/* Copyright (c) 2007, Christophe Fergeau <teuf@gnome.org> + * + * 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! + * + */ +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <fcntl.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <scsi/sg_cmds.h> +#include <sys/stat.h> + +#include <glib.h> +#include <glib/gi18n.h> + +#include "itdb.h" + + +/* do_sg_inquiry and read_sysinfo_extended were heavily + * inspired from libipoddevice + */ +static unsigned char +do_sg_inquiry (int fd, int page, char *buf, char **start) +{ + const unsigned int IPOD_BUF_LENGTH = 252; + + if (sg_ll_inquiry (fd, 0, 1, page, buf, IPOD_BUF_LENGTH, 1, 0) != 0) { + *start = NULL; + return 0; + } else { + *start = buf + 4; + return (unsigned char)buf[3]; + } +} + +static char * +read_sysinfo_extended (const char *device) +{ + int fd; + const unsigned int IPOD_XML_PAGE = 0xc0; + unsigned char len; + char buf[512]; + char *start; + char *offsets; + GString *xml_sysinfo; + unsigned int i; + + fd = open (device, O_RDWR); + if (fd < 0) { + return NULL; + } + + len = do_sg_inquiry (fd, IPOD_XML_PAGE, buf, &start); + if (start == NULL || len == 0) { + close(fd); + return NULL; + } + + offsets = g_new (char, len+1); + memcpy(offsets, start, len); + offsets[len] = 0; + + xml_sysinfo = g_string_new_len (NULL, 512); + if (xml_sysinfo == NULL) { + g_free (offsets); + close (fd); + return NULL; + } + + for (i = 0; offsets[i]; i++) { + bzero(buf, 512); + len = do_sg_inquiry (fd, offsets[i], buf, &start); + start[len] = 0; + g_string_append (xml_sysinfo, start); + } + + g_free (offsets); + close (fd); + + return g_string_free (xml_sysinfo, FALSE); +} + +int +main (int argc, char **argv) +{ + char *xml; + + if (argc < 3) { + g_print (_("usage: %s <device> <mountpoint>\n"), g_basename (argv[0])); + exit (0); + } + + xml = read_sysinfo_extended (argv[1]); + if (xml == NULL) { + g_print (_("Couldn't read xml sysinfo from %s\n"), argv[1]); + return 1; + } else { + const char *mountpoint = argv[2]; + char *device_path; + char *filename; + const char *components[] = { "SysInfoExtended", NULL }; + gboolean success; + + device_path = itdb_get_device_dir (mountpoint); + if (device_path == NULL) { + g_free (xml); + g_print (_("Couldn't resolve Device directory path on %s"), + mountpoint); + return 1; + } + + filename = itdb_resolve_path (device_path, components); + g_free (device_path); + if (filename == NULL) { + g_print (_("Couldn't resolve SysInfoExtended path on %s"), + mountpoint); + g_free (xml); + return 1; + } + + success = g_file_set_contents (filename, xml, -1, NULL); + g_free (xml); + g_free (filename); + if (!success) { + g_print (_("Couldn't write SysInfoExtended to %s"), mountpoint); + return 1; + } + } + + return 0; +} |