[tracker] tracker-file-utils.c: dlopen("libblkid.so.1")

Only two functions are needed from libblkid:
- blkid_get_cache()
- blkid_get_tag_value()

dlopen() the library instead of linking directly to it, and define the
necessary structs and function prototypes here. This removes the need
for the libblkid-dev dependency at build time.

NOTE: libblkid.so.1 is *not* dlclose()'d. This shouldn't be a problem,
since Tracker uses it directly anyway.
This commit is contained in:
David Korth 2024-03-30 11:16:45 -04:00
parent 0393fab3dd
commit 7a1cc1399f
4 changed files with 68 additions and 11 deletions

3
debian/control vendored
View File

@ -33,8 +33,7 @@ Build-Depends:
gettext,
liblz4-dev,
liblzo2-dev,
libgsound-dev,
libblkid-dev
libgsound-dev
Standards-Version: 3.9.8
Homepage: https://github.com/GerbilSoft/rom-properties
Vcs-Git: https://github.com/GerbilSoft/rom-properties

View File

@ -12,7 +12,6 @@ packages:
* XFCE (GTK+ 3.x): libglib2.0-dev libgtk-3-dev libcairo2-dev libthunarx-3-dev libgsound-dev
* GNOME, MATE, Cinnamon: libglib2.0-dev libgtk-3-dev libcairo2-dev libnautilus-extension-dev libgsound-dev
* GNOME 43: libglib2.0-dev libgtk-4-dev libgdk-pixbuf2.0-dev libnautilus-extension-dev libgsound-dev
* GNOME Tracker: libblkid-dev
NOTE: On older versions of Ubuntu, some packages were different:
* Earlier than 18.04:

View File

@ -6,14 +6,13 @@ FIND_PACKAGE(GLib2 ${REQUIRE_XFCE} ${GLIB_MIN_VERSION})
FIND_PACKAGE(GObject2 ${REQUIRE_XFCE} ${GLIB_MIN_VERSION})
FIND_PACKAGE(GIO ${REQUIRE_XFCE} ${GLIB_MIN_VERSION})
FIND_PACKAGE(GIO-UNIX ${REQUIRE_XFCE} ${GLIB_MIN_VERSION})
FIND_PACKAGE(Blkid)
IF(GLib2_FOUND AND GObject2_FOUND AND GIO_FOUND AND GIO-UNIX_FOUND AND Blkid_FOUND)
IF(GLib2_FOUND AND GObject2_FOUND AND GIO_FOUND AND GIO-UNIX_FOUND)
# All required libraries were found.
ELSE(GLib2_FOUND AND GObject2_FOUND AND GIO_FOUND AND GIO-UNIX_FOUND AND Blkid_FOUND)
ELSE(GLib2_FOUND AND GObject2_FOUND AND GIO_FOUND AND GIO-UNIX_FOUND)
# A required library was not found.
# Disable the Tracker extractor.
SET(BUILD_TRACKER_EXTRACTOR OFF CACHE INTERNAL "Build the Tracker extractor module." FORCE)
ENDIF(GLib2_FOUND AND GObject2_FOUND AND GIO_FOUND AND GIO-UNIX_FOUND AND Blkid_FOUND)
ENDIF(GLib2_FOUND AND GObject2_FOUND AND GIO_FOUND AND GIO-UNIX_FOUND)
# Ensure we don't use functions not available in GLib 2.34.
ADD_DEFINITIONS(-DGLIB_VERSION_MIN_REQUIRED=GLIB_VERSION_2_34 -DGLIB_VERSION_MAX_ALLOWED=GLIB_VERSION_2_34)
@ -55,7 +54,6 @@ IF(BUILD_TRACKER_EXTRACTOR)
TARGET_LINK_LIBRARIES(${PROJECT_NAME} PRIVATE unixcommon rpsecure)
TARGET_LINK_LIBRARIES(${PROJECT_NAME} PRIVATE romdata)
TARGET_LINK_LIBRARIES(${PROJECT_NAME} PRIVATE GLib2::gio-unix GLib2::gio GLib2::gobject GLib2::glib)
TARGET_LINK_LIBRARIES(${PROJECT_NAME} PRIVATE Blkid::blkid)
# Link in libdl if it's required for dlopen().
IF(CMAKE_DL_LIBS)
TARGET_LINK_LIBRARIES(${PROJECT_NAME} PRIVATE ${CMAKE_DL_LIBS})

