summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristophe Fergeau <teuf@gnome.org>2007-11-06 19:44:12 +0000
committerChristophe Fergeau <teuf@gnome.org>2007-11-06 19:44:12 +0000
commitff2ab777950a4b2bc8ce1719c0a73114a5445ceb (patch)
tree29077505b80812cf51abbed540c28c55e788825f
parentecae67fbdfacd08e474298447ce978f4318c5e0d (diff)
downloadlibgpod-ff2ab777950a4b2bc8ce1719c0a73114a5445ceb.tar.gz
libgpod-ff2ab777950a4b2bc8ce1719c0a73114a5445ceb.tar.xz
libgpod-ff2ab777950a4b2bc8ce1719c0a73114a5445ceb.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--ChangeLog11
-rw-r--r--configure.ac48
-rw-r--r--tools/20-libgpod-sysinfo-extended.fdi14
-rw-r--r--tools/Makefile.am24
-rw-r--r--tools/hal-callout.c90
-rw-r--r--tools/ipod-scsi-inquiry.c104
-rw-r--r--tools/read-sysinfoextended-sgutils.c75
7 files changed, 291 insertions, 75 deletions
diff --git a/ChangeLog b/ChangeLog
index 60917fa..2e07911 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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]);