[totem-pl-parser] Use libarchive to detect types of ISO files
- From: Bastien Nocera <hadess src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [totem-pl-parser] Use libarchive to detect types of ISO files
- Date: Sat, 2 Apr 2011 19:44:44 +0000 (UTC)
commit e57948ce6ef79af728e40722c8478122270b845e
Author: Bastien Nocera <hadess hadess net>
Date: Sat Apr 2 20:42:08 2011 +0100
Use libarchive to detect types of ISO files
Instead of using GVFS to mount the ISOs through libarchive,
as it was quite fiddly, and unreliable.
configure.in | 35 +++++++++++++
plparse/Makefile.am | 2 +
plparse/totem-disc.c | 130 +++++++++++++++++++++++---------------------------
totem-plparser.pc.in | 2 +-
4 files changed, 98 insertions(+), 71 deletions(-)
---
diff --git a/configure.in b/configure.in
index 556f364..c77302b 100644
--- a/configure.in
+++ b/configure.in
@@ -41,6 +41,7 @@ AC_PATH_PROG([GLIB_MKENUMS],[glib-mkenums])
GLIB_REQS=2.21.6
GIO_REQS=2.24.0
QUVI_REQS=0.2.15
+LIBARCHIVE_REQS=2.8.4
# Before making a release, the PLPARSER_LT_VERSION string should be modified.
# The string is of the form C:R:A.
@@ -101,6 +102,10 @@ else
**************************************************************"
fi
+##################################
+# Checking quvi dependency
+##################################
+
QUVI=""
AC_ARG_ENABLE(quvi,
AS_HELP_STRING([--enable-quvi],
@@ -122,6 +127,31 @@ if test "x$enable_quvi" != "xno" ; then
fi
AC_SUBST(QUVI, $QUVI)
+##################################
+# Checking libarchive dependency
+##################################
+
+ARCHIVE=""
+AC_ARG_ENABLE(libarchive,
+ AS_HELP_STRING([--enable-libarchive],
+ [Enable libarchive support (default is auto).]),
+ [],
+ [enable_libarchive=auto])
+if test "x$enable_libarchive" != "xno" ; then
+ PKG_CHECK_MODULES(ARCHIVE,
+ libarchive >= $LIBARCHIVE_REQS,
+ [have_libarchive=yes], [have_libarchive=no])
+ if test "x$enable_libarchive" = "xyes" -a "x$have_libarchive" = "xno" ; then
+ AC_MSG_ERROR([Libarchive support requested but not available.])
+ fi
+ if test "x$have_libarchive" = "xyes" ; then
+ pkg_modules="$pkg_modules libarchive"
+ ARCHIVE="libarchive"
+ AC_DEFINE(HAVE_LIBARCHIVE, 1, [libarchive available in the system])
+ fi
+fi
+AC_SUBST(ARCHIVE, $ARCHIVE)
+
dnl Check for packages for building libtotem-plparser.la
PKG_CHECK_MODULES(TOTEM_PLPARSER, [$pkg_modules])
AC_SUBST(TOTEM_PLPARSER_CFLAGS)
@@ -178,6 +208,11 @@ if test "x$have_quvi" = "xyes"; then
else
AC_MSG_NOTICE([ Quvi video link parsing disabled])
fi
+if test "x$have_libarchive" = "xyes"; then
+ AC_MSG_NOTICE([** ISO detection with libarchive enabled])
+else
+ AC_MSG_NOTICE([ ISO detection with libarchive disabled])
+fi
echo "
$gmime_message
diff --git a/plparse/Makefile.am b/plparse/Makefile.am
index 46fcf2b..4bbd4cf 100644
--- a/plparse/Makefile.am
+++ b/plparse/Makefile.am
@@ -72,6 +72,7 @@ libtotem_plparser_la_CPPFLAGS = \
libtotem_plparser_la_CFLAGS = \
$(TOTEM_PLPARSER_CFLAGS) \
+ $(ARCHIVE_CFLAGS) \
$(DBUS_CFLAGS) \
$(WARN_CFLAGS) \
$(AM_CFLAGS) \
@@ -82,6 +83,7 @@ libtotem_plparser_la_CFLAGS = \
libtotem_plparser_la_LIBADD = \
$(TOTEM_PLPARSER_LIBS) \
+ $(ARCHIVE_LIBS) \
$(top_builddir)/lib/libtotem_glibc.la
libtotem_plparser_la_LDFLAGS = \
diff --git a/plparse/totem-disc.c b/plparse/totem-disc.c
index 3dbad31..8709b41 100644
--- a/plparse/totem-disc.c
+++ b/plparse/totem-disc.c
@@ -58,6 +58,11 @@
#include <glib/gi18n.h>
#include <gio/gio.h>
+#ifdef HAVE_LIBARCHIVE
+#include <archive.h>
+#include <archive_entry.h>
+#endif /* HAVE_ARCHIVE */
+
#include "totem-disc.h"
#include "totem-pl-parser.h"
@@ -261,27 +266,57 @@ cd_cache_has_content_type (CdCache *cache, const char *content_type)
return FALSE;
}
-static char *
-cd_cache_uri_to_archive (const char *uri)
+static gboolean
+cd_cache_check_archive (CdCache *cache,
+ const char *filename,
+ GError **error)
{
- char *escaped, *escaped2, *retval;
-
- escaped = g_uri_escape_string (uri, NULL, FALSE);
- escaped2 = g_uri_escape_string (escaped, NULL, FALSE);
- g_free (escaped);
- retval = g_strdup_printf ("archive://%s/", escaped2);
- g_free (escaped2);
-
- return retval;
-}
+#ifndef HAVE_LIBARCHIVE
+ g_set_error (error, TOTEM_PL_PARSER_ERROR, TOTEM_PL_PARSER_ERROR_MOUNT_FAILED,
+ _("Failed to mount %s."), filename);
+ return FALSE;
+#else
+ struct archive *a;
+ struct archive_entry *entry;
+ char *content_types[] = { NULL, NULL };
+ int r;
+
+ a = archive_read_new();
+ archive_read_support_compression_all(a);
+ archive_read_support_format_all(a);
+ r = archive_read_open_filename(a, filename, 10240);
+ if (r != ARCHIVE_OK) {
+ g_set_error (error, TOTEM_PL_PARSER_ERROR, TOTEM_PL_PARSER_ERROR_MOUNT_FAILED,
+ _("Failed to mount %s."), filename);
+ return FALSE;
+ }
+ while (archive_read_next_header(a, &entry) == ARCHIVE_OK) {
+ const char *name;
-static void
-cd_cache_mount_archive_callback (GObject *source_object,
- GAsyncResult *res,
- CdCacheCallbackData *data)
-{
- data->result = g_file_mount_enclosing_volume_finish (G_FILE (source_object), res, &data->error);
- data->called = TRUE;
+ name = archive_entry_pathname (entry);
+ if (g_ascii_strcasecmp (name, "VIDEO_TS/VIDEO_TS.IFO") == 0) {
+ content_types[0] = "x-content/video-dvd";
+ cache->content_types = g_strdupv (content_types);
+ break;
+ } else if (g_ascii_strcasecmp (name, "mpegav/AVSEQ01.DAT") == 0) {
+ content_types[0] = "x-content/video-vcd";
+ cache->content_types = g_strdupv (content_types);
+ break;
+ } else if (g_ascii_strcasecmp (name, "MPEG2/AVSEQ01.MPG") == 0) {
+ content_types[0] = "x-content/video-svcd";
+ cache->content_types = g_strdupv (content_types);
+ break;
+ }
+ archive_read_data_skip(a);
+ }
+ r = archive_read_finish(a);
+ if (r != ARCHIVE_OK) {
+ g_set_error (error, TOTEM_PL_PARSER_ERROR, TOTEM_PL_PARSER_ERROR_MOUNT_FAILED,
+ _("Failed to mount %s."), filename);
+ return FALSE;
+ }
+ return TRUE;
+#endif
}
static CdCache *
@@ -320,59 +355,20 @@ cd_cache_new (const char *dev,
return cache;
} else if (g_file_test (local, G_FILE_TEST_IS_REGULAR)) {
- GMount *mount;
- GError *err = NULL;
- char *uri, *archive_path;
-
cache = g_new0 (CdCache, 1);
cache->is_iso = TRUE;
cache->is_media = FALSE;
- uri = g_file_get_uri (file);
g_object_unref (file);
- archive_path = cd_cache_uri_to_archive (uri);
- g_free (uri);
- cache->device = local;
- cache->iso_file = g_file_new_for_uri (archive_path);
- g_free (archive_path);
-
- mount = g_file_find_enclosing_mount (cache->iso_file, NULL, &err);
- if (mount == NULL && g_error_matches (err, G_IO_ERROR, G_IO_ERROR_NOT_MOUNTED)) {
- CdCacheCallbackData data;
-
- memset (&data, 0, sizeof(data));
- data.cache = cache;
- g_file_mount_enclosing_volume (cache->iso_file,
- G_MOUNT_MOUNT_NONE,
- NULL,
- NULL,
- (GAsyncReadyCallback) cd_cache_mount_archive_callback,
- &data);
- while (!data.called) g_main_context_iteration (NULL, TRUE);
-
- if (!data.result) {
- if (data.error) {
- g_propagate_error (error, data.error);
- } else {
- g_set_error (error, TOTEM_PL_PARSER_ERROR, TOTEM_PL_PARSER_ERROR_MOUNT_FAILED,
- _("Failed to mount %s."), cache->device);
- }
- cd_cache_free (cache);
- return FALSE;
- }
- self_mounted = TRUE;
- } else if (mount == NULL) {
+ if (cd_cache_check_archive (cache, local, error) == FALSE) {
cd_cache_free (cache);
return FALSE;
- } else {
- g_object_unref (mount);
}
- cache->content_types = g_content_type_guess_for_tree (cache->iso_file);
- cache->mountpoint = g_file_get_path (cache->iso_file);
- cache->self_mounted = self_mounted;
- cache->mounted = TRUE;
+ cache->device = local;
+ cache->self_mounted = FALSE;
+ cache->mounted = FALSE;
return cache;
}
@@ -468,7 +464,7 @@ cd_cache_open_mountpoint (CdCache *cache,
GFile *root;
/* already opened? */
- if (cache->mounted || cache->is_media == FALSE)
+ if (cache->mounted || cache->is_media == FALSE || cache->is_iso)
return TRUE;
/* check for mounting - assume we'll mount ourselves */
@@ -569,12 +565,10 @@ cd_cache_disc_is_cdda (CdCache *cache,
GError **error)
{
/* We can't have audio CDs on disc, yet */
- if (cache->is_media == FALSE) {
+ if (cache->is_media == FALSE)
return MEDIA_TYPE_DATA;
- }
if (!cd_cache_open_device (cache, error))
return MEDIA_TYPE_ERROR;
-
if (cd_cache_has_content_type (cache, "x-content/audio-cdda") != FALSE)
return MEDIA_TYPE_CDDA;
@@ -590,8 +584,6 @@ cd_cache_disc_is_vcd (CdCache *cache,
return MEDIA_TYPE_ERROR;
if (!cd_cache_open_mountpoint (cache, error))
return MEDIA_TYPE_ERROR;
- if (!cache->mountpoint)
- return MEDIA_TYPE_ERROR;
if (cd_cache_has_content_type (cache, "x-content/video-vcd") != FALSE)
return MEDIA_TYPE_VCD;
@@ -610,8 +602,6 @@ cd_cache_disc_is_dvd (CdCache *cache,
return MEDIA_TYPE_ERROR;
if (!cd_cache_open_mountpoint (cache, error))
return MEDIA_TYPE_ERROR;
- if (!cache->mountpoint)
- return MEDIA_TYPE_ERROR;
if (cd_cache_has_content_type (cache, "x-content/video-dvd") != FALSE)
return MEDIA_TYPE_DVD;
diff --git a/totem-plparser.pc.in b/totem-plparser.pc.in
index bfec510..f789063 100644
--- a/totem-plparser.pc.in
+++ b/totem-plparser.pc.in
@@ -9,7 +9,7 @@ Name: totem-plparser
Description: Totem Playlist Parser library
Version: @VERSION@
Requires: glib-2.0 gobject-2.0 gio-2.0
-Requires.private: gthread-2.0 libxml-2.0 @GMIME@ @QUVI@
+Requires.private: gthread-2.0 libxml-2.0 @GMIME@ @QUVI@ @ARCHIVE@
Libs: -L${libdir} -ltotem-plparser
Cflags: -I${includedir}/totem-pl-parser/1/plparser
uselibcamel= USEGMIME@
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]