summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCedric BAIL <cedric.bail@samsung.com>2013-02-19 13:33:41 +0900
committerCedric BAIL <cedric.bail@samsung.com>2013-02-21 17:19:35 +0900
commitfe21e281a73bbd94336215b0f20896ff258c686d (patch)
treecad3dca92599ada7a69011b2ba576330020accd0
parent83190eb0c2bcf9fdff52992164789d4daed4ee25 (diff)
downloadefl-fe21e281a73bbd94336215b0f20896ff258c686d.tar.gz
eeze: add back support for older system.
Support for older system that don't come with libmount or have an older libmount. This is a backport from Eeze 1.7 tree. There is no code change there.
-rw-r--r--configure.ac30
-rw-r--r--src/Makefile_Eeze.am11
-rw-r--r--src/lib/eeze/eeze_disk_libmount.c495
-rw-r--r--src/lib/eeze/eeze_disk_libmount_new.c4
-rw-r--r--src/lib/eeze/eeze_disk_libmount_old.c401
5 files changed, 938 insertions, 3 deletions
diff --git a/configure.ac b/configure.ac
index 31308a2b36..29301b88c9 100644
--- a/configure.ac
+++ b/configure.ac
@@ -3113,7 +3113,35 @@ EFL_INTERNAL_DEPEND_PKG([EEZE], [ecore-con])
EFL_INTERNAL_DEPEND_PKG([EEZE], [eet])
EFL_DEPEND_PKG([EEZE], [UDEV], [libudev >= 148])
-EFL_DEPEND_PKG([EEZE], [EEZE_MOUNT], [mount >= 2.20.0])
+
+AC_ARG_ENABLE([libmount],
+ [AC_HELP_STRING([--disable-libmount],
+ [disable libmount support. @<:@default=enabled@:>@])],
+ [
+ if test "x${enableval}" = "xyes" ; then
+ want_libmount="yes"
+ else
+ want_libmount="no"
+ fi
+ ],
+ [want_libmount="yes"])
+
+EFL_OPTIONAL_DEPEND_PKG([EEZE], [${want_libmount}],
+ [EEZE_MOUNT], [mount >= 2.18.0])
+EFL_ADD_FEATURE([EEZE], [libmount], [${have_eeze_mount}])
+
+PKG_CHECK_EXISTS([mount > 2.19.0],
+ [have_libmount_new="yes"],
+ [have_libmount_new="no"])
+AC_MSG_CHECKING([Use new libmount API (older that 2.19.0)])
+AC_MSG_RESULT([${have_libmount_new}])
+
+AM_CONDITIONAL([EEZE_LIBMOUNT_NEW], [test "x${have_libmount_new}" = "xyes"])
+if test "x${have_libmount_new}" = "xno"; then
+ AC_DEFINE_UNQUOTED([OLD_LIBMOUNT], [1], [using first version of libmount])
+fi
+
+AM_CONDITIONAL([EEZE_NOLIBMOUNT], [test "x${have_eeze_mount}" = "xno"])
## modules
if test "${want_tizen}" = "yes"; then
diff --git a/src/Makefile_Eeze.am b/src/Makefile_Eeze.am
index f50ad88604..48080877f2 100644
--- a/src/Makefile_Eeze.am
+++ b/src/Makefile_Eeze.am
@@ -15,7 +15,6 @@ lib/eeze/Eeze_Disk.h
# libeeze.la
lib_eeze_libeeze_la_SOURCES = \
lib/eeze/eeze_disk.c \
-lib/eeze/eeze_disk_libmount_new.c \
lib/eeze/eeze_disk_mount.c \
lib/eeze/eeze_disk_private.h \
lib/eeze/eeze_disk_udev.c \
@@ -31,6 +30,16 @@ lib/eeze/eeze_udev_syspath.c \
lib/eeze/eeze_udev_walk.c \
lib/eeze/eeze_udev_watch.c
+if EEZE_NOLIBMOUNT
+lib_eeze_libeeze_la_SOURCES += lib/eeze/eeze_disk_libmount.c
+else
+if EEZE_LIBMOUNT_NEW
+lib_eeze_libeeze_la_SOURCES += lib/eeze/eeze_disk_libmount_new.c
+else
+lib_eeze_libeeze_la_SOURCES += lib/eeze/eeze_disk_libmount_old.c
+endif
+endif
+
lib_eeze_libeeze_la_CPPFLAGS = \
-DPACKAGE_BIN_DIR=\"$(bindir)\" \
-DPACKAGE_LIB_DIR=\"$(libdir)\" \
diff --git a/src/lib/eeze/eeze_disk_libmount.c b/src/lib/eeze/eeze_disk_libmount.c
new file mode 100644
index 0000000000..885f313cc0
--- /dev/null
+++ b/src/lib/eeze/eeze_disk_libmount.c
@@ -0,0 +1,495 @@
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#ifndef USE_UNSTABLE_LIBMOUNT_API
+# define USE_UNSTABLE_LIBMOUNT_API 1
+#endif
+
+#include <Ecore.h>
+#include <Eeze.h>
+#include <Eeze_Disk.h>
+#include <libmount.h>
+#include <unistd.h>
+
+#include "eeze_udev_private.h"
+#include "eeze_disk_private.h"
+
+/*
+ *
+ * PRIVATE
+ *
+ */
+
+static struct libmnt_optmap eeze_optmap[] =
+{
+ { "loop[=]", EEZE_DISK_MOUNTOPT_LOOP, 0 },
+ { "utf8", EEZE_DISK_MOUNTOPT_UTF8, 0 },
+ { "noexec", EEZE_DISK_MOUNTOPT_NOEXEC, 0 },
+ { "nosuid", EEZE_DISK_MOUNTOPT_NOSUID, 0 },
+ { "remount", EEZE_DISK_MOUNTOPT_REMOUNT, 0 },
+ { "uid[=]", EEZE_DISK_MOUNTOPT_UID, 0 },
+ { "nodev", EEZE_DISK_MOUNTOPT_NODEV, 0 },
+ { NULL, 0, 0 }
+};
+typedef struct libmnt_table libmnt_table;
+typedef struct libmnt_lock libmnt_lock;
+typedef struct libmnt_fs libmnt_fs;
+typedef struct libmnt_cache libmnt_cache;
+static Ecore_File_Monitor *_mtab_mon = NULL;
+static Ecore_File_Monitor *_fstab_mon = NULL;
+static Eina_Bool _watching = EINA_FALSE;
+static Eina_Bool _mtab_scan_active = EINA_FALSE;
+static Eina_Bool _mtab_locked = EINA_FALSE;
+static Eina_Bool _fstab_scan_active = EINA_FALSE;
+static libmnt_cache *_eeze_mount_mtab_cache = NULL;
+static libmnt_cache *_eeze_mount_fstab_cache = NULL;
+static libmnt_table *_eeze_mount_mtab = NULL;
+static libmnt_table *_eeze_mount_fstab = NULL;
+static libmnt_lock *_eeze_mtab_lock = NULL;
+extern Eina_List *_eeze_disks;
+
+static libmnt_table *_eeze_mount_tab_parse(const char *filename);
+static void _eeze_mount_tab_watcher(void *data, Ecore_File_Monitor *mon __UNUSED__, Ecore_File_Event event __UNUSED__, const char *path);
+
+static Eina_Bool
+_eeze_mount_lock_mtab(void)
+{
+// DBG("Locking mlock: %s", mnt_lock_get_linkfile(_eeze_mtab_lock));
+ if (EINA_LIKELY(access("/etc/mtab", W_OK)))
+ {
+ INF("Insufficient privs for mtab lock, continuing without lock");
+ return EINA_TRUE;
+ }
+ if (mnt_lock_file(_eeze_mtab_lock))
+ {
+ ERR("Couldn't lock mtab!");
+ return EINA_FALSE;
+ }
+ _mtab_locked = EINA_TRUE;
+ return EINA_TRUE;
+}
+
+static void
+_eeze_mount_unlock_mtab(void)
+{
+// DBG("Unlocking mlock: %s", mnt_lock_get_linkfile(_eeze_mtab_lock));
+ if (_mtab_locked) mnt_unlock_file(_eeze_mtab_lock);
+ _mtab_locked = EINA_FALSE;
+}
+
+
+static int
+_eeze_mount_tab_parse_errcb(libmnt_table *tab __UNUSED__, const char *filename, int line)
+{
+ ERR("%s:%d: could not parse line!", filename, line); /* most worthless error reporting ever. */
+ return -1;
+}
+
+/*
+ * I could use mnt_new_table_from_file() but this way gives much more detailed output
+ * on failure so why not
+ */
+static libmnt_table *
+_eeze_mount_tab_parse(const char *filename)
+{
+ libmnt_table *tab;
+
+ if (!(tab = mnt_new_table())) return NULL;
+ if (mnt_table_set_parser_errcb(tab, _eeze_mount_tab_parse_errcb))
+ {
+ ERR("Alloc!");
+ mnt_free_table(tab);
+ return NULL;
+ }
+
+ if (!mnt_table_parse_file(tab, filename))
+ return tab;
+
+ mnt_free_table(tab);
+ return NULL;
+}
+
+static void
+_eeze_mount_tab_watcher(void *data, Ecore_File_Monitor *mon __UNUSED__, Ecore_File_Event event __UNUSED__, const char *path)
+{
+ libmnt_table *bak;
+
+ if (
+ ((_mtab_scan_active) && (data)) || /* mtab has non-null data to avoid needing strcmp */
+ ((_fstab_scan_active) && (!data))
+ )
+ /* prevent scans from triggering a scan */
+ return;
+
+ bak = _eeze_mount_mtab;
+ if (data)
+ if (!_eeze_mount_lock_mtab())
+ { /* FIXME: maybe queue job here? */
+ ERR("Losing events...");
+ return;
+ }
+ _eeze_mount_mtab = _eeze_mount_tab_parse(path);
+ if (data)
+ _eeze_mount_unlock_mtab();
+ if (!_eeze_mount_mtab)
+ {
+ ERR("Could not parse %s! keeping old tab...", path);
+ goto error;
+ }
+ if (data)
+ {
+ Eina_List *l;
+ Eeze_Disk *disk;
+
+ /* catch externally initiated mounts on existing disks by comparing known mount state to current state */
+ EINA_LIST_FOREACH(_eeze_disks, l, disk)
+ {
+ Eina_Bool mounted;
+
+ mounted = disk->mounted;
+
+ if ((eeze_disk_libmount_mounted_get(disk) != mounted) && (!disk->mount_status))
+ {
+ if (!mounted)
+ {
+ Eeze_Event_Disk_Mount *e;
+ e = malloc(sizeof(Eeze_Event_Disk_Mount));
+ if (e)
+ {
+ e->disk = disk;
+ ecore_event_add(EEZE_EVENT_DISK_MOUNT, e, NULL, NULL);
+ }
+ }
+ else
+ {
+ Eeze_Event_Disk_Unmount *e;
+ e = malloc(sizeof(Eeze_Event_Disk_Unmount));
+ if (e)
+ {
+ e->disk = disk;
+ ecore_event_add(EEZE_EVENT_DISK_UNMOUNT, e, NULL, NULL);
+ }
+ }
+ }
+ }
+ }
+
+ mnt_free_table(bak);
+ if (data)
+ {
+ mnt_free_cache(_eeze_mount_mtab_cache);
+ _eeze_mount_mtab_cache = mnt_new_cache();
+ mnt_table_set_cache(_eeze_mount_mtab, _eeze_mount_mtab_cache);
+ }
+ else
+ {
+ mnt_free_cache(_eeze_mount_fstab_cache);
+ _eeze_mount_fstab_cache = mnt_new_cache();
+ mnt_table_set_cache(_eeze_mount_fstab, _eeze_mount_fstab_cache);
+ }
+ return;
+
+error:
+ mnt_free_table(_eeze_mount_mtab);
+ _eeze_mount_mtab = bak;
+}
+
+/*
+ *
+ * INVISIBLE
+ *
+ */
+
+Eina_Bool
+eeze_libmount_init(void)
+{
+ if (_eeze_mtab_lock)
+ return EINA_TRUE;
+ if (!(_eeze_mtab_lock = mnt_new_lock("/etc/mtab", 0)))
+ return EINA_FALSE;
+ return EINA_TRUE;
+}
+
+void
+eeze_libmount_shutdown(void)
+{
+ if (_eeze_mount_fstab)
+ {
+ mnt_free_table(_eeze_mount_fstab);
+ mnt_free_cache(_eeze_mount_fstab_cache);
+ }
+ if (_eeze_mount_mtab)
+ {
+ mnt_free_table(_eeze_mount_mtab);
+ mnt_free_cache(_eeze_mount_mtab_cache);
+ }
+ eeze_mount_tabs_unwatch();
+ if (!_eeze_mtab_lock)
+ return;
+
+ mnt_unlock_file(_eeze_mtab_lock);
+ mnt_free_lock(_eeze_mtab_lock);
+ _eeze_mtab_lock = NULL;
+}
+
+unsigned long
+eeze_disk_libmount_opts_get(Eeze_Disk *disk)
+{
+ libmnt_fs *mnt;
+ const char *opts;
+ unsigned long f = 0;
+
+ if (!eeze_mount_mtab_scan() || !eeze_mount_fstab_scan())
+ return 0;
+
+ mnt = mnt_table_find_tag(_eeze_mount_mtab, "UUID", eeze_disk_uuid_get(disk), MNT_ITER_BACKWARD);
+ if (!mnt)
+ mnt = mnt_table_find_tag(_eeze_mount_fstab, "UUID", eeze_disk_uuid_get(disk), MNT_ITER_BACKWARD);
+
+ if (!mnt) return 0;
+
+ opts = mnt_fs_get_fs_options(mnt);
+ if (!opts) return 0;
+ if (!mnt_optstr_get_flags(opts, &f, eeze_optmap)) return 0;
+ return f;
+}
+
+/*
+ * helper function to return whether a disk is mounted
+ */
+Eina_Bool
+eeze_disk_libmount_mounted_get(Eeze_Disk *disk)
+{
+ libmnt_fs *mnt;
+
+ if (!disk)
+ return EINA_FALSE;
+
+ if (!eeze_mount_mtab_scan() || !eeze_mount_fstab_scan())
+ return EINA_FALSE;
+
+ mnt = mnt_table_find_srcpath(_eeze_mount_mtab, eeze_disk_devpath_get(disk), MNT_ITER_BACKWARD);
+ if (!mnt)
+ {
+ disk->mounted = EINA_FALSE;
+ return EINA_FALSE;
+ }
+
+ eina_stringshare_replace(&disk->mount_point, mnt_fs_get_target(mnt));
+ disk->mounted = EINA_TRUE;
+ return EINA_TRUE;
+}
+
+
+/*
+ * helper function to return the device that is mounted at a mount point
+ */
+const char *
+eeze_disk_libmount_mp_find_source(const char *mount_point)
+{
+ libmnt_fs *mnt;
+
+ if (!mount_point)
+ return NULL;
+
+ if (!eeze_mount_mtab_scan() || !eeze_mount_fstab_scan())
+ return NULL;
+
+ mnt = mnt_table_find_target(_eeze_mount_mtab, mount_point, MNT_ITER_BACKWARD);
+ if (!mnt)
+ mnt = mnt_table_find_target(_eeze_mount_fstab, mount_point, MNT_ITER_BACKWARD);
+
+ if (!mnt)
+ return NULL;
+
+ return mnt_fs_get_source(mnt);
+}
+
+/*
+ * helper function to return a mount point from a uuid
+ */
+const char *
+eeze_disk_libmount_mp_lookup_by_uuid(const char *uuid)
+{
+ libmnt_fs *mnt;
+
+ if (!uuid)
+ return NULL;
+
+ if (!eeze_mount_mtab_scan() || !eeze_mount_fstab_scan())
+ return NULL;
+
+ mnt = mnt_table_find_tag(_eeze_mount_fstab, "UUID", uuid, MNT_ITER_BACKWARD);
+
+ if (!mnt)
+ return NULL;
+
+ return mnt_fs_get_target(mnt);
+}
+
+/*
+ * helper function to return a mount point from a label
+ */
+const char *
+eeze_disk_libmount_mp_lookup_by_label(const char *label)
+{
+ libmnt_fs *mnt;
+
+ if (!label)
+ return NULL;
+
+ if (!eeze_mount_mtab_scan() || !eeze_mount_fstab_scan())
+ return NULL;
+
+ mnt = mnt_table_find_tag(_eeze_mount_fstab, "LABEL", label, MNT_ITER_BACKWARD);
+
+ if (!mnt)
+ return NULL;
+
+ return mnt_fs_get_target(mnt);
+}
+
+/*
+ * helper function to return a mount point from a /dev/ path
+ */
+const char *
+eeze_disk_libmount_mp_lookup_by_devpath(const char *devpath)
+{
+ libmnt_fs *mnt;
+
+ if (!devpath)
+ return NULL;
+
+ if (!eeze_mount_mtab_scan() || !eeze_mount_fstab_scan())
+ return NULL;
+
+ mnt = mnt_table_find_srcpath(_eeze_mount_mtab, devpath, MNT_ITER_BACKWARD);
+ if (!mnt)
+ mnt = mnt_table_find_srcpath(_eeze_mount_fstab, devpath, MNT_ITER_BACKWARD);
+
+ if (!mnt)
+ return NULL;
+
+ return mnt_fs_get_target(mnt);
+}
+
+/*
+ *
+ * API
+ *
+ */
+
+EAPI Eina_Bool
+eeze_mount_tabs_watch(void)
+{
+ libmnt_table *bak;
+
+ if (_watching)
+ return EINA_TRUE;
+
+ if (!_eeze_mount_lock_mtab())
+ return EINA_FALSE;
+
+ bak = _eeze_mount_tab_parse("/etc/mtab");
+ _eeze_mount_unlock_mtab();
+ if (!bak)
+ goto error;
+
+ mnt_free_table(_eeze_mount_mtab);
+ _eeze_mount_mtab = bak;
+ if (!(bak = _eeze_mount_tab_parse("/etc/fstab")))
+ goto error;
+
+ mnt_free_table(_eeze_mount_fstab);
+ _eeze_mount_fstab = bak;
+
+ _eeze_mount_mtab_cache = mnt_new_cache();
+ mnt_table_set_cache(_eeze_mount_mtab, _eeze_mount_mtab_cache);
+
+ _eeze_mount_fstab_cache = mnt_new_cache();
+ mnt_table_set_cache(_eeze_mount_fstab, _eeze_mount_fstab_cache);
+
+ _mtab_mon = ecore_file_monitor_add("/etc/mtab", _eeze_mount_tab_watcher, (void*)1);
+ _fstab_mon = ecore_file_monitor_add("/etc/fstab", _eeze_mount_tab_watcher, NULL);
+ _watching = EINA_TRUE;
+
+ return EINA_TRUE;
+
+error:
+ if (!_eeze_mount_mtab)
+ ERR("Could not parse /etc/mtab!");
+ else
+ {
+ ERR("Could not parse /etc/fstab!");
+ mnt_free_table(_eeze_mount_mtab);
+ }
+ return EINA_FALSE;
+}
+
+EAPI void
+eeze_mount_tabs_unwatch(void)
+{
+ if (!_watching)
+ return;
+
+ ecore_file_monitor_del(_mtab_mon);
+ _mtab_mon = NULL;
+ ecore_file_monitor_del(_fstab_mon);
+ _fstab_mon = NULL;
+ _watching = EINA_FALSE;
+}
+
+EAPI Eina_Bool
+eeze_mount_mtab_scan(void)
+{
+ libmnt_table *bak;
+
+ if (_watching)
+ return EINA_TRUE;
+
+ if (!_eeze_mount_lock_mtab())
+ return EINA_FALSE;
+ bak = _eeze_mount_tab_parse("/etc/mtab");
+ _eeze_mount_unlock_mtab();
+ if (!bak)
+ goto error;
+ if (_eeze_mount_mtab)
+ {
+ mnt_free_table(_eeze_mount_mtab);
+ mnt_free_cache(_eeze_mount_mtab_cache);
+ }
+ _eeze_mount_mtab = bak;
+ _eeze_mount_mtab_cache = mnt_new_cache();
+ mnt_table_set_cache(_eeze_mount_mtab, _eeze_mount_mtab_cache);
+
+ return EINA_TRUE;
+
+error:
+ return EINA_FALSE;
+}
+
+EAPI Eina_Bool
+eeze_mount_fstab_scan(void)
+{
+ libmnt_table *bak;
+ if (_watching)
+ return EINA_TRUE;
+
+ bak = _eeze_mount_tab_parse("/etc/fstab");
+ if (!bak)
+ goto error;
+ if (_eeze_mount_fstab)
+ {
+ mnt_free_table(_eeze_mount_fstab);
+ mnt_free_cache(_eeze_mount_fstab_cache);
+ }
+ _eeze_mount_fstab = bak;
+ _eeze_mount_fstab_cache = mnt_new_cache();
+ mnt_table_set_cache(_eeze_mount_fstab, _eeze_mount_fstab_cache);
+
+ return EINA_TRUE;
+
+error:
+ return EINA_FALSE;
+}
diff --git a/src/lib/eeze/eeze_disk_libmount_new.c b/src/lib/eeze/eeze_disk_libmount_new.c
index aaae525b68..f7fd17d0af 100644
--- a/src/lib/eeze/eeze_disk_libmount_new.c
+++ b/src/lib/eeze/eeze_disk_libmount_new.c
@@ -14,7 +14,9 @@
#include <Ecore.h>
#include <Eeze.h>
#include <Eeze_Disk.h>
-#include <libmount.h>
+#ifdef HAVE_EEZE_MOUNT
+# include <libmount.h>
+#endif
#include "eeze_udev_private.h"
#include "eeze_disk_private.h"
diff --git a/src/lib/eeze/eeze_disk_libmount_old.c b/src/lib/eeze/eeze_disk_libmount_old.c
new file mode 100644
index 0000000000..20df62e23c
--- /dev/null
+++ b/src/lib/eeze/eeze_disk_libmount_old.c
@@ -0,0 +1,401 @@
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#ifndef USE_UNSTABLE_LIBMOUNT_API
+# define USE_UNSTABLE_LIBMOUNT_API 1
+#endif
+
+#include <Ecore.h>
+#include <Eeze.h>
+#include <Eeze_Disk.h>
+#include <mount/mount.h>
+
+#include "eeze_udev_private.h"
+#include "eeze_disk_private.h"
+/*
+ *
+ * PRIVATE
+ *
+ */
+static Ecore_File_Monitor *_mtab_mon = NULL;
+static Ecore_File_Monitor *_fstab_mon = NULL;
+static Eina_Bool _watching = EINA_FALSE;
+static Eina_Bool _mtab_scan_active = EINA_FALSE;
+static Eina_Bool _fstab_scan_active = EINA_FALSE;
+static mnt_tab *_eeze_mount_mtab = NULL;
+static mnt_tab *_eeze_mount_fstab = NULL;
+static mnt_lock *_eeze_mtab_lock = NULL;
+extern Eina_List *_eeze_disks;
+
+static mnt_tab *_eeze_mount_tab_parse(const char *filename);
+static void _eeze_mount_tab_watcher(void *data, Ecore_File_Monitor *mon __UNUSED__, Ecore_File_Event event __UNUSED__, const char *path);
+
+static Eina_Bool
+_eeze_mount_lock_mtab(void)
+{
+ DBG("Locking mlock: %s", mnt_lock_get_linkfile(_eeze_mtab_lock));
+#if 0
+#warning this code is broken with current libmount!
+ if (mnt_lock_file(_eeze_mtab_lock))
+ {
+ ERR("Couldn't lock mtab!");
+ return EINA_FALSE;
+ }
+#endif
+ return EINA_TRUE;
+}
+
+static void
+_eeze_mount_unlock_mtab(void)
+{
+ DBG("Unlocking mlock: %s", mnt_lock_get_linkfile(_eeze_mtab_lock));
+ mnt_unlock_file(_eeze_mtab_lock);
+}
+
+/*
+ * I could use mnt_new_tab_from_file() but this way gives much more detailed output
+ * on failure so why not
+ */
+static mnt_tab *
+_eeze_mount_tab_parse(const char *filename)
+{
+ mnt_tab *tab;
+
+ if (!(tab = mnt_new_tab(filename)))
+ return NULL;
+ if (!mnt_tab_parse_file(tab))
+ return tab;
+
+ if (mnt_tab_get_nerrs(tab))
+ { /* parse error */
+ char buf[1024];
+
+ mnt_tab_strerror(tab, buf, sizeof(buf));
+ ERR("%s", buf);
+ }
+ else
+ /* system error */
+ ERR("%s", mnt_tab_get_name(tab));
+ mnt_free_tab(tab);
+ return NULL;
+}
+
+static void
+_eeze_mount_tab_watcher(void *data, Ecore_File_Monitor *mon __UNUSED__, Ecore_File_Event event __UNUSED__, const char *path)
+{
+ mnt_tab *bak;
+
+ if (
+ ((_mtab_scan_active) && (data)) || /* mtab has non-null data to avoid needing strcmp */
+ ((_fstab_scan_active) && (!data))
+ )
+ /* prevent scans from triggering a scan */
+ return;
+
+ bak = _eeze_mount_mtab;
+ if (data)
+ if (!_eeze_mount_lock_mtab())
+ { /* FIXME: maybe queue job here? */
+ ERR("Losing events...");
+ return;
+ }
+ _eeze_mount_mtab = _eeze_mount_tab_parse(path);
+ if (data)
+ _eeze_mount_unlock_mtab();
+ if (!_eeze_mount_mtab)
+ {
+ ERR("Could not parse %s! keeping old tab...", path);
+ goto error;
+ }
+
+ if (data)
+ {
+ Eina_List *l;
+ Eeze_Disk *disk;
+
+ /* catch externally initiated mounts on existing disks by comparing known mount state to current state */
+ EINA_LIST_FOREACH(_eeze_disks, l, disk)
+ {
+ Eina_Bool mounted;
+
+ mounted = disk->mounted;
+
+ if ((eeze_disk_libmount_mounted_get(disk) != mounted) && (!disk->mount_status))
+ {
+ if (!mounted)
+ {
+ Eeze_Event_Disk_Mount *e;
+ e = malloc(sizeof(Eeze_Event_Disk_Mount));
+ if (e)
+ {
+ e->disk = disk;
+ ecore_event_add(EEZE_EVENT_DISK_MOUNT, e, NULL, NULL);
+ }
+ }
+ else
+ {
+ Eeze_Event_Disk_Unmount *e;
+ e = malloc(sizeof(Eeze_Event_Disk_Unmount));
+ if (e)
+ {
+ e->disk = disk;
+ ecore_event_add(EEZE_EVENT_DISK_UNMOUNT, e, NULL, NULL);
+ }
+ }
+ }
+ }
+ }
+
+ mnt_free_tab(bak);
+ return;
+
+error:
+ mnt_free_tab(_eeze_mount_mtab);
+ _eeze_mount_mtab = bak;
+}
+
+/*
+ *
+ * INVISIBLE
+ *
+ */
+
+Eina_Bool
+eeze_libmount_init(void)
+{
+ if (_eeze_mtab_lock)
+ return EINA_TRUE;
+ if (!(_eeze_mtab_lock = mnt_new_lock(NULL, 0)))
+ return EINA_FALSE;
+ return EINA_TRUE;
+}
+
+void
+eeze_libmount_shutdown(void)
+{
+ if (!_eeze_mtab_lock)
+ return;
+
+ mnt_unlock_file(_eeze_mtab_lock);
+ mnt_free_lock(_eeze_mtab_lock);
+ _eeze_mtab_lock = NULL;
+}
+
+/*
+ * helper function to return whether a disk is mounted
+ */
+Eina_Bool
+eeze_disk_libmount_mounted_get(Eeze_Disk *disk)
+{
+ mnt_fs *mnt;
+
+ if (!disk)
+ return EINA_FALSE;
+
+ if (!eeze_mount_mtab_scan() || !eeze_mount_fstab_scan())
+ return EINA_FALSE;
+
+ mnt = mnt_tab_find_srcpath(_eeze_mount_mtab, eeze_disk_devpath_get(disk), MNT_ITER_BACKWARD);
+ if (!mnt)
+ {
+ disk->mounted = EINA_FALSE;
+ return EINA_FALSE;
+ }
+
+ disk->mount_point = eina_stringshare_add(mnt_fs_get_target(mnt));
+ disk->mounted = EINA_TRUE;
+ return EINA_TRUE;
+}
+
+
+/*
+ * helper function to return the device that is mounted at a mount point
+ */
+const char *
+eeze_disk_libmount_mp_find_source(const char *mount_point)
+{
+ mnt_fs *mnt;
+
+ if (!mount_point)
+ return NULL;
+
+ if (!eeze_mount_mtab_scan() || !eeze_mount_fstab_scan())
+ return NULL;
+
+ mnt = mnt_tab_find_target(_eeze_mount_mtab, mount_point, MNT_ITER_BACKWARD);
+ if (!mnt)
+ mnt = mnt_tab_find_target(_eeze_mount_fstab, mount_point, MNT_ITER_BACKWARD);
+
+ if (!mnt)
+ return NULL;
+
+ return mnt_fs_get_source(mnt);
+}
+
+/*
+ * helper function to return a mount point from a uuid
+ */
+const char *
+eeze_disk_libmount_mp_lookup_by_uuid(const char *uuid)
+{
+ mnt_fs *mnt;
+
+ if (!uuid)
+ return NULL;
+
+ if (!eeze_mount_mtab_scan() || !eeze_mount_fstab_scan())
+ return NULL;
+
+ mnt = mnt_tab_find_tag(_eeze_mount_fstab, "UUID", uuid, MNT_ITER_BACKWARD);
+
+ if (!mnt)
+ return NULL;
+
+ return mnt_fs_get_target(mnt);
+}
+
+/*
+ * helper function to return a mount point from a label
+ */
+const char *
+eeze_disk_libmount_mp_lookup_by_label(const char *label)
+{
+ mnt_fs *mnt;
+
+ if (!label)
+ return NULL;
+
+ if (!eeze_mount_mtab_scan() || !eeze_mount_fstab_scan())
+ return NULL;
+
+ mnt = mnt_tab_find_tag(_eeze_mount_fstab, "LABEL", label, MNT_ITER_BACKWARD);
+
+ if (!mnt)
+ return NULL;
+
+ return mnt_fs_get_target(mnt);
+}
+
+/*
+ * helper function to return a mount point from a /dev/ path
+ */
+const char *
+eeze_disk_libmount_mp_lookup_by_devpath(const char *devpath)
+{
+ mnt_fs *mnt;
+
+ if (!devpath)
+ return NULL;
+
+ if (!eeze_mount_mtab_scan() || !eeze_mount_fstab_scan())
+ return NULL;
+
+ mnt = mnt_tab_find_srcpath(_eeze_mount_mtab, devpath, MNT_ITER_BACKWARD);
+ if (!mnt)
+ mnt = mnt_tab_find_srcpath(_eeze_mount_fstab, devpath, MNT_ITER_BACKWARD);
+
+ if (!mnt)
+ return NULL;
+
+ return mnt_fs_get_target(mnt);
+}
+
+/*
+ *
+ * API
+ *
+ */
+EAPI Eina_Bool
+eeze_mount_tabs_watch(void)
+{
+ mnt_tab *bak;
+
+ if (_watching)
+ return EINA_TRUE;
+
+ if (!_eeze_mount_lock_mtab())
+ return EINA_FALSE;
+
+ bak = _eeze_mount_tab_parse("/etc/mtab");
+ _eeze_mount_unlock_mtab();
+ if (!bak)
+ goto error;
+
+ mnt_free_tab(_eeze_mount_mtab);
+ _eeze_mount_mtab = bak;
+ if (!(bak = _eeze_mount_tab_parse("/etc/fstab")))
+ goto error;
+
+ mnt_free_tab(_eeze_mount_fstab);
+ _eeze_mount_fstab = bak;
+
+ _mtab_mon = ecore_file_monitor_add("/etc/mtab", _eeze_mount_tab_watcher, (void*)1);
+ _fstab_mon = ecore_file_monitor_add("/etc/fstab", _eeze_mount_tab_watcher, NULL);
+ _watching = EINA_TRUE;
+
+ return EINA_TRUE;
+
+error:
+ if (!_eeze_mount_mtab)
+ ERR("Could not parse /etc/mtab!");
+ else
+ {
+ ERR("Could not parse /etc/fstab!");
+ mnt_free_tab(_eeze_mount_mtab);
+ }
+ return EINA_FALSE;
+}
+
+EAPI void
+eeze_mount_tabs_unwatch(void)
+{
+ if (!_watching)
+ return;
+
+ ecore_file_monitor_del(_mtab_mon);
+ ecore_file_monitor_del(_fstab_mon);
+}
+
+EAPI Eina_Bool
+eeze_mount_mtab_scan(void)
+{
+ mnt_tab *bak;
+
+ if (_watching)
+ return EINA_TRUE;
+
+ if (!_eeze_mount_lock_mtab())
+ return EINA_FALSE;
+ bak = _eeze_mount_tab_parse("/etc/mtab");
+ _eeze_mount_unlock_mtab();
+ if (!bak)
+ goto error;
+ if (_eeze_mount_mtab)
+ mnt_free_tab(_eeze_mount_mtab);
+ _eeze_mount_mtab = bak;
+ return EINA_TRUE;
+
+error:
+ return EINA_FALSE;
+}
+
+EAPI Eina_Bool
+eeze_mount_fstab_scan(void)
+{
+ mnt_tab *bak;
+ if (_watching)
+ return EINA_TRUE;
+
+ bak = _eeze_mount_tab_parse("/etc/fstab");
+ if (!bak)
+ goto error;
+ if (_eeze_mount_fstab)
+ mnt_free_tab(_eeze_mount_fstab);
+ _eeze_mount_fstab = bak;
+
+ return EINA_TRUE;
+
+error:
+ return EINA_FALSE;
+}