parent
0cb7271e97
commit
c9e2fc434e
15 changed files with 1905 additions and 14 deletions
@ -0,0 +1,47 @@ |
||||
dnl Copyright (C) 2004-2008 Kim Woelders |
||||
dnl Copyright (C) 2008 Vincent Torri <vtorri at univ-evry dot fr> |
||||
dnl That code is public domain and can be freely used or copied. |
||||
dnl Originally snatched from somewhere... |
||||
|
||||
dnl Macro for checking if the compiler supports __attribute__ |
||||
|
||||
dnl Usage: AC_C___ATTRIBUTE__ |
||||
dnl call AC_DEFINE for HAVE___ATTRIBUTE__ and __UNUSED__ |
||||
dnl if the compiler supports __attribute__, HAVE___ATTRIBUTE__ is |
||||
dnl defined to 1 and __UNUSED__ is defined to __attribute__((unused)) |
||||
dnl otherwise, HAVE___ATTRIBUTE__ is not defined and __UNUSED__ is |
||||
dnl defined to nothing. |
||||
|
||||
AC_DEFUN([AC_C___ATTRIBUTE__], |
||||
[ |
||||
|
||||
AC_MSG_CHECKING([for __attribute__]) |
||||
|
||||
AC_CACHE_VAL([ac_cv___attribute__], |
||||
[AC_TRY_COMPILE( |
||||
[ |
||||
#include <stdlib.h> |
||||
|
||||
int func(int x); |
||||
int foo(int x __attribute__ ((unused))) |
||||
{ |
||||
exit(1); |
||||
} |
||||
], |
||||
[], |
||||
[ac_cv___attribute__="yes"], |
||||
[ac_cv___attribute__="no"] |
||||
)]) |
||||
|
||||
AC_MSG_RESULT($ac_cv___attribute__) |
||||
|
||||
if test "x${ac_cv___attribute__}" = "xyes" ; then |
||||
AC_DEFINE([HAVE___ATTRIBUTE__], [1], [Define to 1 if your compiler has __attribute__]) |
||||
AC_DEFINE([__UNUSED__], [__attribute__((unused))], [Macro declaring a function argument to be unused]) |
||||
else |
||||
AC_DEFINE([__UNUSED__], [], [Macro declaring a function argument to be unused]) |
||||
fi |
||||
|
||||
]) |
||||
|
||||
dnl End of ac_attribute.m4 |
@ -1,8 +1,33 @@ |
||||
MAINTAINERCLEANFILES = Makefile.in
|
||||
|
||||
bin_PROGRAMS = @EEZE_UDEV_TEST_PRG@
|
||||
EEZE_CFLAGS = \
|
||||
-I$(top_srcdir)/src/lib \ |
||||
@EEZE_CFLAGS@ |
||||
|
||||
EXTRA_PROGRAMS = eeze_udev_test
|
||||
|
||||
if HAVE_EEZE_MOUNT |
||||
DISK_PROGS = eeze_mount eeze_umount eeze_disk_ls
|
||||
else |
||||
DISK_PROGS =
|
||||
endif |
||||
|
||||
bin_PROGRAMS = @EEZE_UDEV_TEST_PRG@ $(DISK_PROGS)
|
||||
|
||||
eeze_udev_test_SOURCES = eeze_udev_test.c
|
||||
eeze_udev_test_CPPFLAGS = -I$(top_srcdir)/src/lib @EEZE_CFLAGS@
|
||||
eeze_udev_test_LDADD = $(top_builddir)/src/lib/libeeze.la @EEZE_LIBS@
|
||||
|
||||
if HAVE_EEZE_MOUNT |
||||
eeze_mount_SOURCES = eeze_mount.c
|
||||
eeze_mount_CFLAGS = -I$(top_srcdir)/src/lib $(EEZE_CFLAGS) @LIBMOUNT_CFLAGS@ @ECORE_FILE_CFLAGS@
|
||||
eeze_mount_LDADD = $(top_builddir)/src/lib/libeeze.la @LIBMOUNT_CFLAGS@ @ECORE_FILE_CFLAGS@
|
||||
|
||||
eeze_umount_SOURCES = eeze_umount.c
|
||||
eeze_umount_CFLAGS = -I$(top_srcdir)/src/lib $(EEZE_CFLAGS) @LIBMOUNT_CFLAGS@ @ECORE_FILE_CFLAGS@
|
||||
eeze_umount_LDADD = $(top_builddir)/src/lib/libeeze.la @LIBMOUNT_CFLAGS@ @ECORE_FILE_CFLAGS@
|
||||
|
||||
eeze_disk_ls_SOURCES = eeze_disk_ls.c
|
||||
eeze_disk_ls_CFLAGS = -I$(top_srcdir)/src/lib $(EEZE_CFLAGS) @LIBMOUNT_CFLAGS@ @ECORE_FILE_CFLAGS@
|
||||
eeze_disk_ls_LDADD = $(top_builddir)/src/lib/libeeze.la @LIBMOUNT_CFLAGS@ @ECORE_FILE_CFLAGS@
|
||||
endif |
||||
|
@ -0,0 +1,53 @@ |
||||
#include <stdio.h> |
||||
#include <Ecore.h> |
||||
#include <Eeze.h> |
||||
#include <Eeze_Disk.h> |
||||
|
||||
/* simple app to print disks and their mount points */ |
||||
|
||||
int |
||||
main(void) |
||||
{ |
||||
Eina_List *disks; |
||||
const char *syspath; |
||||
|
||||
eeze_init(); |
||||
eeze_disk_function(); |
||||
|
||||
disks = eeze_udev_find_by_type(EEZE_UDEV_TYPE_DRIVE_MOUNTABLE, NULL); |
||||
printf("Found the following disks:\n"); |
||||
EINA_LIST_FREE(disks, syspath) |
||||
{ |
||||
Eeze_Disk *disk; |
||||
|
||||
disk = eeze_disk_new(syspath); |
||||
printf("\t%s - %s:%s\n", syspath, eeze_disk_devpath_get(disk), eeze_disk_mount_point_get(disk)); |
||||
eeze_disk_free(disk); |
||||
eina_stringshare_del(syspath); |
||||
} |
||||
|
||||
disks = eeze_udev_find_by_type(EEZE_UDEV_TYPE_DRIVE_REMOVABLE, NULL); |
||||
printf("Found the following removable drives:\n"); |
||||
EINA_LIST_FREE(disks, syspath) |
||||
{ |
||||
Eeze_Disk *disk; |
||||
|
||||
disk = eeze_disk_new(syspath); |
||||
printf("\t%s - %s:%s\n", syspath, eeze_disk_devpath_get(disk), eeze_disk_mount_point_get(disk)); |
||||
eeze_disk_free(disk); |
||||
eina_stringshare_del(syspath); |
||||
} |
||||
|
||||
disks = eeze_udev_find_by_type(EEZE_UDEV_TYPE_DRIVE_INTERNAL, NULL); |
||||
printf("Found the following internal drives:\n"); |
||||
EINA_LIST_FREE(disks, syspath) |
||||
{ |
||||
Eeze_Disk *disk; |
||||
|
||||
disk = eeze_disk_new(syspath); |
||||
printf("\t%s - %s\n", syspath, eeze_disk_devpath_get(disk)); |
||||
eeze_disk_free(disk); |
||||
eina_stringshare_del(syspath); |
||||
} |
||||
return 0; |
||||
} |
@ -0,0 +1,115 @@ |
||||
#include <Eeze.h> |
||||
#include <Eeze_Disk.h> |
||||
#include <Ecore.h> |
||||
#include <Ecore_File.h> |
||||
#include <Ecore_Getopt.h> |
||||
#include <stdio.h> |
||||
|
||||
/** This app can be used as a "dumb" replacement for mount. Just don't try anything fancy yet! */ |
||||
static const Ecore_Getopt opts = |
||||
{ |
||||
"eeze_mount", |
||||
"eeze_mount /dev/sdb1 /media/disk", |
||||
"1.0", |
||||
"(C) 2010 Mike Blumenkrantz", |
||||
"LGPL", |
||||
"Mount a disk using either its /sys/ path or its /dev/ path\n\n", |
||||
1, |
||||
{
|
||||
ECORE_GETOPT_VERSION('V', "version"), |
||||
ECORE_GETOPT_COPYRIGHT('R', "copyright"), |
||||
ECORE_GETOPT_LICENSE('L', "license"), |
||||
ECORE_GETOPT_HELP('h', "help"), |
||||
ECORE_GETOPT_SENTINEL |
||||
} |
||||
}; |
||||
|
||||
void |
||||
_mount_cb(void *data, int type, Eeze_Event_Disk_Mount *e) |
||||
{ |
||||
(void)data; |
||||
(void)type; |
||||
printf("Success!\n"); |
||||
eeze_disk_free(e->disk); |
||||
ecore_main_loop_quit(); |
||||
} |
||||
|
||||
void |
||||
_error_cb(void *data, int type, Eeze_Event_Disk_Error *de) |
||||
{ |
||||
(void)data; |
||||
(void)type; |
||||
printf("Could not mount disk with /dev/ path: %s!\n", eeze_disk_devpath_get(de->disk)); |
||||
eeze_disk_free(de->disk); |
||||
ecore_main_loop_quit(); |
||||
} |
||||
|
||||
int |
||||
main(int argc, char *argv[]) |
||||
{ |
||||
int args; |
||||
const char *dev, *mount_point; |
||||
Eina_Bool exit_option = EINA_FALSE; |
||||
Eeze_Disk *disk; |
||||
|
||||
Ecore_Getopt_Value values[] = |
||||
{
|
||||
ECORE_GETOPT_VALUE_BOOL(exit_option), |
||||
ECORE_GETOPT_VALUE_BOOL(exit_option), |
||||
ECORE_GETOPT_VALUE_BOOL(exit_option), |
||||
ECORE_GETOPT_VALUE_BOOL(exit_option) |
||||
}; |
||||
|
||||
if (argc < 2) |
||||
{ |
||||
printf("Insufficient args specified!\n"); |
||||
ecore_getopt_help(stderr, &opts); |
||||
exit(1); |
||||
} |
||||
|
||||
ecore_init(); |
||||
eeze_init(); |
||||
ecore_app_args_set(argc, (const char **)argv); |
||||
args = ecore_getopt_parse(&opts, values, argc, argv); |
||||
|
||||
if (exit_option) |
||||
return 0; |
||||
|
||||
if (args < 0) |
||||
{ |
||||
printf("No args specified!\n"); |
||||
ecore_getopt_help(stderr, &opts); |
||||
exit(1); |
||||
} |
||||
|
||||
dev = argv[args]; |
||||
if (args + 1 < argc) |
||||
mount_point = argv[args + 1]; |
||||
if ((!strncmp(dev, "/sys/", 5)) || (!strncmp(dev, "/dev/", 5))) |
||||
disk = eeze_disk_new(dev); |
||||
else if ((argc == 2) && (ecore_file_is_dir(dev))) |
||||
disk = eeze_disk_new_from_mount(dev); |
||||
else |
||||
{ |
||||
printf("[Device] must be either a /dev/ path or a /sys/ path!\n"); |
||||
ecore_getopt_help(stderr, &opts); |
||||
exit(1); |
||||
} |
||||
if (eeze_disk_mounted_get(disk)) |
||||
{ |
||||
printf("[%s] is already mounted!", dev); |
||||
exit(1); |
||||
} |
||||
if (argc > 2) |
||||
eeze_disk_mount_point_set(disk, mount_point); |
||||
ecore_event_handler_add(EEZE_EVENT_DISK_MOUNT, (Ecore_Event_Handler_Cb)_mount_cb, NULL); |
||||
ecore_event_handler_add(EEZE_EVENT_DISK_ERROR, (Ecore_Event_Handler_Cb)_error_cb, NULL); |
||||
if (!eeze_disk_mount(disk)) |
||||
{ |
||||
printf("Mount operation could not be started!\n"); |
||||
exit(1); |
||||
} |
||||
ecore_main_loop_begin(); |
||||
|
||||
return 0; |
||||
} |
@ -0,0 +1,111 @@ |
||||
#include <Eeze.h> |
||||
#include <Eeze_Disk.h> |
||||
#include <Ecore.h> |
||||
#include <Ecore_File.h> |
||||
#include <Ecore_Getopt.h> |
||||
#include <stdio.h> |
||||
|
||||
/** This app can be used as a "dumb" replacement for unmount. Just don't try anything fancy yet! */ |
||||
static const Ecore_Getopt opts = |
||||
{ |
||||
"eeze_unmount", |
||||
"eeze_unmount /dev/sdb1 /media/disk", |
||||
"1.0", |
||||
"(C) 2010 Mike Blumenkrantz", |
||||
"LGPL", |
||||
"unmount a disk using either its /sys/ path or its /dev/ path\n\n", |
||||
1, |
||||
{
|
||||
ECORE_GETOPT_VERSION('V', "version"), |
||||
ECORE_GETOPT_COPYRIGHT('R', "copyright"), |
||||
ECORE_GETOPT_LICENSE('L', "license"), |
||||
ECORE_GETOPT_HELP('h', "help"), |
||||
ECORE_GETOPT_SENTINEL |
||||
} |
||||
}; |
||||
|
||||
void |
||||
_unmount_cb(void *data, int type, Eeze_Event_Disk_Unmount *e) |
||||
{ |
||||
(void)data; |
||||
(void)type; |
||||
printf("Success!\n"); |
||||
eeze_disk_free(e->disk); |
||||
ecore_main_loop_quit(); |
||||
} |
||||
|
||||
void |
||||
_error_cb(void *data, int type, Eeze_Event_Disk_Error *de) |
||||
{ |
||||
(void)data; |
||||
(void)type; |
||||
printf("Could not unmount disk with /dev/ path: %s!\n", eeze_disk_devpath_get(de->disk)); |
||||
eeze_disk_free(de->disk); |
||||
ecore_main_loop_quit(); |
||||
} |
||||
|
||||
int |
||||
main(int argc, char *argv[]) |
||||
{ |
||||
int args; |
||||
const char *dev; |
||||
Eina_Bool exit_option = EINA_FALSE; |
||||
Eeze_Disk *disk; |
||||
|
||||
Ecore_Getopt_Value values[] = |
||||
{
|
||||
ECORE_GETOPT_VALUE_BOOL(exit_option), |
||||
ECORE_GETOPT_VALUE_BOOL(exit_option), |
||||
ECORE_GETOPT_VALUE_BOOL(exit_option), |
||||
ECORE_GETOPT_VALUE_BOOL(exit_option) |
||||
}; |
||||
|
||||
if (argc < 2) |
||||
{ |
||||
printf("Insufficient args specified!\n"); |
||||
ecore_getopt_help(stderr, &opts); |
||||
exit(1); |
||||
} |
||||
|
||||
ecore_init(); |
||||
eeze_init(); |
||||
ecore_app_args_set(argc, (const char **)argv); |
||||
args = ecore_getopt_parse(&opts, values, argc, argv); |
||||
|
||||
if (exit_option) |
||||
return 0; |
||||
|
||||
if (args < 0) |
||||
{ |
||||
printf("No args specified!\n"); |
||||
ecore_getopt_help(stderr, &opts); |
||||
exit(1); |
||||
} |
||||
|
||||
dev = argv[args]; |
||||
if ((!strncmp(dev, "/sys/", 5)) || (!strncmp(dev, "/dev/", 5))) |
||||
disk = eeze_disk_new(dev); |
||||
else if ((argc == 2) && (ecore_file_is_dir(dev))) |
||||
disk = eeze_disk_new_from_mount(dev); |
||||
else |
||||
{ |
||||
printf("[Device] must be either a /dev/ path or a /sys/ path!\n"); |
||||
ecore_getopt_help(stderr, &opts); |
||||
exit(1); |
||||
} |
||||
if (!eeze_disk_mounted_get(disk)) |
||||
{ |
||||
printf("[%s] is already unmounted!", dev); |
||||
exit(1); |
||||
} |
||||
ecore_event_handler_add(EEZE_EVENT_DISK_UNMOUNT, (Ecore_Event_Handler_Cb)_unmount_cb, NULL); |
||||
ecore_event_handler_add(EEZE_EVENT_DISK_ERROR, (Ecore_Event_Handler_Cb)_error_cb, NULL); |
||||
if (!eeze_disk_unmount(disk)) |
||||
{ |
||||
printf("unmount operation could not be started!\n"); |
||||
exit(1); |
||||
} |
||||
ecore_main_loop_begin(); |
||||
|
||||
return 0; |
||||
} |
@ -0,0 +1,117 @@ |
||||
#ifndef EEZE_DISK_H |
||||
#define EEZE_DISK_H |
||||
|
||||
#ifdef EAPI |
||||
# undef EAPI |
||||
#endif |
||||
|
||||
#ifdef __GNUC__ |
||||
# if __GNUC__ >= 4 |
||||
# define EAPI __attribute__ ((visibility("default"))) |
||||
# else |
||||
# define EAPI |
||||
# endif |
||||
#else |
||||
# define EAPI |
||||
#endif |
||||
|
||||
#include <Eina.h> |
||||
#include <Ecore.h> |
||||
|
||||
/**
|
||||
* @file Eeze_Disk.h |
||||
* @brief Disk manipulation |
||||
* |
||||
* Eeze disk functions allow you to quickly and efficiently manipulate disks |
||||
* through simple function calls. |
||||
* |
||||
* @addtogroup disk Disk |
||||
* @{ |
||||
*/ |
||||
|
||||
#ifdef __cplusplus |
||||
extern "C" { |
||||
#endif |
||||
|
||||
typedef enum |
||||
{ |
||||
EEZE_DISK_TYPE_UNKNOWN = 0, /**< type could not be determined */ |
||||
EEZE_DISK_TYPE_INTERNAL = 1, /**< internal drive */ |
||||
EEZE_DISK_TYPE_CDROM = 2, /**< cdrom drive */ |
||||
EEZE_DISK_TYPE_USB = 4 /**< usb drive */ |
||||
} Eeze_Disk_Type; |
||||
|
||||
typedef enum |
||||
{ |
||||
EEZE_DISK_MOUNTOPT_DEFAULTS = 0xf0, |
||||
EEZE_DISK_MOUNTOPT_LOOP = (1 << 1) |
||||
} Eeze_Mount_Opts; |
||||
|
||||
EAPI extern int EEZE_EVENT_DISK_MOUNT; |
||||
EAPI extern int EEZE_EVENT_DISK_UNMOUNT; |
||||
EAPI extern int EEZE_EVENT_DISK_ERROR; |
||||
|
||||
typedef struct _Eeze_Event_Disk_Mount Eeze_Event_Disk_Mount; |
||||
typedef struct _Eeze_Event_Disk_Unmount Eeze_Event_Disk_Unmount; |
||||
typedef struct _Eeze_Disk Eeze_Disk; |
||||
|
||||
struct _Eeze_Event_Disk_Mount |
||||
{ |
||||
Eeze_Disk *disk; |
||||
}; |
||||
|
||||
struct _Eeze_Event_Disk_Unmount |
||||
{ |
||||
Eeze_Disk *disk; |
||||
}; |
||||
|
||||
|
||||
typedef struct _Eeze_Event_Disk_Error Eeze_Event_Disk_Error; |
||||
|
||||
struct _Eeze_Event_Disk_Error |
||||
{ |
||||
Eeze_Disk *disk; |
||||
const char *message; |
||||
struct |
||||
{ /* probably switching this to enum */ |
||||
Eina_Bool mount : 1; |
||||
Eina_Bool unmount :1; |
||||
} type; |
||||
}; |
||||
|
||||
EAPI void eeze_disk_function(void); |
||||
EAPI Eeze_Disk *eeze_disk_new(const char *path); |
||||
EAPI Eeze_Disk *eeze_disk_new_from_mount(const char *mount_point); |
||||
EAPI void eeze_disk_free(Eeze_Disk *disk); |
||||
EAPI void eeze_disk_scan(Eeze_Disk *disk); |
||||
EAPI void eeze_disk_data_set(Eeze_Disk *disk, void *data); |
||||
EAPI void *eeze_disk_data_get(Eeze_Disk *disk); |
||||
EAPI const char *eeze_disk_syspath_get(Eeze_Disk *disk); |
||||
EAPI const char *eeze_disk_devpath_get(Eeze_Disk *disk); |
||||
EAPI const char *eeze_disk_fstype_get(Eeze_Disk *disk); |
||||
EAPI const char *eeze_disk_vendor_get(Eeze_Disk *disk); |
||||
EAPI const char *eeze_disk_model_get(Eeze_Disk *disk); |
||||
EAPI const char *eeze_disk_serial_get(Eeze_Disk *disk); |
||||
EAPI const char *eeze_disk_uuid_get(Eeze_Disk *disk); |
||||
EAPI const char *eeze_disk_label_get(Eeze_Disk *disk); |
||||
EAPI Eeze_Disk_Type eeze_disk_type_get(Eeze_Disk *disk); |
||||
EAPI Eina_Bool eeze_disk_removable_get(Eeze_Disk *disk); |
||||
|
||||
EAPI Eina_Bool eeze_disk_mounted_get(Eeze_Disk *disk); |
||||
EAPI Eina_Bool eeze_disk_mount(Eeze_Disk *disk); |
||||
EAPI Eina_Bool eeze_disk_unmount(Eeze_Disk *disk); |
||||
EAPI const char *eeze_disk_mount_point_get(Eeze_Disk *disk); |
||||
EAPI Eina_Bool eeze_disk_mount_point_set(Eeze_Disk *disk, const char *mount_point); |
||||
|
||||
EAPI Eina_Bool eeze_mount_tabs_watch(void); |
||||
EAPI void eeze_mount_tabs_unwatch(void); |
||||
EAPI Eina_Bool eeze_mount_mtab_scan(void); |
||||
EAPI Eina_Bool eeze_mount_fstab_scan(void); |
||||
|
||||
#ifdef __cplusplus |
||||
} |
||||
#endif |
||||
|
||||
/** @} */ |
||||
|
||||
#endif |
@ -0,0 +1,466 @@ |
||||
#ifdef HAVE_CONFIG_H |
||||
#include "config.h" |
||||
#endif |
||||
|
||||
#include <Ecore.h> |
||||
#include <Eeze.h> |
||||
#include <Eeze_Disk.h> |
||||
|
||||
#include "eeze_udev_private.h" |
||||
#include "eeze_disk_private.h" |
||||
|
||||
/**
|
||||
* @addtogroup disk Disk |
||||
* @{ |
||||
*/ |
||||
|
||||
static Eeze_Disk_Type |
||||
_eeze_disk_type_find(Eeze_Disk *disk) |
||||
{ |
||||
const char *bus; |
||||
bus = udev_device_get_property_value(disk->device, "ID_BUS"); |
||||
if (!bus) |
||||
return EEZE_DISK_TYPE_UNKNOWN; |
||||
|
||||
if (!strcmp(bus, "ata") || !strcmp(bus, "scsi")) |
||||
{ /* FIXME: I think some other types of devices fall into this, check later */ |
||||
if (udev_device_get_property_value(disk->device, "ID_CDROM")) |
||||
return EEZE_DISK_TYPE_CDROM; |
||||
else |
||||
return EEZE_DISK_TYPE_INTERNAL; |
||||
} |
||||
else if (!strcmp(bus, "usb")) |
||||
return EEZE_DISK_TYPE_USB; |
||||
|
||||
return EEZE_DISK_TYPE_UNKNOWN; |
||||
} |
||||
|
||||
static _udev_device * |
||||
_eeze_disk_device_from_property(const char *prop, Eina_Bool uuid) |
||||
{ |
||||
_udev_enumerate *en; |
||||
_udev_list_entry *devs, *cur; |
||||
_udev_device *device; |
||||
const char *devname; |
||||
|
||||
en = udev_enumerate_new(udev); |
||||
|
||||
if (!en) |
||||
return NULL; |
||||
|
||||
if (uuid) |
||||
udev_enumerate_add_match_property(en, "ID_FS_UUID", prop); |
||||
else |
||||
udev_enumerate_add_match_property(en, "ID_FS_LABEL", prop); |
||||
udev_enumerate_scan_devices(en); |
||||
devs = udev_enumerate_get_list_entry(en); |
||||
udev_list_entry_foreach(cur, devs) |
||||
{ |
||||
devname = udev_list_entry_get_name(cur); |
||||
device = udev_device_new_from_syspath(udev, devname); |
||||
break; |
||||
} |
||||
udev_enumerate_unref(en); |
||||
return device; |
||||
|
||||
} |
||||
|
||||
/**
|
||||
* @brief Use this function to determine whether your eeze is disk-capable |
||||
* |
||||
* Since applications will die if they run against a function that doesn't exist, |
||||
* if your application successfully runs this function then you have eeze_disk. |
||||
*/ |
||||
EAPI void |
||||
eeze_disk_function(void) |
||||
{ |
||||
} |
||||
|
||||
/**
|
||||
* @brief Create a new disk object from a /sys/ path or /dev/ path |
||||
* @param path The /sys/ or /dev path of the disk; CANNOT be #NULL |
||||
* @return The new disk object |
||||
* |
||||
* This function creates a new #Eeze_Disk from @p path. Note that this function |
||||
* does the minimal amount of work in order to save memory, and udev info about the disk |
||||
* is not retrieved in this call. |
||||
*/ |
||||
EAPI Eeze_Disk * |
||||
eeze_disk_new(const char *path) |
||||
{ |
||||
Eeze_Disk *disk; |
||||
_udev_device *dev; |
||||
const char *syspath; |
||||
Eina_Bool is_dev = EINA_FALSE; |
||||
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(path, NULL); |
||||
|
||||
if (!strncmp(path, "/dev/", 5)) |
||||
{ |
||||
is_dev = EINA_TRUE; |
||||
syspath = eeze_udev_devpath_get_syspath(path); |
||||
if (!syspath) |
||||
return NULL; |
||||
|
||||
if (!(dev = _new_device(syspath))) |
||||
{ |
||||
eina_stringshare_del(syspath); |
||||
return NULL; |
||||
} |
||||
} |
||||
else if (!(dev = _new_device(path))) |
||||
return NULL; |
||||
|
||||
|
||||
if (!(disk = calloc(1, sizeof(Eeze_Disk)))) |
||||
return NULL; |
||||
|
||||
|
||||
if (is_dev) |
||||
{ |
||||
disk->devpath = eina_stringshare_add(path); |
||||
disk->syspath = syspath; |
||||
} |
||||
else |
||||
disk->syspath = eina_stringshare_add(udev_device_get_syspath(dev)); |
||||
|
||||
|
||||
disk->device = dev; |
||||
disk->mount_cmd_changed = EINA_TRUE; |
||||
disk->unmount_cmd_changed = EINA_TRUE; |
||||
|
||||
return disk; |
||||
} |
||||
|
||||
/**
|
||||
* @brief Create a new disk object from a mount point |
||||
* @param mount_point The mount point of the disk; CANNOT be #NULL |
||||
* @return The new disk object |
||||
* |
||||
* This function creates a new #Eeze_Disk from @p mount_point. Note that this function |
||||
* does the minimal amount of work in order to save memory, and udev info about the disk |
||||
* is not retrieved in this call. If the disk is not currently mounted, it must have an entry |
||||
* in /etc/fstab. |
||||
*/ |
||||
EAPI Eeze_Disk * |
||||
eeze_disk_new_from_mount(const char *mount_point) |
||||
{ |
||||
Eeze_Disk *disk = NULL; |
||||
_udev_device *dev = NULL; |
||||
const char *syspath = NULL, *source, *uuid = NULL, *label = NULL, *devpath = NULL; |
||||
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(mount_point, NULL); |
||||
|
||||
if (!(source = eeze_disk_libmount_mp_find_source(mount_point))) |
||||
return NULL; |
||||
|
||||
if (source[4] == '=') |
||||
{ |
||||
source += 4; |
||||
uuid = eina_stringshare_add(source); |
||||
dev = _eeze_disk_device_from_property(uuid, EINA_TRUE); |
||||
} |
||||
else if (source[5] == '=') |
||||
{ |
||||
source += 5; |
||||
label = eina_stringshare_add(source); |
||||
dev = _eeze_disk_device_from_property(label, EINA_FALSE); |
||||
} |
||||
else |
||||
{ |
||||
devpath = eina_stringshare_add(source); |
||||
dev = _new_device(devpath); |
||||
} |
||||
|
||||
if (!dev) |
||||
goto error; |
||||
|
||||
if (!(disk = calloc(1, sizeof(Eeze_Disk)))) |
||||
goto error; |
||||
|
||||
disk->syspath = udev_device_get_syspath(dev); |
||||
|
||||
disk->device = dev; |
||||
disk->mount_cmd_changed = EINA_TRUE; |
||||
disk->unmount_cmd_changed = EINA_TRUE; |
||||
if (uuid) |
||||
disk->cache.uuid = uuid; |
||||
else if (label) |
||||
disk->cache.label = label; |
||||
else |
||||
disk->devpath = devpath; |
||||
|
||||
return disk; |
||||
error: |
||||
if (uuid) |
||||
eina_stringshare_del(uuid); |
||||
else if (label) |
||||
eina_stringshare_del(label); |
||||
else if (devpath) |
||||
eina_stringshare_del(devpath); |
||||
if (syspath) |
||||
eina_stringshare_del(syspath); |
||||
if (dev) |
||||
udev_device_unref(dev); |
||||
return NULL; |
||||
} |
||||
|
||||
/**
|
||||
* @brief Frees a disk object |
||||
* @param disk The disk object to free |
||||
* |
||||
* This call frees an #Eeze_Disk. Once freed, the disk can no longer be used. |
||||
*/ |
||||
EAPI void |
||||
eeze_disk_free(Eeze_Disk *disk) |
||||
{ |
||||
EINA_SAFETY_ON_NULL_RETURN(disk); |
||||
|
||||
eina_stringshare_del(disk->syspath); |
||||
udev_device_unref(disk->device); |
||||
if (disk->mount_cmd) |
||||
eina_strbuf_free(disk->mount_cmd); |
||||
if (disk->unmount_cmd) |
||||
eina_strbuf_free(disk->unmount_cmd); |
||||
free(disk); |
||||
} |
||||
|
||||
/**
|
||||
* @brief Retrieve all disk information |
||||
* @param disk |
||||
* |
||||
* Use this function to retrieve all of a disk's information at once, then use |
||||
* a "get" function to retrieve the value. Data retrieved in this call is cached, |
||||
* meaning that subsequent calls will return immediately without performing any work. |
||||
*/ |
||||
EAPI void |
||||
eeze_disk_scan(Eeze_Disk *disk) |
||||
{ |
||||
EINA_SAFETY_ON_NULL_RETURN(disk); |
||||
/* never rescan; if these values change then something is seriously wrong */ |
||||
if (disk->cache.filled) return; |
||||
|
||||
if (!disk->cache.vendor) |
||||
disk->cache.vendor = udev_device_get_property_value(disk->device, "ID_VENDOR"); |
||||
if (!disk->cache.model) |
||||
disk->cache.model = udev_device_get_property_value(disk->device, "ID_MODEL"); |
||||
if (!disk->cache.serial) |
||||
disk->cache.serial = udev_device_get_property_value(disk->device, "ID_SERIAL_SHORT"); |
||||
if (!disk->cache.uuid) |
||||
disk->cache.uuid = udev_device_get_property_value(disk->device, "ID_FS_UUID"); |
||||
if (!disk->cache.type) |
||||
disk->cache.type = _eeze_disk_type_find(disk); |
||||
if (!disk->cache.label) |
||||
disk->cache.label = udev_device_get_property_value(disk->device, "ID_FS_LABEL"); |
||||
disk->cache.removable = !!strtol(udev_device_get_sysattr_value(disk->device, "removable"), NULL, 10); |
||||
|
||||
disk->cache.filled = EINA_TRUE; |
||||
} |
||||
|
||||
/**
|
||||
* @brief Associate data with a disk |
||||
* @param disk The disk |
||||
* @param data The data |
||||
* |
||||
* Data can be associated with @p disk with this function. |
||||
* @see eeze_disk_data_get |
||||
*/ |
||||
EAPI void |
||||
eeze_disk_data_set(Eeze_Disk *disk, void *data) |
||||
{ |
||||
EINA_SAFETY_ON_NULL_RETURN(disk); |
||||
|
||||
disk->data = data; |
||||
} |
||||
|
||||
/**
|
||||
* @brief Retrieve data previously associated with a disk |
||||
* @param disk The disk |
||||
* @return The data |
||||
* |
||||
* Data that has been previously associated with @p disk |
||||
* is returned with this function. |
||||
* @see eeze_disk_data_set |
||||
*/ |
||||
EAPI void * |
||||
eeze_disk_data_get(Eeze_Disk *disk) |
||||
{ |
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(disk, NULL); |
||||
|
||||
return disk->data; |
||||
} |
||||
|
||||
/**
|
||||
* @brief Return the /sys/ path of a disk |
||||
* @param disk The disk |
||||
* @return The /sys/ path |
||||
* |
||||
* This retrieves the /sys/ path that udev associates with @p disk. |
||||
*/ |
||||
EAPI const char * |
||||
eeze_disk_syspath_get(Eeze_Disk *disk) |
||||
{ |
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(disk, NULL); |
||||
|
||||
return disk->syspath; |
||||
} |
||||
|
||||
/**
|
||||
* @brief Return the /dev/ path of a disk |
||||
* @param disk The disk |
||||
* @return The /dev/ path |
||||
* |
||||
* This retrieves the /dev/ path that udev has created a device node at for @p disk. |
||||
*/ |
||||
EAPI const char * |
||||
eeze_disk_devpath_get(Eeze_Disk *disk) |
||||
{ |
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(disk, NULL); |
||||
|
||||
if (disk->devpath) |
||||
return disk->devpath; |
||||
disk->devpath = udev_device_get_devnode(disk->device); |
||||
return disk->devpath; |
||||
} |
||||
|
||||
/**
|
||||
* @brief Return the filesystem of the disk (if known) |
||||
* @param disk The disk |
||||
* @return The filesystem type |
||||
* |
||||
* This retrieves the filesystem that the disk is using, or #NULL if unknown. |
||||
*/ |
||||
EAPI const char * |
||||
eeze_disk_fstype_get(Eeze_Disk *disk) |
||||
{ |
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(disk, NULL); |
||||
|
||||
return disk->fstype; |
||||
} |
||||
|
||||
/**
|
||||
* @brief Return the manufacturing vendor of the disk |
||||
* @param disk The disk |
||||
* @return The vendor |
||||
* |
||||
* This retrieves the vendor which manufactured the disk, or #NULL if unknown. |
||||
*/ |
||||
EAPI const char * |
||||
eeze_disk_vendor_get(Eeze_Disk *disk) |
||||
{ |
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(disk, NULL); |
||||
|
||||
if (disk->cache.vendor) |
||||
return disk->cache.vendor; |
||||
|
||||
disk->cache.vendor = udev_device_get_property_value(disk->device, "ID_VENDOR"); |
||||
return disk->cache.vendor; |
||||
} |
||||
|
||||
/**
|
||||
* @brief Return the model of the disk |
||||
* @param disk The disk |
||||
* @return The model |
||||
* |
||||
* This retrieves the model of the disk, or #NULL if unknown. |
||||
*/ |
||||
EAPI const char * |
||||
eeze_disk_model_get(Eeze_Disk *disk) |
||||
{ |
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(disk, NULL); |
||||
|
||||
if (disk->cache.model) |
||||
return disk->cache.model; |
||||
|
||||
disk->cache.model = udev_device_get_property_value(disk->device, "ID_MODEL"); |
||||
return disk->cache.model; |
||||
} |
||||
|
||||
/**
|
||||
* @brief Return the serial number of the disk |
||||
* @param disk The disk |
||||
* @return The serial number |
||||
* |
||||
* This retrieves the serial number the disk, or #NULL if unknown. |
||||
*/ |
||||
EAPI const char * |
||||
eeze_disk_serial_get(Eeze_Disk *disk) |
||||
{ |
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(disk, NULL); |
||||
|
||||
if (disk->cache.serial) |
||||
return disk->cache.serial; |
||||
disk->cache.serial = udev_device_get_property_value(disk->device, "ID_SERIAL_SHORT"); |
||||
return disk->cache.serial; |
||||
} |
||||
|
||||
/**
|
||||
* @brief Return the UUID of the disk |
||||
* @param disk The disk |
||||
* @return The UUID |
||||
* |
||||
* This retrieves the UUID of the disk, or #NULL if unknown. |
||||
* A UUID is a 36 character (hopefully) unique identifier which can |
||||
* be used to store persistent information about a disk. |
||||
*/ |
||||
EAPI const char * |
||||
eeze_disk_uuid_get(Eeze_Disk *disk) |
||||
{ |
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(disk, NULL); |
||||
|
||||
if (disk->cache.uuid) |
||||
return disk->cache.uuid; |
||||
disk->cache.uuid = udev_device_get_property_value(disk->device, "ID_FS_UUID"); |
||||
return disk->cache.uuid; |
||||
} |
||||
|
||||
/**
|
||||
* @brief Return the label of the disk |
||||
* @param disk The disk |
||||
* @return The label |
||||
* |
||||
* This retrieves the label (name) of the disk, or #NULL if unknown. |
||||
*/ |
||||
EAPI const char * |
||||
eeze_disk_label_get(Eeze_Disk *disk) |
||||
{ |
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(disk, NULL); |
||||
|
||||
if (disk->cache.label) |
||||
return disk->cache.label; |
||||
disk->cache.label = udev_device_get_property_value(disk->device, "ID_FS_LABEL"); |
||||
return disk->cache.label; |
||||
} |
||||
|
||||
/**
|
||||
* @brief Return the #Eeze_Disk_Type of the disk |
||||
* @param disk The disk |
||||
* @return The type |
||||
* |
||||
* This retrieves the #Eeze_Disk_Type of the disk. This call is useful for determining |
||||
* the bus that the disk is connected through. |
||||
*/ |
||||
EAPI Eeze_Disk_Type |
||||
eeze_disk_type_get(Eeze_Disk *disk) |
||||
{ |
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(disk, EEZE_DISK_TYPE_UNKNOWN); |
||||
|
||||
if (disk->cache.type) |
||||
return disk->cache.type; |
||||
disk->cache.type = _eeze_disk_type_find(disk); |
||||
return disk->cache.type; |
||||
} |
||||
|
||||
EAPI Eina_Bool |
||||
eeze_disk_removable_get(Eeze_Disk *disk) |
||||
{ |
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(disk, EINA_FALSE); |
||||
|
||||
if (disk->cache.filled) |
||||
return disk->cache.removable; |
||||
|
||||
disk->cache.removable = !!strtol(udev_device_get_sysattr_value(disk->device, "removable"), NULL, 10); |
||||
return disk->cache.removable; |
||||
} |
||||
|
||||
/** @} */ |
@ -0,0 +1,405 @@ |
||||
#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" |
||||
|
||||
/**
|
||||
* @addtogroup disk Disk |
||||
* @{ |
||||
*/ |
||||
|
||||
/*
|
||||
* |
||||
* 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; |
||||
|
||||
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; |
||||
} |
||||
|
||||
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); |
||||
} |
||||
|
||||
/*
|
||||
* 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) |
||||
return EINA_FALSE; |
||||
|
||||
disk->mount_point = eina_stringshare_add(mnt_fs_get_target(mnt)); |
||||
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 |
||||
* |
||||
*/ |
||||
|
||||
/**
|
||||
* @brief Begin watching mtab and fstab |
||||
* @return #EINA_TRUE if watching was started, else #EINA_FALSE |
||||
* |
||||
* This function creates inotify watches on /etc/mtab and /etc/fstab and watches |
||||
* them for changes. This function should be used when expecting a lot of disk |
||||
* mounting/unmounting while you need disk data since it will automatically update |
||||
* certain necessary data instead of waiting. |
||||
* @see eeze_mount_mtab_scan, eeze_mount_fstab_scan |
||||
*/ |
||||
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; |
||||
} |
||||
|
||||
/**
|
||||
* @brief Stop watching /etc/fstab and /etc/mtab |
||||
* |
||||
* This function stops watching fstab and mtab. Data obtained previously will be saved. |
||||
*/ |
||||
EAPI void |
||||
eeze_mount_tabs_unwatch(void) |
||||
{ |
||||
if (!_watching) |
||||
return; |
||||
|
||||
ecore_file_monitor_del(_mtab_mon); |
||||