View File

@ -14,7 +14,7 @@
#include "tracker-file-utils.h"
#include <gio/gunixmounts.h>
#include <blkid.h>
//#include <blkid.h>
#ifdef HAVE_BTRFS_IOCTL
# include <linux/btrfs.h>
@ -23,6 +23,8 @@
#endif
// C includes
#include <dlfcn.h>
#include <errno.h>
#include <fcntl.h>
#include <string.h>
#include <unistd.h>
@ -31,6 +33,22 @@
// - g_autofree (2.44)
// - g_unix_mount_monitor_get() (2.44)
/** blkid/blkid.h **/
// dlopen() pointers for libblkid
// NOTE: Not dlclose()'d.
static void *libblkid_so = NULL;
typedef struct blkid_struct_cache *blkid_cache;
extern int blkid_get_cache(blkid_cache *cache, const char *filename);
extern char *blkid_get_tag_value(blkid_cache cache, const char *tagname, const char *devname);
static __typeof__(blkid_get_cache) *pfn_blkid_get_cache = NULL;
static __typeof__(blkid_get_tag_value) *pfn_blkid_get_tag_value = NULL;
/** Original libtracker-miners-common code starts here **/
typedef struct {
GFile *file;
gchar *mount_point;
@ -82,7 +100,7 @@ update_mounts (TrackerUnixMountCache *cache)
UnixMountInfo mount;
devname = g_unix_mount_get_device_path (entry);
id = blkid_get_tag_value (cache->id_cache, "UUID", devname);
id = pfn_blkid_get_tag_value (cache->id_cache, "UUID", devname);
if (!id && strchr (devname, G_DIR_SEPARATOR) != NULL)
id = g_strdup (devname);
@ -115,7 +133,7 @@ tracker_unix_mount_cache_get (void)
obj->mounts = g_array_new (FALSE, FALSE, sizeof (UnixMountInfo));
g_array_set_clear_func (obj->mounts, clear_mount_info);
blkid_get_cache (&obj->id_cache, NULL);
pfn_blkid_get_cache (&obj->id_cache, NULL);
/*g_signal_connect (obj->monitor, "mounts-changed",
G_CALLBACK (on_mounts_changed), obj);*/
@ -181,12 +199,55 @@ tracker_file_get_btrfs_subvolume_id (GFile *file)
}
#endif
/**
* Attempt to initialize libblkid.so.
* @return 0 on success; negative POSIX error code on error.
*/
static int
init_libblkid_so(void)
{
if (libblkid_so) {
// Already initialized.
return 0;
}
// Attempt to dlopen() libblkid.so.
// NOTE: Not dlclose()'d.
libblkid_so = dlopen("libblkid.so.1", RTLD_NOW | RTLD_LOCAL);
if (!libblkid_so) {
// Not found...
// TODO: Other error?
return -ENOENT;
}
// Attempt to dlsym() the required symbols.
pfn_blkid_get_cache = dlsym(libblkid_so, "blkid_get_cache");
pfn_blkid_get_tag_value = dlsym(libblkid_so, "blkid_get_tag_value");
if (!pfn_blkid_get_cache || !pfn_blkid_get_tag_value) {
// One (or both) symbols are missing?
dlclose(libblkid_so);
pfn_blkid_get_cache = NULL;
pfn_blkid_get_tag_value = NULL;
libblkid_so = NULL;
return -EIO;
}
// Symbols loaded.
return 0;
}
gchar *
tracker_file_get_content_identifier (GFile *file, GFileInfo *info, const gchar *suffix)
{
const gchar *id;
/*g_autofree*/ gchar *inode = NULL, *str = NULL, *subvolume = NULL;
// Make sure libblkid.so is initialized.
if (init_libblkid_so() != 0) {
// Cannot initialize libblkid.so.
return NULL;
}
if (info) {
g_object_ref (info);
} else {