diff options
Diffstat (limited to 'src/bin')
-rw-r--r-- | src/bin/Makefile.am | 49 | ||||
-rw-r--r-- | src/bin/eeze_disk_ls.c | 53 | ||||
-rw-r--r-- | src/bin/eeze_mount.c | 130 | ||||
-rw-r--r-- | src/bin/eeze_scanner.c | 453 | ||||
-rw-r--r-- | src/bin/eeze_scanner.h | 33 | ||||
-rw-r--r-- | src/bin/eeze_udev_test.c | 238 | ||||
-rw-r--r-- | src/bin/eeze_umount.c | 113 |
7 files changed, 1069 insertions, 0 deletions
diff --git a/src/bin/Makefile.am b/src/bin/Makefile.am new file mode 100644 index 0000000..280006d --- /dev/null +++ b/src/bin/Makefile.am @@ -0,0 +1,49 @@ +MAINTAINERCLEANFILES = Makefile.in + +EEZE_CFLAGS = \ +-I$(top_srcdir)/src/lib \ +@EEZE_CFLAGS@ + +noinst_PROGRAMS = @EEZE_UDEV_TEST_PRG@ +EXTRA_PROGRAMS = eeze_udev_test eeze_mount eeze_umount eeze_disk_ls eeze_scanner + +if HAVE_EEZE_MOUNT + DISK_PROGS = @EEZE_MOUNT_PRG@ @EEZE_UMOUNT_PRG@ @EEZE_DISK_LS_PRG@ + SCAN_PROGS = @EEZE_SCANNER_PRG@ +else + DISK_PROGS = + SCAN_PROGS = +endif + +bin_PROGRAMS = $(DISK_PROGS) +util_PROGRAMS = $(SCAN_PROGS) +utildir = $(bindir) + +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_LIBS@ @ECORE_FILE_LIBS@ @EEZE_LIBS@ + + 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_LIBS@ @ECORE_FILE_LIBS@ @EEZE_LIBS@ + + 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_LIBS@ @ECORE_FILE_LIBS@ @EEZE_LIBS@ + + eeze_scanner_SOURCES = eeze_scanner.c + eeze_scanner_CFLAGS = -I$(top_srcdir)/src/lib $(EEZE_CFLAGS) @LIBMOUNT_CFLAGS@ @ECORE_FILE_CFLAGS@ @ECORE_CON_CFLAGS@ @EET_CFLAGS@ + eeze_scanner_LDADD = $(top_builddir)/src/lib/libeeze.la @LIBMOUNT_LIBS@ @ECORE_FILE_LIBS@ @ECORE_CON_LIBS@ @EET_LIBS@ @EEZE_LIBS@ + includesdir = $(includedir)/eeze-@VMAJ@ + includes_HEADERS = eeze_scanner.h + +setuid_root_mode = a=rx,u+xs +install-data-hook: + @chmod $(setuid_root_mode) $(DESTDIR)$(bindir)/eeze_scanner$(EXEEXT) || true + +endif diff --git a/src/bin/eeze_disk_ls.c b/src/bin/eeze_disk_ls.c new file mode 100644 index 0000000..46c4006 --- /dev/null +++ b/src/bin/eeze_disk_ls.c @@ -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 mountable 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; +} diff --git a/src/bin/eeze_mount.c b/src/bin/eeze_mount.c new file mode 100644 index 0000000..1f1c561 --- /dev/null +++ b/src/bin/eeze_mount.c @@ -0,0 +1,130 @@ +#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_STORE_TRUE('v', "verbose", "Enable debug output"), + 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 = NULL; + Eina_Bool verbose = EINA_FALSE, exit_option = EINA_FALSE; + Eeze_Disk *disk; + + Ecore_Getopt_Value values[] = + { + ECORE_GETOPT_VALUE_BOOL(verbose), + 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); + } + if (verbose) eina_log_domain_level_set("eeze_disk", EINA_LOG_LEVEL_DBG); + 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 ((args == argc - 1) && (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 - args > 1) + { + eeze_disk_mount_point_set(disk, mount_point); + if (eina_str_has_extension(dev, "iso")) + { + int f; + f = eeze_disk_mountopts_get(disk); + eeze_disk_mountopts_set(disk, f | EEZE_DISK_MOUNTOPT_LOOP); + } + } + 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); + eeze_disk_mountopts_get(disk); + if (!eeze_disk_mount(disk)) + { + const char *mp; + + mp = eeze_disk_mount_point_get(disk); + if (!mp) fprintf(stderr, "No mount point passed!\n"); + else fprintf(stderr, "Mount operation could not be started!\n"); + exit(1); + } + ecore_main_loop_begin(); + + return 0; +} diff --git a/src/bin/eeze_scanner.c b/src/bin/eeze_scanner.c new file mode 100644 index 0000000..2acd736 --- /dev/null +++ b/src/bin/eeze_scanner.c @@ -0,0 +1,453 @@ +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include <Eet.h> +#include <Eeze.h> +#include <Ecore_Con.h> +#include <Eeze_Disk.h> +#include <sys/stat.h> +#include <sys/types.h> +#include <errno.h> +#include <unistd.h> +#include <fcntl.h> + +#include "eeze_scanner.h" + +#define DBG(...) EINA_LOG_DOM_DBG(es_log_dom, __VA_ARGS__) +#define INF(...) EINA_LOG_DOM_INFO(es_log_dom, __VA_ARGS__) +#define WRN(...) EINA_LOG_DOM_WARN(es_log_dom, __VA_ARGS__) +#define ERR(...) EINA_LOG_DOM_ERR(es_log_dom, __VA_ARGS__) +#define CRI(...) EINA_LOG_DOM_CRIT(es_log_dom, __VA_ARGS__) + +static int es_log_dom = -1; +static Ecore_Con_Server *svr = NULL; +static Eet_Data_Descriptor *es_edd = NULL; +static Eina_Hash *clients = NULL; + +static Eina_List *storage_devices = NULL; +static Eina_List *storage_cdrom = NULL; + +static Eina_List *volume_cdrom = NULL; +static Eina_List *volume_devices = NULL; + +static void +event_send(const char *device, Eeze_Scanner_Event_Type type, Eina_Bool volume) +{ + Eeze_Scanner_Event ev; + const Eina_List *l; + Ecore_Con_Client *cl; + + ev.device = device; + ev.type = type; + ev.volume = volume; + EINA_LIST_FOREACH(ecore_con_server_clients_get(svr), l, cl) + { + Eet_Connection *ec; + + ec = eina_hash_find(clients, cl); + if (!ec) continue; + INF("Serializing event..."); + eet_connection_send(ec, es_edd, &ev, NULL); + } +} + +static Eina_Bool +event_write(const void *data, size_t size, Ecore_Con_Client *cl) +{ + INF("Event sent!"); + ecore_con_client_send(cl, data, size); + return EINA_TRUE; +} + +static Eina_Bool +disk_mount(void *data __UNUSED__, int type __UNUSED__, Eeze_Disk *disk) +{ + Eina_List *l; + Eeze_Scanner_Device *d; + if (eeze_disk_type_get(disk) != EEZE_DISK_TYPE_CDROM) return ECORE_CALLBACK_RENEW; + + EINA_LIST_FOREACH(storage_cdrom, l, d) + { + if (d->device == eeze_disk_syspath_get(disk)) + { + d->mounted = !d->mounted; + break; + } + } + return ECORE_CALLBACK_RENEW; +} + +static void +cl_setup(Ecore_Con_Client *cl __UNUSED__, Eet_Connection *ec) +{ + Eina_List *l; + Eeze_Scanner_Device *dev; + Eeze_Scanner_Event ev; + const char *sys; + + INF("Sending initial events to new client"); + EINA_LIST_FOREACH(storage_devices, l, sys) + { + ev.device = sys; + ev.type = EEZE_SCANNER_EVENT_TYPE_ADD; + ev.volume = EINA_FALSE; + eet_connection_send(ec, es_edd, &ev, NULL); + } + EINA_LIST_FOREACH(storage_cdrom, l, dev) + { + ev.device = dev->device; + ev.type = EEZE_SCANNER_EVENT_TYPE_ADD; + ev.volume = EINA_FALSE; + eet_connection_send(ec, es_edd, &ev, NULL); + } + EINA_LIST_FOREACH(volume_devices, l, sys) + { + ev.device = sys; + ev.type = EEZE_SCANNER_EVENT_TYPE_ADD; + ev.volume = EINA_TRUE; + eet_connection_send(ec, es_edd, &ev, NULL); + } + EINA_LIST_FOREACH(volume_cdrom, l, dev) + { + ev.device = dev->device; + ev.type = EEZE_SCANNER_EVENT_TYPE_ADD; + ev.volume = EINA_TRUE; + eet_connection_send(ec, es_edd, &ev, NULL); + } +} + +static Eina_Bool +es_read(const void *eet_data __UNUSED__, size_t size __UNUSED__, void *user_data __UNUSED__) +{ + return EINA_TRUE; +} + +static Eina_Bool +cl_add(void *data __UNUSED__, int type __UNUSED__, Ecore_Con_Event_Client_Add *ev) +{ + Eet_Connection *ec; + INF("Added client"); + + ec = eet_connection_new(es_read, (Eet_Write_Cb*)event_write, ev->client); + if (!ec) + { + ERR("Could not create eet serializer! Lost client!"); + ecore_con_client_del(ev->client); + return ECORE_CALLBACK_RENEW; + } + + eina_hash_direct_add(clients, ev->client, ec); + cl_setup(ev->client, ec); + return ECORE_CALLBACK_RENEW; +} + +static Eina_Bool +cl_del(void *data __UNUSED__, int type __UNUSED__, Ecore_Con_Event_Client_Del *ev) +{ + Eet_Connection *ec; + Eina_Bool d; + INF("Removed client"); + ec = eina_hash_find(clients, ev->client); + if (ec) + { + eet_connection_close(ec, &d); + eina_hash_del_by_data(clients, ec); + } + + return ECORE_CALLBACK_RENEW; +} + +static void +eet_setup(void) +{ + Eet_Data_Descriptor_Class eddc; + + if (!eet_eina_stream_data_descriptor_class_set(&eddc, sizeof(eddc), "eeze_scanner_event", sizeof(Eeze_Scanner_Event))) + { + CRI("Could not create eet data descriptor!"); + exit(1); + } + + es_edd = eet_data_descriptor_stream_new(&eddc); +#define DAT(MEMBER, TYPE) EET_DATA_DESCRIPTOR_ADD_BASIC(es_edd, Eeze_Scanner_Event, #MEMBER, MEMBER, EET_T_##TYPE) + DAT(device, INLINED_STRING); + DAT(type, UINT); + DAT(volume, UCHAR); +#undef DAT +} + +static Eina_Bool +cdrom_timer(Eeze_Scanner_Device *dev) +{ + const char *devpath; + int fd; + + /* cdrom already mounted, no need to poll */ + if (dev->mounted) return EINA_TRUE; + devpath = eeze_udev_syspath_get_devpath(dev->device); + fd = open(devpath, O_RDONLY); + if (fd < 0) + { + Eina_List *l; + + l = eina_list_data_find_list(volume_cdrom, dev); + if (l) + { + /* disc removed, delete volume */ + INF("Removed cdrom '%s'", dev->device); + volume_cdrom = eina_list_remove_list(volume_cdrom, l); + event_send(dev->device, EEZE_SCANNER_EVENT_TYPE_CHANGE, EINA_TRUE); + } + /* just in case */ + dev->mounted = EINA_FALSE; + } + else + { + if (!eina_list_data_find(volume_cdrom, dev)) + { + INF("Added cdrom '%s'", dev->device); + volume_cdrom = eina_list_append(volume_cdrom, dev); + event_send(dev->device, EEZE_SCANNER_EVENT_TYPE_CHANGE, EINA_TRUE); + } + close(fd); + } + eina_stringshare_del(devpath); + return EINA_TRUE; +} + +static void +storage_setup(void) +{ + Eina_List *l, *ll; + const char *sys; + + storage_devices = eeze_udev_find_by_type(EEZE_UDEV_TYPE_DRIVE_INTERNAL, NULL); + if (!storage_devices) + { + ERR("No storage devices found! This is not supposed to happen!"); + exit(1); + } + EINA_LIST_FOREACH(storage_devices, l, sys) + event_send(sys, EEZE_SCANNER_EVENT_TYPE_ADD, EINA_FALSE); + + ll = eeze_udev_find_by_type(EEZE_UDEV_TYPE_DRIVE_REMOVABLE, NULL); + EINA_LIST_FREE(ll, sys) + { + event_send(sys, EEZE_SCANNER_EVENT_TYPE_ADD, EINA_FALSE); + storage_devices = eina_list_append(storage_devices, sys); + } + + l = eeze_udev_find_by_type(EEZE_UDEV_TYPE_DRIVE_CDROM, NULL); + EINA_LIST_FREE(l, sys) + { + Eeze_Scanner_Device *dev; + Eeze_Disk *disk; + + dev = calloc(1, sizeof(Eeze_Scanner_Device)); + if (!dev) + { + ERR("Lost cdrom device '%s'!", sys); + eina_stringshare_del(sys); + continue; + } + disk = eeze_disk_new(sys); + if (!disk) + { + ERR("Lost cdrom device '%s'!", sys); + eina_stringshare_del(sys); + free(dev); + continue; + } + dev->device = sys; + dev->mounted = eeze_disk_mounted_get(disk); + eeze_disk_free(disk); + event_send(sys, EEZE_SCANNER_EVENT_TYPE_ADD, EINA_FALSE); + dev->poller = ecore_poller_add(ECORE_POLLER_CORE, 32, (Ecore_Task_Cb)cdrom_timer, dev); + storage_cdrom = eina_list_append(storage_cdrom, dev); + } + volume_devices = eeze_udev_find_by_type(EEZE_UDEV_TYPE_DRIVE_MOUNTABLE, NULL); + EINA_LIST_FOREACH_SAFE(volume_devices, l, ll, sys) + { + Eina_List *c; + Eeze_Scanner_Device *dev; + + EINA_LIST_FOREACH(storage_cdrom, c, dev) + if (sys == dev->device) + { + eina_stringshare_del(sys); + volume_devices = eina_list_remove_list(volume_devices, l); + volume_cdrom = eina_list_append(volume_cdrom, dev); + event_send(sys, EEZE_SCANNER_EVENT_TYPE_ADD, EINA_TRUE); + l = NULL; + break; + } + if (!l) continue; + event_send(sys, EEZE_SCANNER_EVENT_TYPE_ADD, EINA_TRUE); + } +} + +static void +cb_vol_chg(const char *device, Eeze_Udev_Event ev, void *data __UNUSED__, Eeze_Udev_Watch *watch __UNUSED__) +{ + Eina_List *l; + Eeze_Scanner_Device *dev; + + DBG("device='%s'", device); + + if (ev == EEZE_UDEV_EVENT_ONLINE) ev = EEZE_SCANNER_EVENT_TYPE_ADD; + else if (ev == EEZE_UDEV_EVENT_OFFLINE) ev = EEZE_SCANNER_EVENT_TYPE_REMOVE; + + event_send(device, ev, EINA_TRUE); + switch (ev) + { + case EEZE_UDEV_EVENT_ADD: + case EEZE_UDEV_EVENT_ONLINE: + INF("Added volume '%s'", device); + EINA_LIST_FOREACH(storage_cdrom, l, dev) + if (device == dev->device) + { + volume_cdrom = eina_list_append(volume_cdrom, dev); + return; + } + volume_devices = eina_list_append(volume_devices, eina_stringshare_add(device)); + break; + case EEZE_UDEV_EVENT_REMOVE: + case EEZE_UDEV_EVENT_OFFLINE: + INF("Removed volume '%s'", device); + EINA_LIST_FOREACH(volume_cdrom, l, dev) + if (device == dev->device) + { + volume_cdrom = eina_list_remove_list(volume_cdrom, l); + return; + } + volume_devices = eina_list_remove(volume_devices, device); + eina_stringshare_del(device); + break; + default: + INF("Changed volume '%s'", device); + break; + } +} + +static void +cb_stor_chg(const char *device, Eeze_Udev_Event ev, void *data __UNUSED__, Eeze_Udev_Watch *watch __UNUSED__) +{ + Eina_List *l; + Eeze_Scanner_Device *dev = NULL; + const char *str; + + + DBG("device='%s'", device); + switch (ev) + { + case EEZE_UDEV_EVENT_ADD: + case EEZE_UDEV_EVENT_ONLINE: + INF("Added device '%s'", device); + event_send(device, ev, EINA_FALSE); + str = eeze_udev_syspath_get_property(device, "ID_CDROM"); + if (!str) + { + storage_devices = eina_list_append(storage_devices, eina_stringshare_add(device)); + return; + } + eina_stringshare_del(str); + dev = calloc(1, sizeof(Eeze_Scanner_Device)); + dev->device = eina_stringshare_add(device); + dev->poller = ecore_poller_add(ECORE_POLLER_CORE, 32, + (Ecore_Task_Cb)cdrom_timer, dev); + storage_cdrom = eina_list_append(storage_cdrom, dev); + break; + case EEZE_UDEV_EVENT_REMOVE: + case EEZE_UDEV_EVENT_OFFLINE: + if (!eina_list_data_find(storage_devices, device)) + { + EINA_LIST_FOREACH(storage_cdrom, l, dev) + if (dev->device == device) break; + if ((!dev) || (dev->device != device)) return; + } + INF("Removed device '%s'", device); + event_send(device, ev, EINA_FALSE); + EINA_LIST_FOREACH(storage_cdrom, l, dev) + if (device == dev->device) + { + if (dev->poller) ecore_poller_del(dev->poller); + storage_cdrom = eina_list_remove_list(storage_cdrom, l); + eina_stringshare_del(dev->device); + free(dev); + return; + } + storage_devices = eina_list_remove(storage_devices, device); + eina_stringshare_del(device); + break; + default: + INF("Changed device '%s'", device); + break; + } +} + +static void +es_exit(int sig) +{ + ecore_con_server_del(svr); + exit(sig); +} + +static void +sigs_setup(void) +{ + sigset_t sigs = {{0}}; + struct sigaction s; + + sigfillset(&sigs); + sigdelset(&sigs, SIGSEGV); + sigdelset(&sigs, SIGTERM); + sigdelset(&sigs, SIGINT); + sigdelset(&sigs, SIGQUIT); + + s.sa_handler = es_exit; + s.sa_flags = 0; + sigaction(SIGTERM, &s, NULL); + sigaction(SIGSEGV, &s, NULL); + sigaction(SIGINT, &s, NULL); +} + +int +main(void) +{ + eina_init(); + ecore_init(); + ecore_con_init(); + eeze_init(); + eeze_disk_function(); + eeze_mount_tabs_watch(); + + sigs_setup(); + es_log_dom = eina_log_domain_register("eeze_scanner", EINA_COLOR_CYAN); + + eet_setup(); + clients = eina_hash_pointer_new(NULL); + EINA_SAFETY_ON_NULL_GOTO(clients, error); + + ecore_event_handler_add(ECORE_CON_EVENT_CLIENT_ADD, (Ecore_Event_Handler_Cb)cl_add, NULL); + ecore_event_handler_add(ECORE_CON_EVENT_CLIENT_DEL, (Ecore_Event_Handler_Cb)cl_del, NULL); + ecore_event_handler_add(EEZE_EVENT_DISK_UNMOUNT, (Ecore_Event_Handler_Cb)disk_mount, NULL); + ecore_event_handler_add(EEZE_EVENT_DISK_MOUNT, (Ecore_Event_Handler_Cb)disk_mount, NULL); + + eeze_udev_watch_add(EEZE_UDEV_TYPE_DRIVE_INTERNAL, EEZE_UDEV_EVENT_NONE, cb_stor_chg, NULL); + eeze_udev_watch_add(EEZE_UDEV_TYPE_DRIVE_REMOVABLE, EEZE_UDEV_EVENT_NONE, cb_stor_chg, NULL); + eeze_udev_watch_add(EEZE_UDEV_TYPE_DRIVE_CDROM, EEZE_UDEV_EVENT_NONE, cb_stor_chg, NULL); + eeze_udev_watch_add(EEZE_UDEV_TYPE_DRIVE_MOUNTABLE, EEZE_UDEV_EVENT_NONE, cb_vol_chg, NULL); + + svr = ecore_con_server_add(ECORE_CON_LOCAL_SYSTEM, "eeze_scanner", 0, NULL); + EINA_SAFETY_ON_NULL_GOTO(svr, error); + + storage_setup(); + ecore_main_loop_begin(); + + ecore_con_server_del(svr); + return 0; +error: + ERR("Could not start up!"); + exit(1); +} diff --git a/src/bin/eeze_scanner.h b/src/bin/eeze_scanner.h new file mode 100644 index 0000000..a975793 --- /dev/null +++ b/src/bin/eeze_scanner.h @@ -0,0 +1,33 @@ +#ifndef EEZE_SCANNER_H +#define EEZE_SCANNER_H + +#include <Eeze.h> + +#define EEZE_SCANNER_EDD_SETUP(edd) \ + EET_DATA_DESCRIPTOR_ADD_BASIC((edd), Eeze_Scanner_Event, "device", device, EET_T_INLINED_STRING); \ + EET_DATA_DESCRIPTOR_ADD_BASIC((edd), Eeze_Scanner_Event, "type", type, EET_T_UINT); \ + EET_DATA_DESCRIPTOR_ADD_BASIC((edd), Eeze_Scanner_Event, "volume", volume, EET_T_UCHAR) + +typedef enum +{ + EEZE_SCANNER_EVENT_TYPE_NONE, + EEZE_SCANNER_EVENT_TYPE_ADD = EEZE_UDEV_EVENT_ADD, + EEZE_SCANNER_EVENT_TYPE_REMOVE = EEZE_UDEV_EVENT_REMOVE, + EEZE_SCANNER_EVENT_TYPE_CHANGE = EEZE_UDEV_EVENT_CHANGE +} Eeze_Scanner_Event_Type; + +typedef struct +{ + const char *device; + Eeze_Scanner_Event_Type type; + Eina_Bool volume; +} Eeze_Scanner_Event; + +typedef struct +{ + Ecore_Poller *poller; + const char *device; + Eina_Bool mounted; +} Eeze_Scanner_Device; + +#endif diff --git a/src/bin/eeze_udev_test.c b/src/bin/eeze_udev_test.c new file mode 100644 index 0000000..130771a --- /dev/null +++ b/src/bin/eeze_udev_test.c @@ -0,0 +1,238 @@ +#include <Eeze.h> +#include <Ecore.h> +#include <stdio.h> + +/** + * This demo program shows how to use some eeze_udev functions. It roughly + * 1kb as of now, TODO is to fix this but I'm too lazy now and it's only + * a demo. + */ + +typedef struct kbdmouse +{ + Eina_List *kbds; + Eina_List *mice; + Eina_Hash *hash; +} kbdmouse; + +static void +/* event will always be a syspath starting with /sys */ +catch_events(const char *device, + Eeze_Udev_Event event, + void *data, + Eeze_Udev_Watch *watch) +{ + kbdmouse *akbdmouse = data; + Eina_List *l; + const char *name, *dev, *type; + + /* the device that comes through will be prefixed by "/sys" + * but the saved name will not, so we check for the saved name + * inside the device name + */ + EINA_LIST_FOREACH(akbdmouse->kbds, l, name) + if (!strncmp(device + 5, name, strlen(device + 5) - 8)) goto end; + EINA_LIST_FOREACH(akbdmouse->mice, l, name) + if (!strncmp(device + 5, name, strlen(device + 5) - 8)) goto end; + + /* check to see if the device was just plugged in */ + if (eeze_udev_syspath_is_kbd(device) || eeze_udev_syspath_is_mouse(device)) + goto end; + /* if we reach here, the device is neither a keyboard nor a mouse that we saw + * previously, so we print a moderately amusing message and bail + */ + printf("Sneaky sneaky! But %s is not a keyboard or a mouse!!\n", device); + return; + +end: + /* we stored the devpaths for all the syspaths previously so that + * we can retrieve them now even though the device has been removed and + * is inaccessible to udev + */ + if ((event & EEZE_UDEV_EVENT_ADD) == EEZE_UDEV_EVENT_ADD) + { + dev = eeze_udev_syspath_get_devpath(device); + type = "plugged in"; + } + else + { + dev = eina_hash_find(akbdmouse->hash, name); + type = "unplugged"; + } + printf("You %s %s!\n", type, dev); + printf("All tests completed, exiting successfully!\n"); + /* and the hash */ + eina_hash_free(akbdmouse->hash); + /* now we free the lists */ + eina_list_free(akbdmouse->kbds); + eina_list_free(akbdmouse->mice); + /* and the random storage struct */ + free(akbdmouse); + /* and delete the watch */ + eeze_udev_watch_del(watch); + /* and shut down eudev */ + eeze_shutdown(); + /* and quit the main loop */ + ecore_main_loop_quit(); +} + +static void +hash_free(void *data) +{ + eina_stringshare_del(data); +} + +int +main() +{ + Eina_List *type, *l; + const char *name, *check, *check2; + kbdmouse *akbdmouse; + Eina_Hash *hash; + + ecore_init(); + eeze_init(); + + hash = eina_hash_stringshared_new(hash_free); + akbdmouse = malloc(sizeof(kbdmouse)); + akbdmouse->hash = hash; + + printf("For my first trick, I will find all of your keyboards and return their syspaths.\n"); + /* find all keyboards using type EEZE_UDEV_TYPE_KEYBOARD */ + type = eeze_udev_find_by_type(EEZE_UDEV_TYPE_KEYBOARD, NULL); + /* add all "link" devices that aren't explicitly found, but are still + * part of the device chain + */ + type = eeze_udev_find_unlisted_similar(type); + EINA_LIST_FOREACH(type, l, name) + { + /* add the devpath to the hash for use in the cb later */ + if ((check = eeze_udev_syspath_get_devpath(name))) + eina_hash_direct_add(hash, name, check); + printf("Found keyboard: %s\n", name); + } + /* we save this list for later, because once a device is unplugged it can + * no longer be detected by udev, and any related properties are unusable unless + * they have been previously stored + */ + akbdmouse->kbds = type; + + printf("\nNext, I will find all of your mice and print the corresponding manufacturer.\n"); + /* find all mice using type EEZE_UDEV_TYPE_MOUSE */ + type = eeze_udev_find_by_type(EEZE_UDEV_TYPE_MOUSE, NULL); + type = eeze_udev_find_unlisted_similar(type); + EINA_LIST_FOREACH(type, l, name) + { /* add the devpath to the hash for use in the cb later */ + if ((check = eeze_udev_syspath_get_devpath(name))) + eina_hash_direct_add(hash, name, check); /* get a property using the device's syspath */ + printf("Found mouse %s with vendor: %s\n", name, eeze_udev_walk_get_sysattr(name, "manufacturer")); + } + /* we save this list for later, because once a device is unplugged it can + * no longer be detected by udev, and any related properties are unusable unless + * they have been previously stored + */ + akbdmouse->mice = type; + + printf("\nNow let's try something a little more difficult. Mountable filesystems!\n"); + /* find all mountable drives using type EEZE_UDEV_TYPE_DRIVE_MOUNTABLE */ + type = eeze_udev_find_by_type(EEZE_UDEV_TYPE_DRIVE_MOUNTABLE, NULL); + type = eeze_udev_find_unlisted_similar(type); + EINA_LIST_FREE(type, name) + { + printf("Found device: %s\n", name); /* get a property using the device's syspath */ + if ((check = eeze_udev_syspath_get_property(name, "DEVNAME"))) + { + printf("\tYou probably know it better as %s\n", check); + eina_stringshare_del(check); + } + if ((check = eeze_udev_syspath_get_property(name, "ID_FS_TYPE"))) + { + printf("\tIt's formatted as %s", check); + eina_stringshare_del(check); + check = eeze_udev_syspath_get_property(name, "FSTAB_DIR"); + if (check) + { + printf(", and gets mounted at %s", check); + eina_stringshare_del(check); + } + printf("!\n"); + } + eina_stringshare_del(name); + } + + printf("\nNetwork devices!\n"); + type = eeze_udev_find_by_type(EEZE_UDEV_TYPE_NET, NULL); + type = eeze_udev_find_unlisted_similar(type); + EINA_LIST_FREE(type, name) + { + printf("Found device: %s\n", name); /* get a property using the device's syspath */ + if ((check = eeze_udev_syspath_get_property(name, "INTERFACE"))) + { + printf("\tYou probably know it better as %s\n", check); + eina_stringshare_del(check); + } + eina_stringshare_del(name); + } + + printf("\nInternal drives, anyone? With serial numbers?\n"); + /* find all internal drives using type EEZE_UDEV_TYPE_DRIVE_INTERNAL */ + type = eeze_udev_find_by_type(EEZE_UDEV_TYPE_DRIVE_INTERNAL, NULL); + type = eeze_udev_find_unlisted_similar(type); + EINA_LIST_FREE(type, name) /* get a property using the device's syspath */ + { + if ((check = eeze_udev_syspath_get_property(name, "ID_SERIAL"))) + { + printf("%s: %s\n", name, check); + eina_stringshare_del(check); + } + eina_stringshare_del(name); + } + + printf("\nGot any removables? I'm gonna find em!\n"); + /* find all removable media using type EEZE_UDEV_TYPE_DRIVE_REMOVABLE */ + type = eeze_udev_find_by_type(EEZE_UDEV_TYPE_DRIVE_REMOVABLE, NULL); + type = eeze_udev_find_unlisted_similar(type); + EINA_LIST_FREE(type, name) /* get a property using the device's syspath */ + { + if ((check = eeze_udev_syspath_get_sysattr(name, "model"))) + { + check2 = eeze_udev_syspath_get_subsystem(name); + printf("\tOoh, a %s attached to the %s subsytem!\n", check, check2); + eina_stringshare_del(check); + eina_stringshare_del(check2); + } + eina_stringshare_del(name); + } + + printf("\nGot any v4l device ?\n"); + /* find all V4L device, may be a webcam or anything that can get a video + * stream from the real worl in a numerical form */ + type = eeze_udev_find_by_type(EEZE_UDEV_TYPE_V4L, NULL); + type = eeze_udev_find_unlisted_similar(type); + EINA_LIST_FREE(type, name) /* get a device name using the device's syspath */ + { + if ((check = eeze_udev_syspath_get_property(name, "DEVNAME"))) + { + if ((check2 = eeze_udev_syspath_get_sysattr(name, "name"))) + { + printf("%s: '%s' [%s]\n", name, check2, check); + eina_stringshare_del(check2); + } + eina_stringshare_del(check); + } + eina_stringshare_del(name); + } + + /* set a udev watch, grab all events because no EEZE_UDEV_TYPE filter is specified, + * set the events to be sent to callback function catch_events(), and attach + * kbdmouse to the watch as associated data + */ + eeze_udev_watch_add(EEZE_UDEV_TYPE_NONE, (EEZE_UDEV_EVENT_ADD | EEZE_UDEV_EVENT_REMOVE), catch_events, akbdmouse); + printf("\nAnd now for something more complicated. Plug or unplug your keyboard or mouse for me.\n"); + + /* main loop must be started to use ecore fd polling */ + ecore_main_loop_begin(); + + return 0; +} + diff --git a/src/bin/eeze_umount.c b/src/bin/eeze_umount.c new file mode 100644 index 0000000..75d5ebb --- /dev/null +++ b/src/bin/eeze_umount.c @@ -0,0 +1,113 @@ +#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_STORE_TRUE('v', "verbose", "Enable debug output"), + 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 verbose = EINA_FALSE, exit_option = EINA_FALSE; + Eeze_Disk *disk; + + Ecore_Getopt_Value values[] = + { + ECORE_GETOPT_VALUE_BOOL(verbose), + 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); + } + if (verbose) eina_log_domain_level_set("eeze_disk", EINA_LOG_LEVEL_DBG); + dev = argv[args]; + if ((!strncmp(dev, "/sys/", 5)) || (!strncmp(dev, "/dev/", 5))) + disk = eeze_disk_new(dev); + else if ((args == argc - 1) && (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; +} |