From fe21e281a73bbd94336215b0f20896ff258c686d Mon Sep 17 00:00:00 2001 From: Cedric BAIL Date: Tue, 19 Feb 2013 13:33:41 +0900 Subject: [PATCH] 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. --- configure.ac | 30 +- src/Makefile_Eeze.am | 11 +- src/lib/eeze/eeze_disk_libmount.c | 495 ++++++++++++++++++++++++++ src/lib/eeze/eeze_disk_libmount_new.c | 4 +- src/lib/eeze/eeze_disk_libmount_old.c | 401 +++++++++++++++++++++ 5 files changed, 938 insertions(+), 3 deletions(-) create mode 100644 src/lib/eeze/eeze_disk_libmount.c create mode 100644 src/lib/eeze/eeze_disk_libmount_old.c 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 +#include +#include +#include +#include + +#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 #include #include -#include +#ifdef HAVE_EEZE_MOUNT +# include +#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 +#include +#include +#include + +#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; +}