diff options
author | teuf <teuf@f01d2545-417e-4e96-918e-98f8d0dbbcb6> | 2007-11-06 19:44:12 +0000 |
---|---|---|
committer | teuf <teuf@f01d2545-417e-4e96-918e-98f8d0dbbcb6> | 2007-11-06 19:44:12 +0000 |
commit | 70b8eba363bed3f3bdc3cc9332b6412011590296 (patch) | |
tree | 29077505b80812cf51abbed540c28c55e788825f | |
parent | 7d426e35e663e472641d8fed4ef114f1be5acfa4 (diff) | |
download | libgpod-70b8eba363bed3f3bdc3cc9332b6412011590296.tar.gz libgpod-70b8eba363bed3f3bdc3cc9332b6412011590296.tar.xz libgpod-70b8eba363bed3f3bdc3cc9332b6412011590296.zip |
* configure.ac:
* tools/20-libgpod-sysinfo-extended.fdi:
* tools/Makefile.am:
* tools/hal-callout.c:
* tools/ipod-scsi-inquiry.c:
* tools/read-sysinfoextended-sgutils.c: add hal callout which
automatically write SysinfoExtended to iPods when they are plugged
if it's properly installed
git-svn-id: https://gtkpod.svn.sf.net/svnroot/gtkpod/libgpod/trunk@1760 f01d2545-417e-4e96-918e-98f8d0dbbcb6
-rw-r--r-- | ChangeLog | 11 | ||||
-rw-r--r-- | configure.ac | 48 | ||||
-rw-r--r-- | tools/20-libgpod-sysinfo-extended.fdi | 14 | ||||
-rw-r--r-- | tools/Makefile.am | 24 | ||||
-rw-r--r-- | tools/hal-callout.c | 90 | ||||
-rw-r--r-- | tools/ipod-scsi-inquiry.c | 104 | ||||
-rw-r--r-- | tools/read-sysinfoextended-sgutils.c | 75 |
7 files changed, 291 insertions, 75 deletions
@@ -1,3 +1,14 @@ +2007-11-06 Christophe Fergeau <teuf@gnome.org> + + * configure.ac: + * tools/20-libgpod-sysinfo-extended.fdi: + * tools/Makefile.am: + * tools/hal-callout.c: + * tools/ipod-scsi-inquiry.c: + * tools/read-sysinfoextended-sgutils.c: add hal callout which + automatically write SysinfoExtended to iPods when they are plugged + if it's properly installed + 2007-11-06 Jorg Schuler <jcsjcs at users.sourceforge.net> * itdb_itunesdb.c (itdb_create_directories): Add support for diff --git a/configure.ac b/configure.ac index e4a12fe..cdcff65 100644 --- a/configure.ac +++ b/configure.ac @@ -59,6 +59,23 @@ PKG_CHECK_MODULES(LIBGPOD, glib-2.0 >= 2.8.0 gobject-2.0) LIBGPOD_CFLAGS="$LIBGPOD_CFLAGS -Wall" dnl ************************************************** +dnl * expand $libdir +dnl * by default, it looks like ${prefix}/lib +dnl * we want to expand prefix +dnl ************************************************** +expanded_libdir=`( + case $prefix in + NONE) prefix=$ac_default_prefix ;; + *) ;; + esac + case $exec_prefix in + NONE) exec_prefix=$prefix ;; + *) ;; + esac + eval echo $libdir +)` + +dnl ************************************************** dnl * sgutils is necessary to get the xml device file from the ipod dnl ************************************************** AC_CHECK_LIB(sgutils, sg_ll_inquiry, @@ -67,6 +84,37 @@ AC_CHECK_LIB(sgutils, sg_ll_inquiry, AC_SUBST(SGUTILS_LIBS) AM_CONDITIONAL(HAVE_SGUTILS, test x"$have_sgutils" = xyes) +dnl *********************************************************************** +dnl * HAL is optional, but is required if you want things to "just work" +dnl * when a recent iPod is plugged in +dnl * libgpod by itself doesn't use HAL at all, HAL is just used to build a +dnl * helper program which is then installed as a HAL callout +dnl *********************************************************************** +AC_ARG_WITH(hal, AC_HELP_STRING([--without-hal], + [Disable HAL support])) + +AC_ARG_WITH(hal_callouts_dir, AC_HELP_STRING([--with-hal-callouts-dir=DIR], + [Directory where HAL expects its callout scripts to be located]), , + with_hal_callouts_dir="${expanded_libdir}/hal") +HALCALLOUTSDIR="$with_hal_callouts_dir" +AC_SUBST(HALCALLOUTSDIR) + +if test "x$with_hal" != "xno"; then + PKG_CHECK_MODULES(HAL, hal >= 0.5 hal < 0.6, enable_hal=yes, enable_hal=no) + if test "x$enable_hal" != "xyes" -a "x$with_hal" = "xyes"; then + AC_MSG_ERROR([HAL support explicitly requested but HAL couldn't be found]) + fi + + if test "x$enable_hal" == "xyes"; then + AC_DEFINE(HAVE_HAL, 1, [Define if you have HAL support]) + AC_SUBST(HAL_CFLAGS) + AC_SUBST(HAL_LIBS) + fi +fi +AM_CONDITIONAL(HAVE_HAL, test x"$enable_hal" = xyes) + + + dnl ************************************************** dnl * TagLib is only used by test-rebuild-db dnl ************************************************** diff --git a/tools/20-libgpod-sysinfo-extended.fdi b/tools/20-libgpod-sysinfo-extended.fdi new file mode 100644 index 0000000..8776bf3 --- /dev/null +++ b/tools/20-libgpod-sysinfo-extended.fdi @@ -0,0 +1,14 @@ +<?xml version="1.0" encoding="UTF-8"?> <!-- -*- SGML -*- --> + +<deviceinfo version="0.2"> + <device> + <match key="@info.parent:storage.vendor" contains="Apple"> + <match key="@info.parent:storage.model" contains="iPod"> + <match key="volume.fsusage" contains="filesystem"> + <append key="info.callouts.add" type="strlist">libgpod-callout</append> + </match> + </match> + </match> + </device> +</deviceinfo> + diff --git a/tools/Makefile.am b/tools/Makefile.am index bbd5159..18c24bd 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -2,8 +2,28 @@ if HAVE_SGUTILS bin_PROGRAMS=ipod-read-sysinfo-extended -ipod_read_sysinfo_extended_SOURCES = read-sysinfoextended-sgutils.c +ipod_read_sysinfo_extended_SOURCES = \ + read-sysinfoextended-sgutils.c \ + ipod-scsi-inquiry.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 +if HAVE_HAL +haldir = $(HALCALLOUTSDIR) +hal_PROGRAMS = libgpod-callout + +libgpod_callout_SOURCES = \ + hal-callout.c \ + ipod-scsi-inquiry.c +libgpod_callout_CFLAGS=$(LIBGPOD_CFLAGS) $(SGUTILS_CFLAGS) -I$(top_srcdir)/src +libgpod_callout_LDADD=$(LIBGPOD_LIBS) $(SGUTILS_LIBS) $(top_builddir)/src/libgpod.la + +fdidir = $(datadir)/hal/fdi/policy/20thirdparty +fdi_DATA = 20-libgpod-sysinfo-extended.fdi + +EXTRA_DIST = $(fdi_DATA) + +endif + +endif + diff --git a/tools/hal-callout.c b/tools/hal-callout.c new file mode 100644 index 0000000..5a89a57 --- /dev/null +++ b/tools/hal-callout.c @@ -0,0 +1,90 @@ +#include <errno.h> +#include <glib.h> +#include <glib/gstdio.h> +#define __USE_BSD /* for mkdtemp */ +#include <stdlib.h> +#include <string.h> +#include <sys/mount.h> +#include <itdb.h> +#include <itdb_device.h> + +extern char *read_sysinfo_extended (const char *device); + +static char *mount_ipod (const char *dev_path) +{ + char *filename; + char *tmpname; + const char *fstype; + int result; + + fstype = g_getenv ("HAL_PROP_VOLUME_FSTYPE"); + if (fstype == NULL) { + return NULL; + } + filename = g_build_filename (G_DIR_SEPARATOR_S, "tmp", "ipodXXXXXX", + NULL); + if (filename == NULL) { + return NULL; + } + tmpname = mkdtemp (filename); + if (tmpname == NULL) { + g_free (filename); + return NULL; + } + g_assert (tmpname == filename); + result = mount (dev_path, tmpname, fstype, 0, NULL); + if (result != 0) { + g_rmdir (filename); + g_free (filename); + return NULL; + } + + return tmpname; +} + +static gboolean write_sysinfo_extended (const char *mountpoint, + const char *data) +{ + char *filename; + char *devdirpath; + gboolean result; + + devdirpath = itdb_get_device_dir (mountpoint); + if (devdirpath == NULL) { + return FALSE; + } + filename = itdb_get_path (devdirpath, "SysInfoExtended"); + g_free (devdirpath); + if (filename == NULL) { + return FALSE; + } + + result = g_file_set_contents (filename, data, -1, NULL); + g_free (filename); + + return result; +} + +int main (int argc, char **argv) +{ + char *ipod_mountpoint; + char *xml; + + xml = read_sysinfo_extended (g_getenv ("HAL_PROP_BLOCK_DEVICE")); + if (xml == NULL) { + return -1; + } + ipod_mountpoint = mount_ipod (g_getenv ("HAL_PROP_BLOCK_DEVICE")); + if (ipod_mountpoint == NULL) { + g_free (xml); + return -1; + } + write_sysinfo_extended (ipod_mountpoint, xml); + + umount (ipod_mountpoint); + g_rmdir (ipod_mountpoint); + g_free (ipod_mountpoint); + g_free (xml); + + return 0; +} diff --git a/tools/ipod-scsi-inquiry.c b/tools/ipod-scsi-inquiry.c new file mode 100644 index 0000000..6a0fbd3 --- /dev/null +++ b/tools/ipod-scsi-inquiry.c @@ -0,0 +1,104 @@ +/* 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 "itdb.h" + + +extern char *read_sysinfo_extended (const char *device); +/* 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]; + } +} + +G_GNUC_INTERNAL 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); +} + + diff --git a/tools/read-sysinfoextended-sgutils.c b/tools/read-sysinfoextended-sgutils.c index 76592fd..42a4665 100644 --- a/tools/read-sysinfoextended-sgutils.c +++ b/tools/read-sysinfoextended-sgutils.c @@ -23,83 +23,12 @@ #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); -} +extern char *read_sysinfo_extended (const char *device); int main (int argc, char **argv) @@ -108,7 +37,7 @@ main (int argc, char **argv) if (argc < 3) { g_print (_("usage: %s <device> <mountpoint>\n"), g_basename (argv[0])); - exit (0); + return 1; } xml = read_sysinfo_extended (argv[1]); |