summaryrefslogtreecommitdiff
path: root/src/lib/eeze
diff options
context:
space:
mode:
authorGustavo Sverzut Barbieri <barbieri@gmail.com>2013-01-03 20:37:42 +0000
committerGustavo Sverzut Barbieri <barbieri@gmail.com>2013-01-03 20:37:42 +0000
commit68188ac0c89407cb35a0f04f86ad44b0deb95bdb (patch)
tree0ddf76421ab114f162c5a113f65119a6662d6a54 /src/lib/eeze
parentf7cc32f78bf86c804a3f3ae7b8428a408092fbdf (diff)
efl: merge eeze.
Changes also in this commit: * fix missing EAPI in symbols used by modules * removed old libudev and libmount support as agreed by discomfitor/zmike * replaced __UNUSED__ with EINA_UNUSED * fixed docs hierarchy SVN revision: 82100
Diffstat (limited to 'src/lib/eeze')
-rw-r--r--src/lib/eeze/Eeze.h597
-rw-r--r--src/lib/eeze/Eeze_Disk.h571
-rw-r--r--src/lib/eeze/Eeze_Net.h65
-rw-r--r--src/lib/eeze/Eeze_Sensor.h325
-rw-r--r--src/lib/eeze/eeze_disk.c483
-rw-r--r--src/lib/eeze/eeze_disk_libmount.c495
-rw-r--r--src/lib/eeze/eeze_disk_libmount_new.c525
-rw-r--r--src/lib/eeze/eeze_disk_mount.c461
-rw-r--r--src/lib/eeze/eeze_disk_private.h93
-rw-r--r--src/lib/eeze/eeze_disk_udev.c90
-rw-r--r--src/lib/eeze/eeze_main.c123
-rw-r--r--src/lib/eeze/eeze_net.c323
-rw-r--r--src/lib/eeze/eeze_net_private.h53
-rw-r--r--src/lib/eeze/eeze_sensor.c320
-rw-r--r--src/lib/eeze/eeze_sensor_private.h89
-rw-r--r--src/lib/eeze/eeze_udev_find.c384
-rw-r--r--src/lib/eeze/eeze_udev_private.c200
-rw-r--r--src/lib/eeze/eeze_udev_private.h46
-rw-r--r--src/lib/eeze/eeze_udev_syspath.c292
-rw-r--r--src/lib/eeze/eeze_udev_walk.c65
-rw-r--r--src/lib/eeze/eeze_udev_watch.c449
21 files changed, 6049 insertions, 0 deletions
diff --git a/src/lib/eeze/Eeze.h b/src/lib/eeze/Eeze.h
new file mode 100644
index 0000000000..82ef11ae82
--- /dev/null
+++ b/src/lib/eeze/Eeze.h
@@ -0,0 +1,597 @@
1/**
2
3 @brief Eeze Device Library
4
5 @page eeze_main Eeze
6
7 @date 2010 (created)
8
9 @section toc Table of Contents
10
11 @li @ref eeze_main_intro
12 @li @ref eeze_main_compiling
13 @li @ref eeze_main_next_steps
14
15 @section eeze_main_intro Introduction
16
17 Eeze is a library for manipulating devices through udev with a
18 simple and fast api. It interfaces directly with libudev, avoiding
19 such middleman daemons as udisks/upower or hal, to immediately
20 gather device information the instant it becomes known to the
21 system. This can be used to determine such things as:
22
23 @li If a cdrom has a disk inserted
24 @li The temperature of a cpu core
25 @li The remaining power left in a battery
26 @li The current power consumption of various parts
27 @li Monitor in realtime the status of peripheral devices
28
29 Each of the above examples can be performed by using only a single eeze
30 function, as one of the primary focuses of the library is to reduce the
31 complexity of managing devices.
32
33 @section eeze_main_compiling How to compile
34
35 Eeze is a library your application links to. The procedure for this is very
36 simple. You simply have to compile your application with the appropriate
37 compiler flags that the @p pkg-config script outputs. For example:
38
39 Compiling C or C++ files into object files:
40
41 @verbatim
42 gcc -c -o main.o main.c `pkg-config --cflags eeze`
43 @endverbatim
44
45 Linking object files into a binary executable:
46
47 @verbatim
48 gcc -o my_application main.o `pkg-config --libs eeze`
49 @endverbatim
50
51 See @ref pkgconfig
52
53 @section eeze_main_next_steps Next Steps
54
55 After you understood what Eeze is and installed it in your system
56 you should proceed understanding the programming interface. We'd
57 recommend you to take a while to learn @ref Eina and @ref Ecore as
58 they convenient and Eeze provides integration with it.
59
60 Recommended reading:
61
62 @li @link Eeze.h Eeze functions @endlink
63 @li @ref Eeze_Udev UDEV functions
64 @li @ref Eeze_Watch Functions that watch for events
65 @li @ref Eeze_Syspath Functions that accept a device /sys/ path
66 @li @ref Eeze_Find Functions which find types of devices
67 @li @ref Eeze_Disk Disk functions
68 @li @ref Eeze_Net Net functions
69 @li @ref Eeze_Sensor Sensor functions
70
71 */
72#ifndef EEZE_UDEV_H
73#define EEZE_UDEV_H
74
75#include <Eina.h>
76
77#ifdef EAPI
78# undef EAPI
79#endif
80
81#ifdef __GNUC__
82# if __GNUC__ >= 4
83# define EAPI __attribute__ ((visibility("default")))
84# else
85# define EAPI
86# endif
87#else
88# define EAPI
89#endif
90
91/**
92 * @file Eeze.h
93 * @brief Easy device manipulation.
94 *
95 * Eeze is a library for manipulating devices through udev with a simple and fast
96 * api. It interfaces directly with libudev, avoiding such middleman daemons as
97 * udisks/upower or hal, to immediately gather device information the instant it
98 * becomes known to the system. This can be used to determine such things as:
99 * @li If a cdrom has a disk inserted
100 * @li The temperature of a cpu core
101 * @li The remaining power left in a battery
102 * @li The current power consumption of various parts
103 * @li Monitor in realtime the status of peripheral devices
104 * Each of the above examples can be performed by using only a single eeze
105 * function, as one of the primary focuses of the library is to reduce the
106 * complexity of managing devices.
107 *
108 *
109 * For udev functions, see @ref udev.
110 */
111
112/**
113 * @defgroup Eeze_Main main
114 * @ingroup Eeze
115 *
116 * These are general eeze functions which include init and shutdown.
117 */
118
119/**
120 * @defgroup Eeze_Udev udev
121 * @ingroup Eeze_Main
122 *
123 * These are functions which interact directly with udev.
124 */
125
126/**
127 * @addtogroup Eeze_Udev
128 *
129 * These are the device subsystems of udev:
130 * @li ac97
131 * @li acpi
132 * @li bdi
133 * @li block
134 * @li bsg
135 * @li dmi
136 * @li graphics
137 * @li hid
138 * @li hwmon
139 * @li i2c
140 * @li input
141 * @li mem
142 * @li misc
143 * @li net
144 * @li pci
145 * @li pci_bus
146 * @li pci_express
147 * @li platform
148 * @li pnp
149 * @li rtc
150 * @li scsi
151 * @li scsi_device
152 * @li scsi_disk
153 * @li scsi_generic
154 * @li scsi_host
155 * @li serio
156 * @li sound
157 * @li thermal
158 * @li tty
159 * @li usb
160 * @li usb_device
161 * @li vc
162 * @li vtconsole
163 *
164 * These are the devtypes of udev.
165 * @li atapi
166 * @li audio
167 * @li block
168 * @li cd
169 * @li char
170 * @li disk
171 * @li floppy
172 * @li generic
173 * @li hid
174 * @li hub
175 * @li media
176 * @li optical
177 * @li printer
178 * @li rbc
179 * @li scsi
180 * @li storage
181 * @li tape
182 * @li video
183 */
184#ifdef __cplusplus
185extern "C" {
186#endif
187
188/**
189 * @addtogroup Eeze_Udev
190 * @typedef Eeze_Udev_Event
191 * @enum Eeze_Udev_Event
192 * @brief Flags for watch events
193 *
194 * These events are used to specify the events to watch in a
195 * #Eeze_Udev_Watch. They can be ORed together.
196 *@{
197 */
198typedef enum
199{
200 /** - No event specified */
201 EEZE_UDEV_EVENT_NONE = 0xf0,
202 /** - Device added */
203 EEZE_UDEV_EVENT_ADD = (1 << 1),
204 /** - Device removed */
205 EEZE_UDEV_EVENT_REMOVE = (1 << 2),
206 /** - Device changed */
207 EEZE_UDEV_EVENT_CHANGE = (1 << 3),
208 /** - Device has come online */
209 EEZE_UDEV_EVENT_ONLINE = (1 << 4),
210 /** - Device has gone offline */
211 EEZE_UDEV_EVENT_OFFLINE = (1 << 5)
212} Eeze_Udev_Event;
213/** @} */
214
215/**
216 * @addtogroup Eeze_Udev udev
217 * @typedef Eeze_Udev_Type Eeze_Udev_Type
218 * @enum Eeze_Udev_Type
219 * @brief Convenience types to simplify udev access.
220 *
221 * These types allow easy access to certain udev device types. They
222 * may only be used in specified functions.
223 *
224 * @{
225 */
226/*FIXME: these probably need to be bitmasks with categories*/
227typedef enum
228{
229 /** - No type */
230 EEZE_UDEV_TYPE_NONE,
231 /** - Keyboard device */
232 EEZE_UDEV_TYPE_KEYBOARD,
233 /** - Mouse device */
234 EEZE_UDEV_TYPE_MOUSE,
235 /** - Touchpad device */
236 EEZE_UDEV_TYPE_TOUCHPAD,
237 /** - Mountable drive */
238 EEZE_UDEV_TYPE_DRIVE_MOUNTABLE,
239 /** - Internal drive */
240 EEZE_UDEV_TYPE_DRIVE_INTERNAL,
241 /** - Removable drive */
242 EEZE_UDEV_TYPE_DRIVE_REMOVABLE,
243 /** - cd drive */
244 EEZE_UDEV_TYPE_DRIVE_CDROM,
245 /** - AC adapter */
246 EEZE_UDEV_TYPE_POWER_AC,
247 /** - Battery */
248 EEZE_UDEV_TYPE_POWER_BAT,
249 /** - Temperature sensor */
250 EEZE_UDEV_TYPE_IS_IT_HOT_OR_IS_IT_COLD_SENSOR,
251 /** - Network devices */
252 EEZE_UDEV_TYPE_NET,
253 /** - WebCam */
254 EEZE_UDEV_TYPE_V4L,
255 /** - Bluetooth */
256 EEZE_UDEV_TYPE_BLUETOOTH,
257 /** - Joystick
258 * @since 1.7
259 */
260 EEZE_UDEV_TYPE_JOYSTICK
261} Eeze_Udev_Type;
262/**@}*/
263
264struct Eeze_Udev_Watch;
265
266/**
267 * @addtogroup Eeze_Watch
268 * @typedef Eeze_Udev_Watch Eeze_Udev_Watch
269 * @brief Opaque structure to hold data for a udev watch
270 */
271typedef struct Eeze_Udev_Watch Eeze_Udev_Watch;
272
273#define EEZE_VERSION_MAJOR 1
274#define EEZE_VERSION_MINOR 8
275
276 typedef struct _Eeze_Version
277 {
278 int major;
279 int minor;
280 int micro;
281 int revision;
282 } Eeze_Version;
283
284 EAPI extern Eeze_Version *eeze_version;
285
286/**
287 * @addtogroup Eeze_Watch
288 * @typedef Eeze_Udev_Watch_Cb Eeze_Udev_Watch_Cb
289 * @brief Callback type for use with #Eeze_Udev_Watch
290 */
291typedef void(*Eeze_Udev_Watch_Cb)(const char *, Eeze_Udev_Event, void *, Eeze_Udev_Watch *);
292
293
294/**
295 * Initialize the eeze library.
296 * @return The number of times the function has been called, or -1 on failure.
297 *
298 * This function should be called prior to using any eeze functions, and MUST
299 * be called prior to using any udev functions to avoid a segv.
300 *
301 * @ingroup Eeze_Main
302 */
303EAPI int eeze_init(void);
304
305/**
306 * Shut down the eeze library.
307 * @return The number of times the eeze_init has been called, or -1 when
308 * all occurrences of eeze have been shut down.
309 *
310 * This function should be called when no further eeze functions will be called.
311 *
312 * @ingroup Eeze_Main
313 */
314EAPI int eeze_shutdown(void);
315
316 /**
317 * @addtogroup Eeze_Find Find
318 *
319 * These are functions which find/supplement lists of devices.
320 *
321 * @ingroup Eeze_Udev
322 *
323 * @{
324 */
325
326/**
327 * Returns a stringshared list of all syspaths that are (or should be) the same
328 * device as the device pointed at by @p syspath.
329 *
330 * @param syspath The syspath of the device to find matches for
331 * @return All devices which are the same as the one passed
332 */
333EAPI Eina_List *eeze_udev_find_similar_from_syspath(const char *syspath);
334
335/**
336 * Updates a list of all syspaths that are (or should be) the same
337 * device.
338 *
339 * @param list The list of devices to update
340 * @return The updated list
341 *
342 * This function will update @p list to include all devices matching
343 * devices with syspaths currently stored in @p list. All strings are
344 * stringshared.
345 *
346 * @note This is an expensive call, do not use it unless you must.
347 */
348EAPI Eina_List *eeze_udev_find_unlisted_similar(Eina_List *list);
349
350/**
351 * Find a list of devices by a sysattr (and, optionally, a value of that sysattr).
352 *
353 * @param sysattr The attribute to find
354 * @param value Optional: the value that the attribute should have
355 *
356 * @return A stringshared list of the devices found with the attribute
357 *
358 * @ingroup Eeze_Find
359 */
360EAPI Eina_List *eeze_udev_find_by_sysattr(const char *sysattr, const char *value);
361
362/**
363 * Find devices using an #Eeze_Udev_Type and/or a name.
364 *
365 * @param type An #Eeze_Udev_Type or 0
366 * @param name A filter for the device name or @c NULL
367 * @return A stringshared Eina_List of matched devices or @c NULL on failure
368 *
369 * Return a list of syspaths (/sys/$syspath) for matching udev devices.
370 */
371EAPI Eina_List *eeze_udev_find_by_type(Eeze_Udev_Type type, const char *name);
372
373/**
374 * A more advanced find, allows finds using udev properties.
375 *
376 * @param subsystem The udev subsystem to filter by, or @c NULL
377 * @param type "ID_INPUT_KEY", "ID_INPUT_MOUSE", "ID_INPUT_TOUCHPAD", @c NULL, etc
378 * @param name A filter for the device name, or @c NULL
379 * @return A stringshared Eina_List* of matched devices or @c NULL on failure
380 *
381 * Return a list of syspaths (/sys/$syspath) for matching udev devices.
382 * Requires at least one filter.
383 */
384EAPI Eina_List *eeze_udev_find_by_filter(const char *subsystem, const char *type, const char *name);
385 /**
386 * @}
387 */
388
389 /**
390 * @addtogroup Eeze_Syspath Syspath
391 *
392 * These are functions which interact with the syspath (/sys/$PATH) of
393 * a device.
394 *
395 * @ingroup Eeze_Udev
396 *
397 * @{
398 */
399
400/**
401 * Get the syspath of a device from the /dev/ path.
402 *
403 * @param devpath The /dev/ path of the device
404 * @return A stringshared char* which corresponds to the /sys/ path of the device or @c NULL on failure
405 *
406 * Takes "/dev/path" and returns the corresponding /sys/ path (without the "/sys/")
407 */
408EAPI const char *eeze_udev_devpath_get_syspath(const char *devpath);
409
410/**
411 * Find the root device of a device from its syspath.
412 *
413 * @param syspath The syspath of a device, with or without "/sys/"
414 * @return The syspath of the parent device
415 *
416 * Return a stringshared syspath (/sys/$syspath) for the parent device.
417 */
418EAPI const char *eeze_udev_syspath_get_parent(const char *syspath);
419
420/**
421 * Returns a list of all parent device syspaths for @p syspath.
422 *
423 * @param syspath The device to find parents of
424 * @return A stringshared list of the parent devices of @p syspath
425 */
426EAPI Eina_List *eeze_udev_syspath_get_parents(const char *syspath);
427
428/**
429 * Get the /dev/ path from the /sys/ path.
430 *
431 * @param syspath The /sys/ path with or without the /sys/
432 * @return A stringshared char* with the /dev/ path or @c NULL on failure
433 *
434 * Takes /sys/$PATH and turns it into the corresponding "/dev/x/y".
435 */
436EAPI const char *eeze_udev_syspath_get_devpath(const char *syspath);
437
438/**
439 * Get the /dev/ name from the /sys/ path.
440 *
441 * @param syspath The /sys/ path with or without the /sys/
442 * @return A stringshared char* of the device name without the /dev/ path, or @c NULL on failure
443 *
444 * Takes /sys/$PATH and turns it into the corresponding /dev/x/"y".
445 */
446EAPI const char *eeze_udev_syspath_get_devname(const char *syspath);
447
448/**
449 * Get the subsystem of a device from the /sys/ path.
450 *
451 * @param syspath The /sys/ path with or without the /sys/
452 * @return A stringshared char* with the subsystem of the device or @c NULL on failure
453 *
454 * Takes /sys/$PATH and returns the corresponding device subsystem,
455 * such as "input" for keyboards/mice.
456 */
457EAPI const char *eeze_udev_syspath_get_subsystem(const char *syspath);
458
459/**
460 * Get the property value of a device from the /sys/ path.
461 *
462 * @param syspath The /sys/ path with or without the /sys/
463 * @param property The property to get; full list of these is a FIXME
464 * @return A stringshared char* with the property or @c NULL on failure
465 */
466EAPI const char *eeze_udev_syspath_get_property(const char *syspath, const char *property);
467
468/**
469 * Get the sysattr value of a device from the /sys/ path.
470 *
471 * @param syspath The /sys/ path with or without the /sys/
472 * @param sysattr The sysattr to get; full list of these is a FIXME
473 * @return A stringshared char* with the sysattr or @c NULL on failure
474 */
475EAPI const char *eeze_udev_syspath_get_sysattr(const char *syspath, const char *sysattr);
476
477/**
478 * Checks whether the device is a mouse.
479 *
480 * @param syspath The /sys/ path with or without the /sys/
481 * @return If true, the device is a mouse
482 */
483EAPI Eina_Bool eeze_udev_syspath_is_mouse(const char *syspath);
484
485/**
486 * Checks whether the device is a keyboard.
487 *
488 * @param syspath The /sys/ path with or without the /sys/
489 * @return If true, the device is a keyboard
490 */
491EAPI Eina_Bool eeze_udev_syspath_is_kbd(const char *syspath);
492
493/**
494 * Checks whether the device is a touchpad.
495 *
496 * @param syspath The /sys/ path with or without the /sys/
497 * @return If true, the device is a touchpad
498 */
499EAPI Eina_Bool eeze_udev_syspath_is_touchpad(const char *syspath);
500
501/**
502 * Checks whether the device is a joystick.
503 *
504 * @param syspath The /sys/ path with or without the /sys/
505 * @return If true, the device is a joystick
506 * @since 1.7
507 */
508EAPI Eina_Bool eeze_udev_syspath_is_joystick(const char *syspath);
509 /**
510 * @}
511 */
512
513 /**
514 * @addtogroup Eeze_Walks Walks
515 *
516 * These are functions which walk up the device chain.
517 *
518 * @ingroup Eeze_Udev
519 *
520 * @{
521 */
522
523/**
524 * Walks up the device chain starting at @p syspath,
525 * checking each device for @p sysattr with (optional) @p value.
526 *
527 * @param syspath The /sys/ path of the device to start at, with or without the /sys/
528 * @param sysattr The attribute to find
529 * @param value OPTIONAL: The value that @p sysattr should have, or @c NULL
530 *
531 * @return If the sysattr (with value) is found, returns TRUE. Else, false.
532 */
533EAPI Eina_Bool eeze_udev_walk_check_sysattr(const char *syspath, const char *sysattr, const char *value);
534
535/**
536 * Walks up the device chain starting at @p syspath,
537 * checking each device for @p sysattr, and returns the value if found.
538 *
539 * @param syspath The /sys/ path of the device to start at, with or without the /sys/
540 * @param sysattr The attribute to find
541 *
542 * @return The stringshared value of @p sysattr if found, or @c NULL
543 */
544EAPI const char *eeze_udev_walk_get_sysattr(const char *syspath, const char *sysattr);
545 /**
546 * @}
547 */
548
549 /**
550 * @addtogroup Eeze_Watch Watch
551 *
552 * @brief These are functions which monitor udev for events.
553 *
554 * Eeze watches are simple: you specify a type of device to watch (or all devices), some events (or all) to watch for, a callback,
555 * and some data, and then udev watches those device types for events of the type you specified. Your callback is called with a
556 * syspath of the triggering device and the event that happened to the device, along with the data you associated with the watch and
557 * the watch object itself in case you want to stop the watch easily in a callback.
558 *
559 * @ingroup Eeze_Udev
560 *
561 * @{
562 */
563
564/**
565 * Add a watch for a device type
566 *
567 * @param type The #Eeze_Udev_Type to watch
568 * @param event The events to watch; an OR list of #Eeze_Udev_Event (ie (#EEZE_UDEV_EVENT_ADD | #EEZE_UDEV_EVENT_REMOVE)), or 0 for all events
569 * @param cb The function to call when the watch receives data of type #Eeze_Udev_Watch_Cb
570 * @param user_data Data to pass to the callback function
571 *
572 * @return A watch struct for the watch type specified, or @c NULL on failure
573 *
574 * Eeze watches will monitor udev for changes of type(s) @p event to devices of type @p type. When these changes occur, the stringshared
575 * syspath of the device will be sent to function @p func, along with the bitmask of the event type which can be detected through
576 * binary &.
577 */
578EAPI Eeze_Udev_Watch *eeze_udev_watch_add(Eeze_Udev_Type type, int event, Eeze_Udev_Watch_Cb cb, void *user_data);
579
580/**
581 * Deletes a watch.
582 *
583 * @param watch An Eeze_Udev_Watch object
584 * @return The data originally associated with the watch, or @c NULL
585 *
586 * Deletes a watch, closing file descriptors and freeing related udev memory.
587 */
588EAPI void *eeze_udev_watch_del(Eeze_Udev_Watch *watch);
589 /**
590 * @}
591 */
592
593#ifdef __cplusplus
594}
595#endif
596
597#endif
diff --git a/src/lib/eeze/Eeze_Disk.h b/src/lib/eeze/Eeze_Disk.h
new file mode 100644
index 0000000000..ca131d3f51
--- /dev/null
+++ b/src/lib/eeze/Eeze_Disk.h
@@ -0,0 +1,571 @@
1#ifndef EEZE_DISK_H
2#define EEZE_DISK_H
3
4#ifdef EAPI
5# undef EAPI
6#endif
7
8#ifdef __GNUC__
9# if __GNUC__ >= 4
10# define EAPI __attribute__ ((visibility("default")))
11# else
12# define EAPI
13# endif
14#else
15# define EAPI
16#endif
17
18#include <Eina.h>
19#include <Ecore.h>
20
21/**
22 * @file Eeze_Disk.h
23 * @brief Disk manipulation
24 * @since 1.1
25 *
26 * Eeze disk functions allow you to quickly and efficiently manipulate disks
27 * through simple function calls.
28 *
29 * @defgroup Eeze_Disk Disk
30 * Scan and query information about disks. Manipulate them with moun,
31 * unmount and eject.
32 *
33 * @ingroup Eeze
34 * @{
35 */
36
37#ifdef __cplusplus
38extern "C" {
39#endif
40
41/**
42 * @enum Eeze_Disk_Type
43 * @since 1.1
44 *
45 * All disk types known to Eeze.
46 */
47typedef enum
48{
49 EEZE_DISK_TYPE_UNKNOWN = 0, /**< type could not be determined */
50 EEZE_DISK_TYPE_INTERNAL = (1 << 0), /**< internal drive */
51 EEZE_DISK_TYPE_CDROM = (1 << 1), /**< cdrom drive */
52 EEZE_DISK_TYPE_USB = (1 << 2), /**< usb drive */
53 EEZE_DISK_TYPE_FLASH = (1 << 3) /**< flash disk */
54} Eeze_Disk_Type;
55
56/**
57 * @enum Eeze_Mount_Opts
58 * @since 1.1
59 *
60 * All mount options known to Eeze.
61 */
62typedef enum
63{
64#define EEZE_DISK_MOUNTOPT_DEFAULTS (EEZE_DISK_MOUNTOPT_UTF8 | EEZE_DISK_MOUNTOPT_NOEXEC | EEZE_DISK_MOUNTOPT_NOSUID)
65 EEZE_DISK_MOUNTOPT_LOOP = (1 << 1),
66 EEZE_DISK_MOUNTOPT_UTF8 = (1 << 2),
67 EEZE_DISK_MOUNTOPT_NOEXEC = (1 << 3),
68 EEZE_DISK_MOUNTOPT_NOSUID = (1 << 4),
69 EEZE_DISK_MOUNTOPT_REMOUNT = (1 << 5),
70 EEZE_DISK_MOUNTOPT_UID = (1 << 6), /**< use current user's uid */
71 EEZE_DISK_MOUNTOPT_NODEV = (1 << 7) /**< @since 1.7 */
72} Eeze_Mount_Opts;
73
74
75EAPI extern int EEZE_EVENT_DISK_MOUNT;
76EAPI extern int EEZE_EVENT_DISK_UNMOUNT;
77EAPI extern int EEZE_EVENT_DISK_EJECT;
78EAPI extern int EEZE_EVENT_DISK_ERROR;
79
80typedef struct _Eeze_Event_Disk Eeze_Event_Disk_Mount;
81typedef struct _Eeze_Event_Disk Eeze_Event_Disk_Unmount;
82typedef struct _Eeze_Event_Disk Eeze_Event_Disk_Eject;
83
84/**
85 * @typedef Eeze_Disk
86 * @since 1.1
87 *
88 * Handle for an Eeze Disk.
89 */
90typedef struct _Eeze_Disk Eeze_Disk;
91
92struct _Eeze_Event_Disk
93{
94 Eeze_Disk *disk;
95};
96
97/**
98 * @typedef Eeze_Event_Disk_Error
99 * @since 1.1
100 *
101 * Contains the human readable error message.
102 */
103typedef struct _Eeze_Event_Disk_Error Eeze_Event_Disk_Error;
104
105struct _Eeze_Event_Disk_Error
106{
107 Eeze_Disk *disk;
108 const char *message;
109};
110
111/**
112 * @brief Use this function to determine whether your eeze is disk-capable
113 *
114 * Since applications will die if they run/compile against a function that doesn't exist,
115 * if your application successfully runs/compiles with this function then you have eeze_disk.
116 * @since 1.1
117 */
118EAPI void eeze_disk_function(void);
119
120/**
121 * @brief Return whether mount support is available in eeze
122 *
123 * Use this function to determine whether your Eeze library was compiled with a mount
124 * binary available.
125 * @since 1.1
126 */
127EAPI Eina_Bool eeze_disk_can_mount(void);
128
129/**
130 * @brief Return whether unmount support is available in eeze
131 *
132 * Use this function to determine whether your Eeze library was compiled with an unmount
133 * binary available.
134 * @since 1.1
135 */
136EAPI Eina_Bool eeze_disk_can_unmount(void);
137
138/**
139 * @brief Return whether eject support is available in eeze
140 *
141 * Use this function to determine whether your Eeze library was compiled with an eject
142 * binary available.
143 * @since 1.1
144 */
145EAPI Eina_Bool eeze_disk_can_eject(void);
146
147/**
148 * @brief Create a new disk object from a /sys/ path or /dev/ path
149 * @param path The /sys/ or /dev path of the disk; CANNOT be @c NULL.
150 * @return The new disk object
151 *
152 * This function creates a new #Eeze_Disk from @p path. Note that this function
153 * does the minimal amount of work in order to save memory, and udev info about the disk
154 * is not retrieved in this call.
155 * @since 1.1
156 */
157EAPI Eeze_Disk *eeze_disk_new(const char *path);
158
159/**
160 * @brief Create a new disk object from a mount point
161 * @param mount_point The mount point of the disk; CANNOT be @c NULL
162 * @return The new disk object
163 *
164 * This function creates a new #Eeze_Disk from @p mount_point. Note that this function
165 * does the minimal amount of work in order to save memory, and udev info about the disk
166 * is not retrieved in this call. If the disk is not currently mounted, it must have an entry
167 * in /etc/fstab.
168 * @since 1.1
169 */
170EAPI Eeze_Disk *eeze_disk_new_from_mount(const char *mount_point);
171
172/**
173 * @brief Frees a disk object
174 * @param disk The disk object to free
175 *
176 * This call frees an #Eeze_Disk. Once freed, the disk can no longer be used.
177 * @since 1.1
178 */
179EAPI void eeze_disk_free(Eeze_Disk *disk);
180
181/**
182 * @brief Retrieve all disk information
183 * @param disk
184 *
185 * Use this function to retrieve all of a disk's information at once, then use
186 * a "get" function to retrieve the value. Data retrieved in this call is cached,
187 * meaning that subsequent calls will return immediately without performing any work.
188 * @since 1.1
189 */
190EAPI void eeze_disk_scan(Eeze_Disk *disk);
191
192/**
193 * @brief Associate data with a disk
194 * @param disk The disk
195 * @param data The data
196 *
197 * Data can be associated with @p disk with this function.
198 * @see eeze_disk_data_get
199 * @since 1.1
200 */
201EAPI void eeze_disk_data_set(Eeze_Disk *disk, void *data);
202
203/**
204 * @brief Retrieve data previously associated with a disk
205 * @param disk The disk
206 * @return The data
207 *
208 * Data that has been previously associated with @p disk
209 * is returned with this function.
210 * @see eeze_disk_data_set
211 * @since 1.1
212 */
213EAPI void *eeze_disk_data_get(Eeze_Disk *disk);
214
215/**
216 * @brief Return the /sys/ path of a disk
217 * @param disk The disk
218 * @return The /sys/ path
219 *
220 * This retrieves the /sys/ path that udev associates with @p disk.
221 * @since 1.1
222 */
223EAPI const char *eeze_disk_syspath_get(Eeze_Disk *disk);
224
225/**
226 * @brief Return the /dev/ path of a disk
227 * @param disk The disk
228 * @return The /dev/ path
229 *
230 * This retrieves the /dev/ path that udev has created a device node at for @p disk.
231 * @since 1.1
232 */
233EAPI const char *eeze_disk_devpath_get(Eeze_Disk *disk);
234
235/**
236 * @brief Return the filesystem of the disk (if known)
237 * @param disk The disk
238 * @return The filesystem type
239 *
240 * This retrieves the filesystem that the disk is using, or @c NULL if unknown.
241 * @since 1.1
242 */
243EAPI const char *eeze_disk_fstype_get(Eeze_Disk *disk);
244
245/**
246 * @brief Return the manufacturing vendor of the disk
247 * @param disk The disk
248 * @return The vendor
249 *
250 * This retrieves the vendor which manufactured the disk, or @c NULL if unknown.
251 * @since 1.1
252 */
253EAPI const char *eeze_disk_vendor_get(Eeze_Disk *disk);
254
255/**
256 * @brief Return the model of the disk
257 * @param disk The disk
258 * @return The model
259 *
260 * This retrieves the model of the disk, or @c NULL if unknown.
261 * @since 1.1
262 */
263EAPI const char *eeze_disk_model_get(Eeze_Disk *disk);
264
265/**
266 * @brief Return the serial number of the disk
267 * @param disk The disk
268 * @return The serial number
269 *
270 * This retrieves the serial number the disk, or @c NULL if unknown.
271 * @since 1.1
272 */
273EAPI const char *eeze_disk_serial_get(Eeze_Disk *disk);
274
275/**
276 * @brief Return the UUID of the disk
277 * @param disk The disk
278 * @return The UUID
279 *
280 * This retrieves the UUID of the disk, or @c NULL if unknown.
281 * A UUID is a 36 character (hopefully) unique identifier which can
282 * be used to store persistent information about a disk.
283 * @since 1.1
284 */
285EAPI const char *eeze_disk_uuid_get(Eeze_Disk *disk);
286
287/**
288 * @brief Return the label of the disk
289 * @param disk The disk
290 * @return The label
291 *
292 * This retrieves the label (name) of the disk, or @c NULL if unknown.
293 * @since 1.1
294 */
295EAPI const char *eeze_disk_label_get(Eeze_Disk *disk);
296
297/**
298 * @brief Return the #Eeze_Disk_Type of the disk
299 * @param disk The disk
300 * @return The type
301 *
302 * This retrieves the #Eeze_Disk_Type of the disk. This call is useful for determining
303 * the bus that the disk is connected through.
304 * @since 1.1
305 */
306EAPI Eeze_Disk_Type eeze_disk_type_get(Eeze_Disk *disk);
307
308/**
309 * @brief Return whether the disk is removable
310 * @param disk The disk
311 * @return @c EINA_TRUE if removable, @c EINA_FALSE otherwise.
312 * @since 1.1
313 */
314EAPI Eina_Bool eeze_disk_removable_get(Eeze_Disk *disk);
315
316
317/**
318 * @brief Return the mount state of a disk
319 * @param disk The disk
320 * @return The mount state
321 *
322 * This returns the mounted state of the disk. @c EINA_TRUE if mounted,
323 * @c EINA_FALSE otherwise.
324 * @since 1.1
325 */
326EAPI Eina_Bool eeze_disk_mounted_get(Eeze_Disk *disk);
327
328/**
329 * @brief Get the previously set mount wrapper for a disk
330 * @param disk The disk
331 * @return The wrapper, or @c NULL on failure.
332 *
333 * This returns the wrapper previously set with eeze_disk_mount_wrapper_set
334 * @since 1.1
335 */
336EAPI const char *eeze_disk_mount_wrapper_get(Eeze_Disk *disk);
337
338/**
339 * @brief Set a wrapper to run mount commands with
340 * @param disk The disk to wrap mount commands for
341 * @param wrapper The wrapper executable
342 * @return @c EINA_TRUE on success, @c EINA_FALSE otherwise.
343 *
344 * Use this function to set up a wrapper for running mount/umount commands. The wrapper must
345 * NOT use any of the standard mount/umount error code return values, and it must return 0 on success.
346 * Note that this function will call stat() on @p wrapper if not @c NULL to test for existence.
347 * @since 1.1
348 */
349EAPI Eina_Bool eeze_disk_mount_wrapper_set(Eeze_Disk *disk, const char *wrapper);
350
351/**
352 * @brief Begin a mount operation on the disk
353 * @param disk The disk
354 * @return @c EINA_TRUE if the operation was started, @c EINA_FALSE otherwise.
355 *
356 * This call is used to begin a mount operation on @p disk. The operation will
357 * run asynchronously in a pipe, emitting an EEZE_EVENT_DISK_MOUNT event with the disk object
358 * as its event on completion. If any errors are encountered, they will automatically logged
359 * to the eeze_disk domain and an EEZE_EVENT_DISK_ERROR event will be generated with an #Eeze_Event_Disk_Error
360 * struct as its event.
361 *
362 * NOTE: The return value of this function does not in any way reflect the mount state of a disk.
363 * @since 1.1
364 */
365EAPI Eina_Bool eeze_disk_mount(Eeze_Disk *disk);
366
367/**
368 * @brief Begin an unmount operation on the disk
369 * @param disk The disk
370 * @return @c EINA_TRUE if the operation was started, @c EINA_FALSE otherwise.
371 *
372 * This call is used to begin an unmount operation on @p disk. The operation will
373 * run asynchronously in a pipe, emitting an EEZE_EVENT_DISK_UNMOUNT event with the disk object
374 * as its event on completion. If any errors are encountered, they will automatically logged
375 * to the eeze_disk domain and an EEZE_EVENT_DISK_ERROR event will be generated with
376 * an #Eeze_Event_Disk_Error struct as its event.
377 *
378 * NOTE: The return value of this function does not in any way reflect the mount state of a disk.
379 * @since 1.1
380 */
381EAPI Eina_Bool eeze_disk_unmount(Eeze_Disk *disk);
382
383/**
384 * @brief Begin an eject operation on the disk
385 * @param disk The disk
386 * @return @c EINA_TRUE if the operation was started, @c EINA_FALSE otherwise.
387 *
388 * This call is used to begin an eject operation on @p disk. The operation will
389 * run asynchronously in a pipe, emitting an EEZE_EVENT_DISK_EJECT event with the disk object
390 * as its event on completion. If any errors are encountered, they will automatically logged
391 * to the eeze_disk domain and an EEZE_EVENT_DISK_ERROR event will be generated with
392 * an #Eeze_Event_Disk_Error struct as its event.
393 *
394 * NOTE: The return value of this function does not in any way reflect the mount state of a disk.
395 * @since 1.1
396 */
397EAPI Eina_Bool eeze_disk_eject(Eeze_Disk *disk);
398/**
399 * @brief Cancel a pending operation on the disk
400 * @param disk The disk
401 *
402 * This function cancels the current pending operation on @p disk which was previously
403 * started with eeze_disk_mount or eeze_disk_unmount.
404 * @since 1.1
405 */
406EAPI void eeze_disk_cancel(Eeze_Disk *disk);
407
408/**
409 * @brief Return the mount point of a disk
410 * @param disk The disk
411 * @return The mount point
412 *
413 * This function returns the mount point associated with @p disk.
414 * Note that to determine whether the disk is actually mounted, eeze_disk_mounted_get should be used.
415 * @since 1.1
416 */
417EAPI const char *eeze_disk_mount_point_get(Eeze_Disk *disk);
418
419/**
420 * @brief Set the mount point of a disk
421 * @param disk The disk
422 * @param mount_point The mount point
423 * @return @c EINA_TRUE on success, @c EINA_FALSE otherwise.
424 *
425 * This function sets the mount point associated with @p disk.
426 * Note that to determine whether the disk is actually mounted, eeze_disk_mounted_get should be used.
427 * Also note that this function cannot be used while the disk is mounted to avoid losing the current mount point.
428 * @since 1.1
429 */
430EAPI Eina_Bool eeze_disk_mount_point_set(Eeze_Disk *disk, const char *mount_point);
431
432/**
433 * @brief Set the mount options using flags
434 * @param disk The disk
435 * @param opts An ORed set of #Eeze_Mount_Opts
436 * @return @c EINA_TRUE on success, @c EINA_FALSE otherwise.
437 *
438 * This function replaces the current mount opts of a disk with the ones in @p opts.
439 * @since 1.1
440 */
441EAPI Eina_Bool eeze_disk_mountopts_set(Eeze_Disk *disk, unsigned long opts);
442
443/**
444 * @brief Get the flags of a disk's current mount options
445 * @param disk The disk
446 * @return An ORed set of #Eeze_Mount_Opts, 0 on failure
447 *
448 * This function returns the current mount opts of a disk.
449 * @since 1.1
450 */
451EAPI unsigned long eeze_disk_mountopts_get(Eeze_Disk *disk);
452
453
454/**
455 * @brief Begin watching mtab and fstab
456 * @return @c EINA_TRUE if watching was started, @c EINA_FALSE otherwise.
457 *
458 * This function creates inotify watches on /etc/mtab and /etc/fstab and watches
459 * them for changes. This function should be used when expecting a lot of disk
460 * mounting/unmounting while you need disk data since it will automatically update
461 * certain necessary data instead of waiting.
462 * @see eeze_mount_mtab_scan, eeze_mount_fstab_scan
463 * @since 1.1
464 */
465EAPI Eina_Bool eeze_mount_tabs_watch(void);
466
467/**
468 * @brief Stop watching /etc/fstab and /etc/mtab
469 *
470 * This function stops watching fstab and mtab. Data obtained previously will be saved.
471 * @since 1.1
472 */
473EAPI void eeze_mount_tabs_unwatch(void);
474
475/**
476 * @brief Scan /etc/mtab a single time
477 * @return @c EINA_TRUE if mtab could be scanned, @c EINA_FALSE otherwise.
478 *
479 * This function is used to perform a single scan on /etc/mtab. It is used to gather
480 * information about mounted filesystems which can then be used with your #Eeze_Disk objects
481 * where appropriate. These files will automatically be scanned any time a mount point or mount state
482 * is requested unless eeze_mount_tabs_watch has been called previously, in which case data is stored for
483 * use.
484 * If this function is called after eeze_mount_tabs_watch, @c EINA_TRUE will be returned.
485 * @see eeze_mount_tabs_watch, eeze_mount_fstab_scan
486 * @since 1.1
487 */
488EAPI Eina_Bool eeze_mount_mtab_scan(void);
489
490/**
491 * @brief Scan /etc/fstab a single time
492 * @return @c EINA_TRUE if mtab could be scanned, @c EINA_FALSE otherwise.
493 *
494 * This function is used to perform a single scan on /etc/fstab. It is used to gather
495 * information about mounted filesystems which can then be used with your #Eeze_Disk objects
496 * where appropriate. These files will automatically be scanned any time a mount point or mount state
497 * is requested unless eeze_mount_tabs_watch has been called previously, in which case data is stored for
498 * use.
499 * If this function is called after eeze_mount_tabs_watch, @c EINA_TRUE will be returned.
500 * @see eeze_mount_tabs_watch, eeze_mount_mtab_scan
501 * @since 1.1
502 */
503EAPI Eina_Bool eeze_mount_fstab_scan(void);
504
505/**
506 * @brief Get the property value of a disk
507 *
508 * @param disk The disk
509 * @param property The property to get; full list of these is a FIXME
510 * @return A stringshared char* with the property or @c NULL on failure.
511 * @since 1.1
512 */
513
514EAPI const char *eeze_disk_udev_get_property(Eeze_Disk *disk, const char *property);
515
516/**
517 * @brief Get the sysattr value of a disk.
518 *
519 * @param disk The disk
520 * @param sysattr The sysattr to get; full list of these is a FIXME
521 * @return A stringshared char* with the sysattr or @c NULL on failure.
522 * @since 1.1
523 */
524
525EAPI const char *eeze_disk_udev_get_sysattr(Eeze_Disk *disk, const char *sysattr);
526
527/**
528 * Find the root device of a disk.
529 *
530 * @param disk The disk
531 * @return The syspath of the parent device
532 *
533 * Return a stringshared syspath (/sys/$syspath) for the parent device.
534 * @since 1.1
535 */
536EAPI const char *eeze_disk_udev_get_parent(Eeze_Disk *disk);
537
538/**
539 * Walks up the device chain using the device from @p disk,
540 * checking each device for @p sysattr with (optional) @p value.
541 *
542 * @param disk The disk to walk
543 * @param sysattr The attribute to find
544 * @param value OPTIONAL: The value that @p sysattr should have, or @c NULL.
545 *
546 * @return If the sysattr (with value) is found, returns @c EINA_TRUE,
547 * @c EINA_FALSE otherwise.
548 * @since 1.1
549 */
550EAPI Eina_Bool eeze_disk_udev_walk_check_sysattr(Eeze_Disk *disk, const char *sysattr, const char *value);
551
552/**
553 * @brief Walks up the device chain of @p disk
554 * checking each device for @p sysattr and returns the value if found.
555 *
556 * @param disk The disk
557 * @param sysattr The attribute to find
558 *
559 * @return The stringshared value of @p sysattr if found, or @c NULL.
560 * @since 1.1
561 */
562EAPI const char *eeze_disk_udev_walk_get_sysattr(Eeze_Disk *disk, const char *sysattr);
563
564#ifdef __cplusplus
565}
566#endif
567
568/**
569 * @}
570 */
571#endif
diff --git a/src/lib/eeze/Eeze_Net.h b/src/lib/eeze/Eeze_Net.h
new file mode 100644
index 0000000000..aa58deb8d4
--- /dev/null
+++ b/src/lib/eeze/Eeze_Net.h
@@ -0,0 +1,65 @@
1#ifndef EEZE_NET_H
2#define EEZE_NET_H
3
4#ifdef EAPI
5# undef EAPI
6#endif
7
8#ifdef __GNUC__
9# if __GNUC__ >= 4
10# define EAPI __attribute__ ((visibility("default")))
11# else
12# define EAPI
13# endif
14#else
15# define EAPI
16#endif
17
18#include <Eina.h>
19#include <Ecore.h>
20
21/**
22 * @file Eeze_Net.h
23 * @brief Network manipulation
24 *
25 * Eeze net functions allow you to gather information about network objects
26 *
27 * @defgroup Eeze_Net Net
28 * Gather information about network devices.
29 *
30 * @ingroup Eeze
31 * @{
32 */
33
34typedef struct Eeze_Net Eeze_Net;
35
36typedef enum
37{
38 EEZE_NET_ADDR_TYPE_IP,
39 EEZE_NET_ADDR_TYPE_IP6,
40 EEZE_NET_ADDR_TYPE_BROADCAST,
41 EEZE_NET_ADDR_TYPE_BROADCAST6,
42 EEZE_NET_ADDR_TYPE_NETMASK,
43 EEZE_NET_ADDR_TYPE_NETMASK6,
44} Eeze_Net_Addr_Type;
45
46#ifdef __cplusplus
47extern "C" {
48#endif
49
50EAPI Eeze_Net *eeze_net_new(const char *name);
51EAPI void eeze_net_free(Eeze_Net *net);
52EAPI const char *eeze_net_mac_get(Eeze_Net *net);
53EAPI int eeze_net_idx_get(Eeze_Net *net);
54EAPI Eina_Bool eeze_net_scan(Eeze_Net *net);
55EAPI const char *eeze_net_addr_get(Eeze_Net *net, Eeze_Net_Addr_Type type);
56EAPI const char *eeze_net_attribute_get(Eeze_Net *net, const char *attr);
57EAPI const char *eeze_net_syspath_get(Eeze_Net *net);
58EAPI Eina_List *eeze_net_list(void);
59
60#ifdef __cplusplus
61}
62#endif
63/** @} */
64
65#endif
diff --git a/src/lib/eeze/Eeze_Sensor.h b/src/lib/eeze/Eeze_Sensor.h
new file mode 100644
index 0000000000..02a51fe385
--- /dev/null
+++ b/src/lib/eeze/Eeze_Sensor.h
@@ -0,0 +1,325 @@
1#ifndef EEZE_SENSOR_H
2#define EEZE_SENSOR_H
3
4#ifdef EAPI
5# undef EAPI
6#endif
7
8#ifdef __GNUC__
9# if __GNUC__ >= 4
10# define EAPI __attribute__ ((visibility("default")))
11# else
12# define EAPI
13# endif
14#else
15# define EAPI
16#endif
17
18#include <Eina.h>
19
20/**
21 * @file Eeze_Sensor.h
22 * @brief Sensor information subsystem
23 *
24 * Eeze sensor functions allow you to gather sensor information from different
25 * sensor sources available on your hardware. It supports a plugin architecture
26 * to support different hardware platforms and devices. These plugins can be
27 * loaded at runtime.
28 *
29 * Right now we have support for the Tizen sensor framework as well as a simple
30 * fake plugin to be used as a test harness for development. Plugins for other
31 * sensor frameworks or platforms are always welcome.
32 *
33 * Synchronous as well as asynchronous reads are possible. As reading the
34 * physical sensor might be bound to a high latency and thus cost the value of
35 * the last read is cached within Eeze_Sensor together with a timestamp of the
36 * actual read out. This can speed up the value access for application while the
37 * values are still getting updating asynchronously in the background. The
38 * timestamp should be checked if the specific time requirements are needed.
39 *
40 * As an alternative the sensor could be read synchronously. With the
41 * disadvantage that the function call will block until the data is read from
42 * the sensor.
43 *
44 * @since 1.8
45 *
46 * @addtogroup Eeze_Sensor Sensor
47 * Gather sensor information from different sources. Works based on plugins,
48 * with a Tizen plugin being available.
49 *
50 * @ingroup Eeze
51 * @{
52 */
53
54/**
55 * @enum Eeze_Sensor_Type
56 *
57 * All sensor types known by Eeze Sensor. This list of types include real
58 * physical types like proximity or light as well as "aggregated" types like
59 * facedown or doubletap. All types with MOTION in their name can be used as
60 * real events coming from the underlying system. This is not supported on all
61 * systems.
62 *
63 * @since 1.8
64 */
65typedef enum
66{
67 EEZE_SENSOR_TYPE_ACCELEROMETER, /**< Accelerometer sensor */
68 EEZE_SENSOR_TYPE_MAGNETIC, /**< Magnetic sensor */
69 EEZE_SENSOR_TYPE_ORIENTATION, /**< Orientation sensor */
70 EEZE_SENSOR_TYPE_GYROSCOPE, /**< Gyroscope sensor */
71 EEZE_SENSOR_TYPE_LIGHT, /**< Light sensor */
72 EEZE_SENSOR_TYPE_PROXIMITY, /**< Proximity sensor */
73 EEZE_SENSOR_TYPE_MOTION_SNAP, /**< Snap motion sensor */
74 EEZE_SENSOR_TYPE_MOTION_SHAKE, /**< Shake motion sensor */
75 EEZE_SENSOR_TYPE_MOTION_DOUBLETAP, /**< Doubletap motion sensor */
76 EEZE_SENSOR_TYPE_MOTION_PANNING, /**< Panning motion sensor */
77 EEZE_SENSOR_TYPE_MOTION_FACEDOWN, /**< Facedown motion sensor */
78 /* Non-Tizen from here */
79 EEZE_SENSOR_TYPE_BAROMETER, /**< Barometer sensor */
80 EEZE_SENSOR_TYPE_TEMPERATURE, /**< Temperature sensor */
81 EEZE_SENSOR_TYPE_LAST = 0xFF /**< Last item to mark end of enum */
82} Eeze_Sensor_Type;
83
84/**
85 * @defgroup Eeze_Sensor_Events Available eeze sensor events
86 * @brief Sensor events that are emitted from the library as ecore events
87 * @ingroup Eeze
88 *
89 * Event types used to register ecore_event_handler on. These events are used
90 * for #eeze_sensor_async_read to deliver read out data. It is also used for
91 * generated events like facedown or shake. Subscribing to these events in your
92 * application allowsyou to react on these changes in an efficient way without
93 * polling for new updates and wasting power and computing cycles.
94 *
95 * @since 1.8
96 * @{
97 */
98EAPI int EEZE_SENSOR_EVENT_ACCELEROMETER;
99EAPI int EEZE_SENSOR_EVENT_MAGNETIC;
100EAPI int EEZE_SENSOR_EVENT_ORIENTATION;
101EAPI int EEZE_SENSOR_EVENT_GYROSCOPE;
102EAPI int EEZE_SENSOR_EVENT_LIGHT;
103EAPI int EEZE_SENSOR_EVENT_PROXIMITY;
104EAPI int EEZE_SENSOR_EVENT_SNAP;
105EAPI int EEZE_SENSOR_EVENT_SHAKE;
106EAPI int EEZE_SENSOR_EVENT_DOUBLETAP;
107EAPI int EEZE_SENSOR_EVENT_PANNING;
108EAPI int EEZE_SENSOR_EVENT_FACEDOWN;
109EAPI int EEZE_SENSOR_EVENT_BAROMETER;
110EAPI int EEZE_SENSOR_EVENT_TEMPERATURE;
111/**@}*/
112
113/**
114 * @typedef Eeze_Sensor_Obj;
115 *
116 * Object for a sensor type. Keeps information about the type and holds the
117 * data for the accessor functions. As this information gets also updated by
118 * asynchronous reads it might be a good idea to check the timestamp value to
119 * see when the data has been updated. The timestamp is given in microseconds.
120 *
121 * You are not supposed to access the raw data values from here but use the
122 * getter functions for it. Using the raw values from this struct might break
123 * your applications later if the internal structure changes.
124 *
125 * @since 1.8
126 */
127typedef struct _Eeze_Sensor_Obj
128{
129 unsigned int type; /**< Sensor type see #Eeze_Sensor_Type */
130 int accuracy; /**< Accuracy of the sensor value */
131 float data[3]; /**< Sensor data depending on the sensor type */
132 unsigned long long timestamp; /**< Timestamp of data read */
133 Eina_Bool continuous_flow; /**< FUTURE USE: Continuous flow of sensor read out */
134} Eeze_Sensor_Obj;
135
136#ifdef __cplusplus
137extern "C" {
138#endif
139
140/**
141 * @brief Create sensor object to operate on.
142 * @param type Sensor type to create object from.
143 * @return Sensor object for the given type.
144 *
145 * Takes the sensor type and create an object for it to operate on. During this
146 * it also does an initial sensor data read to fill the sensor data into the
147 * object. The #eeze_sensor_free function must be used to destroy the object
148 * and release its memory.
149 *
150 * For every sensor type you want to work with this is the first thing you have
151 * to do. Create the object from the type and everything else the operates on
152 * this object.
153 *
154 * This also takes into account what runtime modules are loaded and handles
155 * them in a given priority to pick up the best sensor source for your sensor
156 * object.
157 *
158 * @since 1.8
159 */
160EAPI Eeze_Sensor_Obj *eeze_sensor_new(Eeze_Sensor_Type type);
161
162/**
163 * @brief Free a sensor object.
164 * @param sens Sensor object to operate on.
165 *
166 * Free an sensor object when it is no longer needed. Always use this function
167 * to cleanup unused sensor objects.
168 *
169 * @since 1.8
170 */
171EAPI void eeze_sensor_free(Eeze_Sensor_Obj *sens);
172
173/**
174 * @brief Get accuracy from sensor object.
175 * @param sens Sensor object to operate on.
176 * @param accuracy Pointer to write accuracy value into.
177 * @return EINA_TRUE for success and EINA_FALSE for failure
178 *
179 * Access function to get the accuracy property from the sensor object. The
180 * accuracy value can have the following values and meaning:
181 * -1 Undefined accuracy
182 * 0 Bad accurancy
183 * 1 Normal accuracy
184 * 2 Good accuracy
185 * 3 Very good accuracy
186 *
187 * @since 1.8
188 */
189EAPI Eina_Bool eeze_sensor_accuracy_get(Eeze_Sensor_Obj *sens, int *accuracy);
190
191/**
192 * @brief Get data from all three data properties
193 * @param sens Sensor object to operate on.
194 * @param x Pointer to write first data property value into.
195 * @param y Pointer to write second data property value into.
196 * @param z Pointer to write third data property value into.
197 * @return EINA_TRUE for success and EINA_FALSE for failure
198 *
199 * Access function to get all three data properties from the sensor object.
200 * This is used for sensor types that offer all three values. Like accelerometer
201 * and magnetic.
202 *
203 * @since 1.8
204 */
205EAPI Eina_Bool eeze_sensor_xyz_get(Eeze_Sensor_Obj *sens, float *x, float *y, float *z);
206
207/**
208 * @brief Get data from first two data properties
209 * @param sens Sensor object to operate on.
210 * @param x Pointer to write first data property value into.
211 * @param y Pointer to write second data property value into.
212 * @return EINA_TRUE for success and EINA_FALSE for failure
213 *
214 * Access function to get the first two data properties from the sensor object.
215 * This is used for sensor types that offer two values. Like panning.
216 *
217 * @since 1.8
218 */
219EAPI Eina_Bool eeze_sensor_xy_get(Eeze_Sensor_Obj *sens, float *x, float *y);
220
221/**
222 * @brief Get the data from first data property
223 * @param sens Sensor object to operate on.
224 * @param x Pointer to write first data property value into.
225 * @return EINA_TRUE for success and EINA_FALSE for failure
226 *
227 * Access function to get the first data property from the sensor object. This
228 * is used for sensor types that only offer one value. Like light or proximity.
229 *
230 * @since 1.8
231 */
232EAPI Eina_Bool eeze_sensor_x_get(Eeze_Sensor_Obj *sens, float *x);
233
234/**
235 * @brief Get timestamp from sensor object.
236 * @param sens Sensor object to operate on.
237 * @param timestamp Pointer to write timestamp value into.
238 * @return EINA_TRUE for success and EINA_FALSE for failure
239 *
240 * Access function to get the timestamp property from the sensor object. It
241 * allows you to determine if the values have been updated since the last time
242 * you requested them.
243 *
244 * @since 1.8
245 */
246EAPI Eina_Bool eeze_sensor_timestamp_get(Eeze_Sensor_Obj *sens, unsigned long long *timestamp);
247
248/**
249 * @brief Read out sensor data
250 * @param sens Sensor object to operate on.
251 * @return EINA_TRUE for success and EINA_FALSE for failure
252 *
253 * This function reads sensor data from the device and fills the sensor object
254 * with the data. This call is synchronous and blocks until the data is read out
255 * and updated in the sensor object. For simple applications this is fine and
256 * the easiest way to use the API. A more efficient way is to use
257 * #eeze_sensor_async_read which allows the sensor readout to happen in the
258 * background and the application would check the timestamp of the data to
259 * determine how recent the data is.
260 *
261 * @since 1.8
262 */
263EAPI Eina_Bool eeze_sensor_read(Eeze_Sensor_Obj *sens);
264
265/**
266 * @brief Asynchronous read out sensor data
267 * @param sens Sensor object to operate on.
268 * @param user_data Data to pass to the callback function.
269 * @return EINA_TRUE for success and EINA_FALSE for failure
270 *
271 * This function reads sensor data from the device and fills the sensor object
272 * with the data. The read is done asynchronously and thus does not block after
273 * calling. Instead the given the application can determine how recent the
274 * values are from the timestamp value that can be accessed through
275 * #eeze_sensor_timestamp_get.
276 *
277 * This function is more efficient but needs a bit more work in the application.
278 * An easier way is to use the synchronous #eeze_sensor_read functions. The
279 * downside of it is that it blocks until the data was read out from the
280 * physical sensor. That might be a long time depending on the hardware and its
281 * interface.
282 *
283 * @since 1.8
284 */
285EAPI Eina_Bool eeze_sensor_async_read(Eeze_Sensor_Obj *sens, void *user_data);
286
287/**
288 * @brief Fetch the sensor object by type from the sensor object list
289 * @param type Sensor type to fetch from the list of sensor objects.
290 * @return The sensor object matching the given type
291 *
292 * @since 1.8
293 */
294EAPI Eeze_Sensor_Obj *eeze_sensor_obj_get(Eeze_Sensor_Type type);
295
296/**
297 * @brief Initialize the Eeze sensor subsystem.
298 * @return EINA_TRUE for success and EINA_FALSE for failure
299 *
300 * This function must be called before using any of the Eeze_Sensor
301 * functionality to make sure the subsystem is setup correctly for usage. If
302 * you already call #eeze_init in your program this is already been take care
303 * of and there is no need to call this to initialize this subsystem manually.
304 *
305 * @since 1.8
306 */
307EAPI Eina_Bool eeze_sensor_init(void);
308
309/**
310 * @brief Clean up and shutdown the Eeze sensor subsystem.
311 *
312 * This function must be called when now longer using Eeze_Sensor to allow the
313 * subsystem to shutdown cleanly. If you already called #eeze_shutdown this is
314 * already been taken care of and there is no need to call this to shutdown this
315 * subsystem manually.
316 *
317 * @since 1.8
318 */
319EAPI void eeze_sensor_shutdown(void);
320
321#ifdef __cplusplus
322}
323#endif
324/** @} */
325#endif
diff --git a/src/lib/eeze/eeze_disk.c b/src/lib/eeze/eeze_disk.c
new file mode 100644
index 0000000000..80b0c31437
--- /dev/null
+++ b/src/lib/eeze/eeze_disk.c
@@ -0,0 +1,483 @@
1#ifdef HAVE_CONFIG_H
2#include "config.h"
3#endif
4
5#include <Ecore.h>
6#include <Eeze.h>
7#include <Eeze_Disk.h>
8#include <unistd.h>
9
10#include "eeze_udev_private.h"
11#include "eeze_disk_private.h"
12
13int _eeze_disk_log_dom = -1;
14Eina_List *_eeze_disks = NULL;
15
16static Eeze_Disk_Type
17_eeze_disk_type_find(Eeze_Disk *disk)
18{
19 const char *test;
20 Eeze_Disk_Type ret;
21 Eina_Bool filesystem = EINA_FALSE; /* this will have no children */
22
23 if (udev_device_get_property_value(disk->device, "ID_CDROM"))
24 return EEZE_DISK_TYPE_CDROM;
25 test = udev_device_get_property_value(disk->device, "ID_FS_USAGE");
26 if ((!test) || strcmp(test, "filesystem"))
27 {
28 test = _walk_children_get_attr(disk->syspath, "ID_CDROM", "block", EINA_TRUE);
29 if (test)
30 {
31 eina_stringshare_del(test);
32 return EEZE_DISK_TYPE_CDROM;
33 }
34 }
35 else
36 filesystem = EINA_TRUE;
37 if (udev_device_get_property_value(disk->device, "ID_ATA"))
38 return EEZE_DISK_TYPE_INTERNAL;
39 if (!filesystem)
40 {
41 test = _walk_children_get_attr(disk->syspath, "ID_ATA", "block", EINA_TRUE);
42 if (test)
43 {
44 eina_stringshare_del(test);
45 return EEZE_DISK_TYPE_INTERNAL;
46 }
47 }
48 test = udev_device_get_property_value(disk->device, "ID_BUS");
49 if (test)
50 {
51 if (!strcmp(test, "ata")) return EEZE_DISK_TYPE_INTERNAL;
52 if (!strcmp(test, "usb")) return EEZE_DISK_TYPE_USB;
53 return EEZE_DISK_TYPE_UNKNOWN; /* FIXME */
54 }
55 if ((!test) && (!filesystem))
56 test = _walk_children_get_attr(disk->syspath, "ID_BUS", "block", EINA_TRUE);
57 if (!test)
58 {
59 _udev_device *dev;
60
61 for (dev = udev_device_get_parent(disk->device); dev; dev = udev_device_get_parent(dev))
62 {
63 test = udev_device_get_subsystem(dev);
64 if (!test) return EEZE_DISK_TYPE_UNKNOWN;
65 if (!strcmp(test, "block")) continue;
66 if (!strcmp(test, "mmc")) return EEZE_DISK_TYPE_FLASH;
67 break;
68 }
69 return EEZE_DISK_TYPE_UNKNOWN; /* FIXME */
70 }
71
72 if (!strcmp(test, "ata")) ret = EEZE_DISK_TYPE_INTERNAL;
73 else if (!strcmp(test, "usb")) ret = EEZE_DISK_TYPE_USB;
74 else ret = EEZE_DISK_TYPE_UNKNOWN; /* FIXME */
75
76 eina_stringshare_del(test);
77
78 return ret;
79}
80
81static _udev_device *
82_eeze_disk_device_from_property(const char *prop, Eina_Bool uuid)
83{
84 _udev_enumerate *en;
85 _udev_list_entry *devs, *cur;
86 _udev_device *device = NULL;
87 const char *devname;
88
89 en = udev_enumerate_new(udev);
90
91 if (!en)
92 return NULL;
93
94 if (uuid)
95 udev_enumerate_add_match_property(en, "ID_FS_UUID", prop);
96 else
97 udev_enumerate_add_match_property(en, "ID_FS_LABEL", prop);
98 udev_enumerate_scan_devices(en);
99 devs = udev_enumerate_get_list_entry(en);
100 udev_list_entry_foreach(cur, devs)
101 {
102 devname = udev_list_entry_get_name(cur);
103 device = udev_device_new_from_syspath(udev, devname);
104 break;
105 }
106 udev_enumerate_unref(en);
107 return device;
108
109}
110
111void
112eeze_disk_shutdown(void)
113{
114 eeze_mount_shutdown();
115 ecore_file_shutdown();
116 eina_log_domain_unregister(_eeze_disk_log_dom);
117 _eeze_disk_log_dom = -1;
118}
119
120Eina_Bool
121eeze_disk_init(void)
122{
123 _eeze_disk_log_dom = eina_log_domain_register("eeze_disk", EINA_COLOR_LIGHTBLUE);
124
125 if (_eeze_disk_log_dom < 0)
126 {
127 EINA_LOG_ERR("Could not register 'eeze_disk' log domain.");
128 goto disk_fail;
129 }
130
131 if (!ecore_file_init())
132 goto disk_fail;
133 if (!eeze_mount_init())
134 goto ecore_file_fail;
135
136 return EINA_TRUE;
137
138ecore_file_fail:
139 ecore_file_shutdown();
140disk_fail:
141 eina_log_domain_unregister(_eeze_disk_log_dom);
142 _eeze_disk_log_dom = -1;
143 return EINA_FALSE;
144}
145
146EAPI void
147eeze_disk_function(void)
148{
149}
150
151EAPI Eeze_Disk *
152eeze_disk_new(const char *path)
153{
154 Eeze_Disk *disk;
155 _udev_device *dev;
156 const char *syspath = NULL;
157 Eina_Bool is_dev = EINA_FALSE;
158
159 EINA_SAFETY_ON_NULL_RETURN_VAL(path, NULL);
160
161 if (!strncmp(path, "/dev/", 5))
162 {
163 is_dev = EINA_TRUE;
164 syspath = eeze_udev_devpath_get_syspath(path);
165 if (!syspath)
166 return NULL;
167
168 if (!(dev = _new_device(syspath)))
169 {
170 eina_stringshare_del(syspath);
171 return NULL;
172 }
173 }
174 else if (!(dev = _new_device(path)))
175 return NULL;
176
177
178 if (!(disk = calloc(1, sizeof(Eeze_Disk))))
179 return NULL;
180
181
182 if (is_dev)
183 {
184 disk->devpath = eina_stringshare_add(path);
185 disk->syspath = syspath;
186 }
187 else
188 disk->syspath = eina_stringshare_add(udev_device_get_syspath(dev));
189
190
191 disk->device = dev;
192 disk->mount_opts = EEZE_DISK_MOUNTOPT_DEFAULTS;
193 disk->mount_cmd_changed = EINA_TRUE;
194 disk->unmount_cmd_changed = EINA_TRUE;
195
196 _eeze_disks = eina_list_append(_eeze_disks, disk);
197
198 return disk;
199}
200
201EAPI Eeze_Disk *
202eeze_disk_new_from_mount(const char *mount_point)
203{
204 Eeze_Disk *disk = NULL;
205 _udev_device *dev = NULL;
206 const char *syspath = NULL, *source, *uuid = NULL, *label = NULL, *devpath = NULL;
207
208 EINA_SAFETY_ON_NULL_RETURN_VAL(mount_point, NULL);
209
210 if (!(source = eeze_disk_libmount_mp_find_source(mount_point)))
211 return NULL;
212
213 if (source[4] == '=')
214 {
215 source += 5;
216 uuid = eina_stringshare_add(source);
217 dev = _eeze_disk_device_from_property(uuid, EINA_TRUE);
218 }
219 else if (source[5] == '=')
220 {
221 source += 6;
222 label = eina_stringshare_add(source);
223 dev = _eeze_disk_device_from_property(label, EINA_FALSE);
224 }
225 else
226 {
227 const char *spath;
228
229 devpath = eina_stringshare_add(source);
230 spath = eeze_udev_devpath_get_syspath(devpath);
231 dev = _new_device(spath);
232 eina_stringshare_del(spath);
233 }
234
235 if (!dev)
236 goto error;
237
238 if (!(disk = calloc(1, sizeof(Eeze_Disk))))
239 goto error;
240
241 disk->syspath = udev_device_get_syspath(dev);
242
243 disk->device = dev;
244 disk->mount_cmd_changed = EINA_TRUE;
245 disk->unmount_cmd_changed = EINA_TRUE;
246 if (uuid)
247 disk->cache.uuid = uuid;
248 else if (label)
249 disk->cache.label = label;
250 else
251 disk->devpath = devpath;
252 disk->mount_point = eina_stringshare_add(mount_point);
253
254 _eeze_disks = eina_list_append(_eeze_disks, disk);
255
256 return disk;
257error:
258 if (uuid)
259 eina_stringshare_del(uuid);
260 else if (label)
261 eina_stringshare_del(label);
262 else if (devpath)
263 eina_stringshare_del(devpath);
264 if (syspath)
265 eina_stringshare_del(syspath);
266 if (dev)
267 udev_device_unref(dev);
268 return NULL;
269}
270
271EAPI void
272eeze_disk_free(Eeze_Disk *disk)
273{
274 extern Eina_List *eeze_events;
275 EINA_SAFETY_ON_NULL_RETURN(disk);
276
277 udev_device_unref(disk->device);
278 if (disk->mount_cmd)
279 eina_strbuf_free(disk->mount_cmd);
280 if (disk->unmount_cmd)
281 eina_strbuf_free(disk->unmount_cmd);
282 if (disk->eject_cmd)
283 eina_strbuf_free(disk->eject_cmd);
284 if (disk->mounter) ecore_exe_kill(disk->mounter);
285 _eeze_disks = eina_list_remove(_eeze_disks, disk);
286 eeze_events = eina_list_remove(eeze_events, disk);
287 free(disk);
288}
289
290EAPI void
291eeze_disk_scan(Eeze_Disk *disk)
292{
293 const char *test;
294 EINA_SAFETY_ON_NULL_RETURN(disk);
295 /* never rescan; if these values change then something is seriously wrong */
296 if (disk->cache.filled) return;
297
298 if (!disk->cache.vendor)
299 disk->cache.vendor = udev_device_get_property_value(disk->device, "ID_VENDOR");
300 if (!disk->cache.vendor)
301 if (!disk->cache.vendor) disk->cache.vendor = udev_device_get_sysattr_value(disk->device, "vendor");
302 if (!disk->cache.model)
303 disk->cache.model = udev_device_get_property_value(disk->device, "ID_MODEL");
304 if (!disk->cache.model)
305 if (!disk->cache.model) disk->cache.model = udev_device_get_sysattr_value(disk->device, "model");
306 if (!disk->cache.serial)
307 disk->cache.serial = udev_device_get_property_value(disk->device, "ID_SERIAL_SHORT");
308 if (!disk->cache.uuid)
309 disk->cache.uuid = udev_device_get_property_value(disk->device, "ID_FS_UUID");
310 if (!disk->cache.type)
311 disk->cache.type = _eeze_disk_type_find(disk);
312 if (!disk->cache.label)
313 disk->cache.label = udev_device_get_property_value(disk->device, "ID_FS_LABEL");
314 test = udev_device_get_sysattr_value(disk->device, "removable");
315 if (test) disk->cache.removable = !!strtol(test, NULL, 10);
316 else
317 test = _walk_children_get_attr(disk->syspath, "removable", "block", EINA_FALSE);
318 if (test)
319 {
320 disk->cache.removable = !!strtol(test, NULL, 10);
321 eina_stringshare_del(test);
322 }
323
324 disk->cache.filled = EINA_TRUE;
325}
326
327EAPI void
328eeze_disk_data_set(Eeze_Disk *disk, void *data)
329{
330 EINA_SAFETY_ON_NULL_RETURN(disk);
331
332 disk->data = data;
333}
334
335EAPI void *
336eeze_disk_data_get(Eeze_Disk *disk)
337{
338 EINA_SAFETY_ON_NULL_RETURN_VAL(disk, NULL);
339
340 return disk->data;
341}
342
343EAPI const char *
344eeze_disk_syspath_get(Eeze_Disk *disk)
345{
346 EINA_SAFETY_ON_NULL_RETURN_VAL(disk, NULL);
347
348 return disk->syspath;
349}
350
351EAPI const char *
352eeze_disk_devpath_get(Eeze_Disk *disk)
353{
354 EINA_SAFETY_ON_NULL_RETURN_VAL(disk, NULL);
355
356 if (disk->devpath)
357 return disk->devpath;
358 disk->devpath = udev_device_get_devnode(disk->device);
359 return disk->devpath;
360}
361
362EAPI const char *
363eeze_disk_fstype_get(Eeze_Disk *disk)
364{
365 EINA_SAFETY_ON_NULL_RETURN_VAL(disk, NULL);
366
367 return disk->fstype;
368}
369
370EAPI const char *
371eeze_disk_vendor_get(Eeze_Disk *disk)
372{
373 EINA_SAFETY_ON_NULL_RETURN_VAL(disk, NULL);
374
375 if (disk->cache.vendor)
376 return disk->cache.vendor;
377
378 disk->cache.vendor = udev_device_get_property_value(disk->device, "ID_VENDOR");
379 if (!disk->cache.vendor) disk->cache.vendor = udev_device_get_sysattr_value(disk->device, "vendor");
380 return disk->cache.vendor;
381}
382
383EAPI const char *
384eeze_disk_model_get(Eeze_Disk *disk)
385{
386 EINA_SAFETY_ON_NULL_RETURN_VAL(disk, NULL);
387
388 if (disk->cache.model)
389 return disk->cache.model;
390
391 disk->cache.model = udev_device_get_property_value(disk->device, "ID_MODEL");
392 if (!disk->cache.model) disk->cache.model = udev_device_get_sysattr_value(disk->device, "model");
393 return disk->cache.model;
394}
395
396EAPI const char *
397eeze_disk_serial_get(Eeze_Disk *disk)
398{
399 EINA_SAFETY_ON_NULL_RETURN_VAL(disk, NULL);
400
401 if (disk->cache.serial)
402 return disk->cache.serial;
403 disk->cache.serial = udev_device_get_property_value(disk->device, "ID_SERIAL_SHORT");
404 return disk->cache.serial;
405}
406
407EAPI const char *
408eeze_disk_uuid_get(Eeze_Disk *disk)
409{
410 EINA_SAFETY_ON_NULL_RETURN_VAL(disk, NULL);
411
412 if (disk->cache.uuid)
413 return disk->cache.uuid;
414 disk->cache.uuid = udev_device_get_property_value(disk->device, "ID_FS_UUID");
415 return disk->cache.uuid;
416}
417
418EAPI const char *
419eeze_disk_label_get(Eeze_Disk *disk)
420{
421 EINA_SAFETY_ON_NULL_RETURN_VAL(disk, NULL);
422
423 if (disk->cache.label)
424 return disk->cache.label;
425 disk->cache.label = udev_device_get_property_value(disk->device, "ID_FS_LABEL");
426 return disk->cache.label;
427}
428
429EAPI Eeze_Disk_Type
430eeze_disk_type_get(Eeze_Disk *disk)
431{
432 EINA_SAFETY_ON_NULL_RETURN_VAL(disk, EEZE_DISK_TYPE_UNKNOWN);
433
434 if (disk->cache.type)
435 return disk->cache.type;
436 disk->cache.type = _eeze_disk_type_find(disk);
437 return disk->cache.type;
438}
439
440EAPI Eina_Bool
441eeze_disk_removable_get(Eeze_Disk *disk)
442{
443 const char *test;
444 EINA_SAFETY_ON_NULL_RETURN_VAL(disk, EINA_FALSE);
445
446 if (disk->cache.filled)
447 return disk->cache.removable;
448
449 test = udev_device_get_sysattr_value(disk->device, "removable");
450 if (test) disk->cache.removable = !!strtol(test, NULL, 10);
451 else
452 test = _walk_children_get_attr(disk->syspath, "removable", "block", EINA_FALSE);
453 if (test)
454 {
455 disk->cache.removable = !!strtol(test, NULL, 10);
456 eina_stringshare_del(test);
457 }
458 return disk->cache.removable;
459}
460
461EAPI Eina_Bool
462eeze_disk_can_mount(void)
463{
464 if (sizeof(EEZE_MOUNT_BIN) == sizeof(""))
465 return EINA_FALSE;
466 return access(EEZE_MOUNT_BIN, X_OK | R_OK) == 0;
467}
468
469EAPI Eina_Bool
470eeze_disk_can_unmount(void)
471{
472 if (sizeof(EEZE_UNMOUNT_BIN) == sizeof(""))
473 return EINA_FALSE;
474 return access(EEZE_UNMOUNT_BIN, X_OK | R_OK) == 0;
475}
476
477EAPI Eina_Bool
478eeze_disk_can_eject(void)
479{
480 if (sizeof(EEZE_EJECT_BIN) == sizeof(""))
481 return EINA_FALSE;
482 return access(EEZE_EJECT_BIN, X_OK | R_OK) == 0;
483}
diff --git a/src/lib/eeze/eeze_disk_libmount.c b/src/lib/eeze/eeze_disk_libmount.c
new file mode 100644
index 0000000000..9cc1980bb2
--- /dev/null
+++ b/src/lib/eeze/eeze_disk_libmount.c
@@ -0,0 +1,495 @@
1#ifdef HAVE_CONFIG_H
2#include "config.h"
3#endif
4
5#ifndef USE_UNSTABLE_LIBMOUNT_API
6# define USE_UNSTABLE_LIBMOUNT_API 1
7#endif
8
9#include <Ecore.h>
10#include <Eeze.h>
11#include <Eeze_Disk.h>
12#include <libmount.h>
13#include <unistd.h>
14
15#include "eeze_udev_private.h"
16#include "eeze_disk_private.h"
17
18/*
19 *
20 * PRIVATE
21 *
22 */
23
24static struct libmnt_optmap eeze_optmap[] =
25{
26 { "loop[=]", EEZE_DISK_MOUNTOPT_LOOP, 0 },
27 { "utf8", EEZE_DISK_MOUNTOPT_UTF8, 0 },
28 { "noexec", EEZE_DISK_MOUNTOPT_NOEXEC, 0 },
29 { "nosuid", EEZE_DISK_MOUNTOPT_NOSUID, 0 },
30 { "remount", EEZE_DISK_MOUNTOPT_REMOUNT, 0 },
31 { "uid[=]", EEZE_DISK_MOUNTOPT_UID, 0 },
32 { "nodev", EEZE_DISK_MOUNTOPT_NODEV, 0 },
33 { NULL, 0, 0 }
34};
35typedef struct libmnt_table libmnt_table;
36typedef struct libmnt_lock libmnt_lock;
37typedef struct libmnt_fs libmnt_fs;
38typedef struct libmnt_cache libmnt_cache;
39static Ecore_File_Monitor *_mtab_mon = NULL;
40static Ecore_File_Monitor *_fstab_mon = NULL;
41static Eina_Bool _watching = EINA_FALSE;
42static Eina_Bool _mtab_scan_active = EINA_FALSE;
43static Eina_Bool _mtab_locked = EINA_FALSE;
44static Eina_Bool _fstab_scan_active = EINA_FALSE;
45static libmnt_cache *_eeze_mount_mtab_cache = NULL;
46static libmnt_cache *_eeze_mount_fstab_cache = NULL;
47static libmnt_table *_eeze_mount_mtab = NULL;
48static libmnt_table *_eeze_mount_fstab = NULL;
49static libmnt_lock *_eeze_mtab_lock = NULL;
50extern Eina_List *_eeze_disks;
51
52static libmnt_table *_eeze_mount_tab_parse(const char *filename);
53static void _eeze_mount_tab_watcher(void *data, Ecore_File_Monitor *mon EINA_UNUSED, Ecore_File_Event event EINA_UNUSED, const char *path);
54
55static Eina_Bool
56_eeze_mount_lock_mtab(void)
57{
58// DBG("Locking mlock: %s", mnt_lock_get_linkfile(_eeze_mtab_lock));
59 if (EINA_LIKELY(access("/etc/mtab", W_OK)))
60 {
61 INF("Insufficient privs for mtab lock, continuing without lock");
62 return EINA_TRUE;
63 }
64 if (mnt_lock_file(_eeze_mtab_lock))
65 {
66 ERR("Couldn't lock mtab!");
67 return EINA_FALSE;
68 }
69 _mtab_locked = EINA_TRUE;
70 return EINA_TRUE;
71}
72
73static void
74_eeze_mount_unlock_mtab(void)
75{
76// DBG("Unlocking mlock: %s", mnt_lock_get_linkfile(_eeze_mtab_lock));
77 if (_mtab_locked) mnt_unlock_file(_eeze_mtab_lock);
78 _mtab_locked = EINA_FALSE;
79}
80
81
82static int
83_eeze_mount_tab_parse_errcb(libmnt_table *tab EINA_UNUSED, const char *filename, int line)
84{
85 ERR("%s:%d: could not parse line!", filename, line); /* most worthless error reporting ever. */
86 return -1;
87}
88
89/*
90 * I could use mnt_new_table_from_file() but this way gives much more detailed output
91 * on failure so why not
92 */
93static libmnt_table *
94_eeze_mount_tab_parse(const char *filename)
95{
96 libmnt_table *tab;
97
98 if (!(tab = mnt_new_table())) return NULL;
99 if (mnt_table_set_parser_errcb(tab, _eeze_mount_tab_parse_errcb))
100 {
101 ERR("Alloc!");
102 mnt_free_table(tab);
103 return NULL;
104 }
105
106 if (!mnt_table_parse_file(tab, filename))
107 return tab;
108
109 mnt_free_table(tab);
110 return NULL;
111}
112
113static void
114_eeze_mount_tab_watcher(void *data, Ecore_File_Monitor *mon EINA_UNUSED, Ecore_File_Event event EINA_UNUSED, const char *path)
115{
116 libmnt_table *bak;
117
118 if (
119 ((_mtab_scan_active) && (data)) || /* mtab has non-null data to avoid needing strcmp */
120 ((_fstab_scan_active) && (!data))
121 )
122 /* prevent scans from triggering a scan */
123 return;
124
125 bak = _eeze_mount_mtab;
126 if (data)
127 if (!_eeze_mount_lock_mtab())
128 { /* FIXME: maybe queue job here? */
129 ERR("Losing events...");
130 return;
131 }
132 _eeze_mount_mtab = _eeze_mount_tab_parse(path);
133 if (data)
134 _eeze_mount_unlock_mtab();
135 if (!_eeze_mount_mtab)
136 {
137 ERR("Could not parse %s! keeping old tab...", path);
138 goto error;
139 }
140 if (data)
141 {
142 Eina_List *l;
143 Eeze_Disk *disk;
144
145 /* catch externally initiated mounts on existing disks by comparing known mount state to current state */
146 EINA_LIST_FOREACH(_eeze_disks, l, disk)
147 {
148 Eina_Bool mounted;
149
150 mounted = disk->mounted;
151
152 if ((eeze_disk_libmount_mounted_get(disk) != mounted) && (!disk->mount_status))
153 {
154 if (!mounted)
155 {
156 Eeze_Event_Disk_Mount *e;
157 e = malloc(sizeof(Eeze_Event_Disk_Mount));
158 if (e)
159 {
160 e->disk = disk;
161 ecore_event_add(EEZE_EVENT_DISK_MOUNT, e, NULL, NULL);
162 }
163 }
164 else
165 {
166 Eeze_Event_Disk_Unmount *e;
167 e = malloc(sizeof(Eeze_Event_Disk_Unmount));
168 if (e)
169 {
170 e->disk = disk;
171 ecore_event_add(EEZE_EVENT_DISK_UNMOUNT, e, NULL, NULL);
172 }
173 }
174 }
175 }
176 }
177
178 mnt_free_table(bak);
179 if (data)
180 {
181 mnt_free_cache(_eeze_mount_mtab_cache);
182 _eeze_mount_mtab_cache = mnt_new_cache();
183 mnt_table_set_cache(_eeze_mount_mtab, _eeze_mount_mtab_cache);
184 }
185 else
186 {
187 mnt_free_cache(_eeze_mount_fstab_cache);
188 _eeze_mount_fstab_cache = mnt_new_cache();
189 mnt_table_set_cache(_eeze_mount_fstab, _eeze_mount_fstab_cache);
190 }
191 return;
192
193error:
194 mnt_free_table(_eeze_mount_mtab);
195 _eeze_mount_mtab = bak;
196}
197
198/*
199 *
200 * INVISIBLE
201 *
202 */
203
204Eina_Bool
205eeze_libmount_init(void)
206{
207 if (_eeze_mtab_lock)
208 return EINA_TRUE;
209 if (!(_eeze_mtab_lock = mnt_new_lock("/etc/mtab", 0)))
210 return EINA_FALSE;
211 return EINA_TRUE;
212}
213
214void
215eeze_libmount_shutdown(void)
216{
217 if (_eeze_mount_fstab)
218 {
219 mnt_free_table(_eeze_mount_fstab);
220 mnt_free_cache(_eeze_mount_fstab_cache);
221 }
222 if (_eeze_mount_mtab)
223 {
224 mnt_free_table(_eeze_mount_mtab);
225 mnt_free_cache(_eeze_mount_mtab_cache);
226 }
227 eeze_mount_tabs_unwatch();
228 if (!_eeze_mtab_lock)
229 return;
230
231 mnt_unlock_file(_eeze_mtab_lock);
232 mnt_free_lock(_eeze_mtab_lock);
233 _eeze_mtab_lock = NULL;
234}
235
236unsigned long
237eeze_disk_libmount_opts_get(Eeze_Disk *disk)
238{
239 libmnt_fs *mnt;
240 const char *opts;
241 unsigned long f = 0;
242
243 if (!eeze_mount_mtab_scan() || !eeze_mount_fstab_scan())
244 return 0;
245
246 mnt = mnt_table_find_tag(_eeze_mount_mtab, "UUID", eeze_disk_uuid_get(disk), MNT_ITER_BACKWARD);
247 if (!mnt)
248 mnt = mnt_table_find_tag(_eeze_mount_fstab, "UUID", eeze_disk_uuid_get(disk), MNT_ITER_BACKWARD);
249
250 if (!mnt) return 0;
251
252 opts = mnt_fs_get_fs_options(mnt);
253 if (!opts) return 0;
254 if (!mnt_optstr_get_flags(opts, &f, eeze_optmap)) return 0;
255 return f;
256}
257
258/*
259 * helper function to return whether a disk is mounted
260 */
261Eina_Bool
262eeze_disk_libmount_mounted_get(Eeze_Disk *disk)
263{
264 libmnt_fs *mnt;
265
266 if (!disk)
267 return EINA_FALSE;
268
269 if (!eeze_mount_mtab_scan() || !eeze_mount_fstab_scan())
270 return EINA_FALSE;
271
272 mnt = mnt_table_find_srcpath(_eeze_mount_mtab, eeze_disk_devpath_get(disk), MNT_ITER_BACKWARD);
273 if (!mnt)
274 {
275 disk->mounted = EINA_FALSE;
276 return EINA_FALSE;
277 }
278
279 eina_stringshare_replace(&disk->mount_point, mnt_fs_get_target(mnt));
280 disk->mounted = EINA_TRUE;
281 return EINA_TRUE;
282}
283
284
285/*
286 * helper function to return the device that is mounted at a mount point
287 */
288const char *
289eeze_disk_libmount_mp_find_source(const char *mount_point)
290{
291 libmnt_fs *mnt;
292
293 if (!mount_point)
294 return NULL;
295
296 if (!eeze_mount_mtab_scan() || !eeze_mount_fstab_scan())
297 return NULL;
298
299 mnt = mnt_table_find_target(_eeze_mount_mtab, mount_point, MNT_ITER_BACKWARD);
300 if (!mnt)
301 mnt = mnt_table_find_target(_eeze_mount_fstab, mount_point, MNT_ITER_BACKWARD);
302
303 if (!mnt)
304 return NULL;
305
306 return mnt_fs_get_source(mnt);
307}
308
309/*
310 * helper function to return a mount point from a uuid
311 */
312const char *
313eeze_disk_libmount_mp_lookup_by_uuid(const char *uuid)
314{
315 libmnt_fs *mnt;
316
317 if (!uuid)
318 return NULL;
319
320 if (!eeze_mount_mtab_scan() || !eeze_mount_fstab_scan())
321 return NULL;
322
323 mnt = mnt_table_find_tag(_eeze_mount_fstab, "UUID", uuid, MNT_ITER_BACKWARD);
324
325 if (!mnt)
326 return NULL;
327
328 return mnt_fs_get_target(mnt);
329}
330
331/*
332 * helper function to return a mount point from a label
333 */
334const char *
335eeze_disk_libmount_mp_lookup_by_label(const char *label)
336{
337 libmnt_fs *mnt;
338
339 if (!label)
340 return NULL;
341
342 if (!eeze_mount_mtab_scan() || !eeze_mount_fstab_scan())
343 return NULL;
344
345 mnt = mnt_table_find_tag(_eeze_mount_fstab, "LABEL", label, MNT_ITER_BACKWARD);
346
347 if (!mnt)
348 return NULL;
349
350 return mnt_fs_get_target(mnt);
351}
352
353/*
354 * helper function to return a mount point from a /dev/ path
355 */
356const char *
357eeze_disk_libmount_mp_lookup_by_devpath(const char *devpath)
358{
359 libmnt_fs *mnt;
360
361 if (!devpath)
362 return NULL;
363
364 if (!eeze_mount_mtab_scan() || !eeze_mount_fstab_scan())
365 return NULL;
366
367 mnt = mnt_table_find_srcpath(_eeze_mount_mtab, devpath, MNT_ITER_BACKWARD);
368 if (!mnt)
369 mnt = mnt_table_find_srcpath(_eeze_mount_fstab, devpath, MNT_ITER_BACKWARD);
370
371 if (!mnt)
372 return NULL;
373
374 return mnt_fs_get_target(mnt);
375}
376
377/*
378 *
379 * API
380 *
381 */
382
383EAPI Eina_Bool
384eeze_mount_tabs_watch(void)
385{
386 libmnt_table *bak;
387
388 if (_watching)
389 return EINA_TRUE;
390
391 if (!_eeze_mount_lock_mtab())
392 return EINA_FALSE;
393
394 bak = _eeze_mount_tab_parse("/etc/mtab");
395 _eeze_mount_unlock_mtab();
396 if (!bak)
397 goto error;
398
399 mnt_free_table(_eeze_mount_mtab);
400 _eeze_mount_mtab = bak;
401 if (!(bak = _eeze_mount_tab_parse("/etc/fstab")))
402 goto error;
403
404 mnt_free_table(_eeze_mount_fstab);
405 _eeze_mount_fstab = bak;
406
407 _eeze_mount_mtab_cache = mnt_new_cache();
408 mnt_table_set_cache(_eeze_mount_mtab, _eeze_mount_mtab_cache);
409
410 _eeze_mount_fstab_cache = mnt_new_cache();
411 mnt_table_set_cache(_eeze_mount_fstab, _eeze_mount_fstab_cache);
412
413 _mtab_mon = ecore_file_monitor_add("/etc/mtab", _eeze_mount_tab_watcher, (void*)1);
414 _fstab_mon = ecore_file_monitor_add("/etc/fstab", _eeze_mount_tab_watcher, NULL);
415 _watching = EINA_TRUE;
416
417 return EINA_TRUE;
418
419error:
420 if (!_eeze_mount_mtab)
421 ERR("Could not parse /etc/mtab!");
422 else
423 {
424 ERR("Could not parse /etc/fstab!");
425 mnt_free_table(_eeze_mount_mtab);
426 }
427 return EINA_FALSE;
428}
429
430EAPI void
431eeze_mount_tabs_unwatch(void)
432{
433 if (!_watching)
434 return;
435
436 ecore_file_monitor_del(_mtab_mon);
437 _mtab_mon = NULL;
438 ecore_file_monitor_del(_fstab_mon);
439 _fstab_mon = NULL;
440 _watching = EINA_FALSE;
441}
442
443EAPI Eina_Bool
444eeze_mount_mtab_scan(void)
445{
446 libmnt_table *bak;
447
448 if (_watching)
449 return EINA_TRUE;
450
451 if (!_eeze_mount_lock_mtab())
452 return EINA_FALSE;
453 bak = _eeze_mount_tab_parse("/etc/mtab");
454 _eeze_mount_unlock_mtab();
455 if (!bak)
456 goto error;
457 if (_eeze_mount_mtab)
458 {
459 mnt_free_table(_eeze_mount_mtab);
460 mnt_free_cache(_eeze_mount_mtab_cache);
461 }
462 _eeze_mount_mtab = bak;
463 _eeze_mount_mtab_cache = mnt_new_cache();
464 mnt_table_set_cache(_eeze_mount_mtab, _eeze_mount_mtab_cache);
465
466 return EINA_TRUE;
467
468error:
469 return EINA_FALSE;
470}
471
472EAPI Eina_Bool
473eeze_mount_fstab_scan(void)
474{
475 libmnt_table *bak;
476 if (_watching)
477 return EINA_TRUE;
478
479 bak = _eeze_mount_tab_parse("/etc/fstab");
480 if (!bak)
481 goto error;
482 if (_eeze_mount_fstab)
483 {
484 mnt_free_table(_eeze_mount_fstab);
485 mnt_free_cache(_eeze_mount_fstab_cache);
486 }
487 _eeze_mount_fstab = bak;
488 _eeze_mount_fstab_cache = mnt_new_cache();
489 mnt_table_set_cache(_eeze_mount_fstab, _eeze_mount_fstab_cache);
490
491 return EINA_TRUE;
492
493error:
494 return EINA_FALSE;
495}
diff --git a/src/lib/eeze/eeze_disk_libmount_new.c b/src/lib/eeze/eeze_disk_libmount_new.c
new file mode 100644
index 0000000000..aaae525b68
--- /dev/null
+++ b/src/lib/eeze/eeze_disk_libmount_new.c
@@ -0,0 +1,525 @@
1#ifdef HAVE_CONFIG_H
2#include "config.h"
3#endif
4
5#ifndef USE_UNSTABLE_LIBMOUNT_API
6# define USE_UNSTABLE_LIBMOUNT_API 1
7#endif
8
9#include <unistd.h>
10#include <sys/types.h>
11#include <sys/stat.h>
12#include <fcntl.h>
13
14#include <Ecore.h>
15#include <Eeze.h>
16#include <Eeze_Disk.h>
17#include <libmount.h>
18#include "eeze_udev_private.h"
19#include "eeze_disk_private.h"
20
21/*
22 *
23 * PRIVATE
24 *
25 */
26
27static struct libmnt_optmap eeze_optmap[] =
28{
29 { "loop[=]", EEZE_DISK_MOUNTOPT_LOOP, 0 },
30 { "utf8", EEZE_DISK_MOUNTOPT_UTF8, 0 },
31 { "noexec", EEZE_DISK_MOUNTOPT_NOEXEC, 0 },
32 { "nosuid", EEZE_DISK_MOUNTOPT_NOSUID, 0 },
33 { "remount", EEZE_DISK_MOUNTOPT_REMOUNT, 0 },
34 { "uid[=]", EEZE_DISK_MOUNTOPT_UID, 0 },
35 { "nodev", EEZE_DISK_MOUNTOPT_NODEV, 0 },
36 { NULL, 0, 0 }
37};
38typedef struct libmnt_table libmnt_table;
39typedef struct libmnt_fs libmnt_fs;
40typedef struct libmnt_cache libmnt_cache;
41static Ecore_File_Monitor *_fstab_mon = NULL;
42static Eina_Bool _watching = EINA_FALSE;
43static Eina_Bool _fstab_scan_active = EINA_FALSE;
44static libmnt_cache *_eeze_mount_mtab_cache = NULL;
45static libmnt_cache *_eeze_mount_fstab_cache = NULL;
46static libmnt_table *_eeze_mount_mtab = NULL;
47static libmnt_table *_eeze_mount_fstab = NULL;
48extern Eina_List *_eeze_disks;
49
50static Ecore_Fd_Handler *_mountinfo_fdh = NULL;
51static int _mountinfo = -1;
52
53static libmnt_table *_eeze_mount_tab_parse(const char *filename);
54static void _eeze_mount_tab_watcher(void *data, Ecore_File_Monitor *mon EINA_UNUSED, Ecore_File_Event event EINA_UNUSED, const char *path);
55
56static int
57_eeze_mount_tab_parse_errcb(libmnt_table *tab EINA_UNUSED, const char *filename, int line)
58{
59 ERR("%s:%d: could not parse line!", filename, line); /* most worthless error reporting ever. */
60 return -1;
61}
62
63/*
64 * I could use mnt_new_table_from_file() but this way gives much more detailed output
65 * on failure so why not
66 */
67static libmnt_table *
68_eeze_mount_tab_parse(const char *filename)
69{
70 libmnt_table *tab;
71
72 if (!(tab = mnt_new_table())) return NULL;
73 if (mnt_table_set_parser_errcb(tab, _eeze_mount_tab_parse_errcb))
74 {
75 ERR("Alloc!");
76 mnt_free_table(tab);
77 return NULL;
78 }
79
80 if (!mnt_table_parse_file(tab, filename))
81 return tab;
82
83 mnt_free_table(tab);
84 return NULL;
85}
86
87static void
88_eeze_mount_tab_watcher(void *data, Ecore_File_Monitor *mon EINA_UNUSED, Ecore_File_Event event EINA_UNUSED, const char *path)
89{
90 libmnt_table *bak;
91
92 if (_fstab_scan_active)
93 /* prevent scans from triggering a scan */
94 return;
95
96 bak = _eeze_mount_mtab;
97 _eeze_mount_mtab = _eeze_mount_tab_parse(path);
98 if (!_eeze_mount_mtab)
99 {
100 ERR("Could not parse %s! keeping old tab...", path);
101 goto error;
102 }
103
104 mnt_free_table(bak);
105 if (data)
106 {
107 mnt_free_cache(_eeze_mount_mtab_cache);
108 _eeze_mount_mtab_cache = mnt_new_cache();
109 mnt_table_set_cache(_eeze_mount_mtab, _eeze_mount_mtab_cache);
110 }
111 else
112 {
113 mnt_free_cache(_eeze_mount_fstab_cache);
114 _eeze_mount_fstab_cache = mnt_new_cache();
115 mnt_table_set_cache(_eeze_mount_fstab, _eeze_mount_fstab_cache);
116 }
117 return;
118
119error:
120 mnt_free_table(_eeze_mount_mtab);
121 _eeze_mount_mtab = bak;
122}
123
124/* on tab change, check differences
125 * based on code from findmnt
126 */
127static Eina_Bool
128_eeze_mount_fdh(void *d EINA_UNUSED, Ecore_Fd_Handler *fdh EINA_UNUSED)
129{
130 libmnt_table *tb_new;
131 libmnt_fs *old, *new;
132 int change;
133 struct libmnt_iter *itr = NULL;
134 struct libmnt_tabdiff *diff = NULL;
135
136 tb_new = mnt_new_table();
137 EINA_SAFETY_ON_NULL_RETURN_VAL(tb_new, ECORE_CALLBACK_RENEW);
138 EINA_SAFETY_ON_TRUE_GOTO(mnt_table_set_parser_errcb(tb_new, _eeze_mount_tab_parse_errcb), err);
139 itr = mnt_new_iter(MNT_ITER_BACKWARD);
140 EINA_SAFETY_ON_NULL_GOTO(itr, err);
141 diff = mnt_new_tabdiff();
142 EINA_SAFETY_ON_NULL_GOTO(diff, err);
143 if (mnt_table_parse_file(tb_new, "/proc/self/mountinfo"))
144 {
145 ERR("PARSING FAILED FOR /proc/self/mountinfo! THIS IS WEIRD!");
146 goto err;
147 }
148 change = mnt_diff_tables(diff, _eeze_mount_mtab, tb_new);
149 if (change < 0)
150 {
151 ERR("DIFFING FAILED FOR /proc/self/mountinfo! THIS IS ALSO WEIRD!");
152 goto err;
153 }
154 if (!change) goto err;
155 while (!mnt_tabdiff_next_change(diff, itr, &old, &new, &change))
156 {
157 const char *src;
158 Eeze_Disk *disk;
159 Eina_Bool found = EINA_FALSE;
160 Eeze_Event_Disk_Mount *e;
161 Eina_List *l;
162
163 src = mnt_fs_get_source(new);
164 if (!src) continue;
165 EINA_LIST_FOREACH(_eeze_disks, l, disk)
166 {
167 if (!strcmp(src, eeze_disk_devpath_get(disk)))
168 {
169 found = EINA_TRUE;
170 break;
171 }
172 }
173 if (!found) continue;
174 switch (change)
175 {
176 case MNT_TABDIFF_MOUNT:
177 disk->mounted = EINA_TRUE;
178 eina_stringshare_replace(&disk->mount_point, mnt_fs_get_target(new));
179 if (disk->mount_status) break;
180 e = malloc(sizeof(Eeze_Event_Disk_Mount));
181 if (e)
182 {
183 e->disk = disk;
184 ecore_event_add(EEZE_EVENT_DISK_MOUNT, e, NULL, NULL);
185 }
186 break;
187 case MNT_TABDIFF_UMOUNT:
188 if (!mnt_fs_get_target(new))
189 disk->mounted = EINA_FALSE;
190 eina_stringshare_replace(&disk->mount_point, NULL);
191 if (disk->mount_status) break;
192 e = malloc(sizeof(Eeze_Event_Disk_Mount));
193 if (e)
194 {
195 e->disk = disk;
196 ecore_event_add(EEZE_EVENT_DISK_UNMOUNT, e, NULL, NULL);
197 }
198 break;
199 /* anything could have happened here, send both events to flush */
200 case MNT_TABDIFF_REMOUNT:
201 case MNT_TABDIFF_MOVE:
202 if (!mnt_fs_get_target(new))
203 disk->mounted = EINA_FALSE;
204 eina_stringshare_replace(&disk->mount_point, mnt_fs_get_target(new));
205 if (disk->mount_status) break;
206 e = malloc(sizeof(Eeze_Event_Disk_Mount));
207 if (e)
208 {
209 e->disk = disk;
210 ecore_event_add(EEZE_EVENT_DISK_UNMOUNT, e, NULL, NULL);
211 }
212 e = malloc(sizeof(Eeze_Event_Disk_Mount));
213 if (e)
214 {
215 e->disk = disk;
216 ecore_event_add(EEZE_EVENT_DISK_MOUNT, e, NULL, NULL);
217 }
218 default:
219 break;
220 }
221 }
222
223 mnt_free_cache(_eeze_mount_mtab_cache);
224 _eeze_mount_mtab_cache = mnt_new_cache();
225 mnt_table_set_cache(_eeze_mount_mtab, _eeze_mount_mtab_cache);
226 mnt_free_table(_eeze_mount_mtab);
227 _eeze_mount_mtab = tb_new;
228 return ECORE_CALLBACK_RENEW;
229err:
230 if (tb_new) mnt_free_table(tb_new);
231 if (itr) mnt_free_iter(itr);
232 if (diff) mnt_free_tabdiff(diff);
233 return ECORE_CALLBACK_RENEW;
234}
235
236/*
237 *
238 * INVISIBLE
239 *
240 */
241
242Eina_Bool
243eeze_libmount_init(void)
244{
245 /* placeholder */
246 return EINA_TRUE;
247}
248
249void
250eeze_libmount_shutdown(void)
251{
252 if (_eeze_mount_fstab)
253 {
254 mnt_free_table(_eeze_mount_fstab);
255 mnt_free_cache(_eeze_mount_fstab_cache);
256 }
257 if (_eeze_mount_mtab)
258 {
259 mnt_free_table(_eeze_mount_mtab);
260 mnt_free_cache(_eeze_mount_mtab_cache);
261 }
262 eeze_mount_tabs_unwatch();
263}
264
265unsigned long
266eeze_disk_libmount_opts_get(Eeze_Disk *disk)
267{
268 libmnt_fs *mnt;
269 const char *opts;
270 unsigned long f = 0;
271
272 if (!eeze_mount_mtab_scan() || !eeze_mount_fstab_scan())
273 return 0;
274
275 mnt = mnt_table_find_tag(_eeze_mount_mtab, "UUID", eeze_disk_uuid_get(disk), MNT_ITER_BACKWARD);
276 if (!mnt)
277 mnt = mnt_table_find_tag(_eeze_mount_fstab, "UUID", eeze_disk_uuid_get(disk), MNT_ITER_BACKWARD);
278
279 if (!mnt) return 0;
280
281 opts = mnt_fs_get_fs_options(mnt);
282 if (!opts) return 0;
283 if (!mnt_optstr_get_flags(opts, &f, eeze_optmap)) return 0;
284 return f;
285}
286
287/*
288 * helper function to return whether a disk is mounted
289 */
290Eina_Bool
291eeze_disk_libmount_mounted_get(Eeze_Disk *disk)
292{
293 libmnt_fs *mnt;
294
295 if (!disk)
296 return EINA_FALSE;
297
298 if (!eeze_mount_mtab_scan() || !eeze_mount_fstab_scan())
299 return EINA_FALSE;
300
301 mnt = mnt_table_find_source(_eeze_mount_mtab, eeze_disk_devpath_get(disk), MNT_ITER_BACKWARD);
302 if (!mnt)
303 {
304 disk->mounted = EINA_FALSE;
305 return EINA_FALSE;
306 }
307
308 eina_stringshare_replace(&disk->mount_point, mnt_fs_get_target(mnt));
309 disk->mounted = EINA_TRUE;
310 return EINA_TRUE;
311}
312
313
314/*
315 * helper function to return the device that is mounted at a mount point
316 */
317const char *
318eeze_disk_libmount_mp_find_source(const char *mount_point)
319{
320 libmnt_fs *mnt;
321
322 if (!mount_point)
323 return NULL;
324
325 if (!eeze_mount_mtab_scan() || !eeze_mount_fstab_scan())
326 return NULL;
327
328 mnt = mnt_table_find_target(_eeze_mount_mtab, mount_point, MNT_ITER_BACKWARD);
329 if (!mnt)
330 mnt = mnt_table_find_target(_eeze_mount_fstab, mount_point, MNT_ITER_BACKWARD);
331
332 if (!mnt)
333 return NULL;
334
335 return mnt_fs_get_source(mnt);
336}
337
338/*
339 * helper function to return a mount point from a uuid
340 */
341const char *
342eeze_disk_libmount_mp_lookup_by_uuid(const char *uuid)
343{
344 libmnt_fs *mnt;
345
346 if (!uuid)
347 return NULL;
348
349 if (!eeze_mount_mtab_scan() || !eeze_mount_fstab_scan())
350 return NULL;
351
352 mnt = mnt_table_find_tag(_eeze_mount_fstab, "UUID", uuid, MNT_ITER_BACKWARD);
353
354 if (!mnt)
355 return NULL;
356
357 return mnt_fs_get_target(mnt);
358}
359
360/*
361 * helper function to return a mount point from a label
362 */
363const char *
364eeze_disk_libmount_mp_lookup_by_label(const char *label)
365{
366 libmnt_fs *mnt;
367
368 if (!label)
369 return NULL;
370
371 if (!eeze_mount_mtab_scan() || !eeze_mount_fstab_scan())
372 return NULL;
373
374 mnt = mnt_table_find_tag(_eeze_mount_fstab, "LABEL", label, MNT_ITER_BACKWARD);
375
376 if (!mnt)
377 return NULL;
378
379 return mnt_fs_get_target(mnt);
380}
381
382/*
383 * helper function to return a mount point from a /dev/ path
384 */
385const char *
386eeze_disk_libmount_mp_lookup_by_devpath(const char *devpath)
387{
388 libmnt_fs *mnt;
389
390 if (!devpath)
391 return NULL;
392
393 if (!eeze_mount_mtab_scan() || !eeze_mount_fstab_scan())
394 return NULL;
395
396 mnt = mnt_table_find_srcpath(_eeze_mount_mtab, devpath, MNT_ITER_BACKWARD);
397 if (!mnt)
398 mnt = mnt_table_find_srcpath(_eeze_mount_fstab, devpath, MNT_ITER_BACKWARD);
399
400 if (!mnt)
401 return NULL;
402
403 return mnt_fs_get_target(mnt);
404}
405
406/*
407 *
408 * API
409 *
410 */
411
412EAPI Eina_Bool
413eeze_mount_tabs_watch(void)
414{
415 libmnt_table *bak;
416
417 if (_watching)
418 return EINA_TRUE;
419
420 bak = _eeze_mount_tab_parse("/proc/self/mountinfo");
421 EINA_SAFETY_ON_NULL_GOTO(bak, error);
422
423 mnt_free_table(_eeze_mount_mtab);
424 _eeze_mount_mtab = bak;
425 bak = _eeze_mount_tab_parse("/etc/fstab");
426 EINA_SAFETY_ON_NULL_GOTO(bak, error);
427
428 mnt_free_table(_eeze_mount_fstab);
429 _eeze_mount_fstab = bak;
430
431 _eeze_mount_mtab_cache = mnt_new_cache();
432 mnt_table_set_cache(_eeze_mount_mtab, _eeze_mount_mtab_cache);
433
434 _eeze_mount_fstab_cache = mnt_new_cache();
435 mnt_table_set_cache(_eeze_mount_fstab, _eeze_mount_fstab_cache);
436
437 _mountinfo = open("/proc/self/mountinfo", O_RDONLY, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
438 if (_mountinfo < 0) goto error;
439 if (fcntl(_mountinfo, F_SETFL, O_NONBLOCK) < 0) goto error;
440
441 _mountinfo_fdh = ecore_main_fd_handler_file_add(_mountinfo, ECORE_FD_ERROR, _eeze_mount_fdh, NULL, NULL, NULL);
442 if (!_mountinfo_fdh) goto error;
443 _fstab_mon = ecore_file_monitor_add("/etc/fstab", _eeze_mount_tab_watcher, NULL);
444 _watching = EINA_TRUE;
445
446 return EINA_TRUE;
447
448error:
449 if (_mountinfo >= 0) close(_mountinfo);
450 _mountinfo = -1;
451 if (!_eeze_mount_mtab)
452 ERR("Could not parse /proc/self/mountinfo!");
453 else
454 {
455 ERR("Could not parse /etc/fstab!");
456 mnt_free_table(_eeze_mount_mtab);
457 }
458 _eeze_mount_mtab = _eeze_mount_fstab = NULL;
459 return EINA_FALSE;
460}
461
462EAPI void
463eeze_mount_tabs_unwatch(void)
464{
465 if (!_watching)
466 return;
467
468 ecore_main_fd_handler_del(_mountinfo_fdh);
469 ecore_file_monitor_del(_fstab_mon);
470 close(_mountinfo);
471 _mountinfo = -1;
472 _fstab_mon = NULL;
473 _watching = EINA_FALSE;
474}
475
476EAPI Eina_Bool
477eeze_mount_mtab_scan(void)
478{
479 libmnt_table *bak;
480
481 if (_watching)
482 return EINA_TRUE;
483
484 bak = _eeze_mount_tab_parse("/proc/self/mountinfo");
485 if (!bak)
486 goto error;
487 if (_eeze_mount_mtab)
488 {
489 mnt_free_table(_eeze_mount_mtab);
490 mnt_free_cache(_eeze_mount_mtab_cache);
491 }
492 _eeze_mount_mtab = bak;
493 _eeze_mount_mtab_cache = mnt_new_cache();
494 mnt_table_set_cache(_eeze_mount_mtab, _eeze_mount_mtab_cache);
495
496 return EINA_TRUE;
497
498error:
499 return EINA_FALSE;
500}
501
502EAPI Eina_Bool
503eeze_mount_fstab_scan(void)
504{
505 libmnt_table *bak;
506 if (_watching)
507 return EINA_TRUE;
508
509 bak = _eeze_mount_tab_parse("/etc/fstab");
510 if (!bak)
511 goto error;
512 if (_eeze_mount_fstab)
513 {
514 mnt_free_table(_eeze_mount_fstab);
515 mnt_free_cache(_eeze_mount_fstab_cache);
516 }
517 _eeze_mount_fstab = bak;
518 _eeze_mount_fstab_cache = mnt_new_cache();
519 mnt_table_set_cache(_eeze_mount_fstab, _eeze_mount_fstab_cache);
520
521 return EINA_TRUE;
522
523error:
524 return EINA_FALSE;
525}
diff --git a/src/lib/eeze/eeze_disk_mount.c b/src/lib/eeze/eeze_disk_mount.c
new file mode 100644
index 0000000000..bfbf8f0781
--- /dev/null
+++ b/src/lib/eeze/eeze_disk_mount.c
@@ -0,0 +1,461 @@
1#ifdef HAVE_CONFIG_H
2#include "config.h"
3#endif
4
5#include <unistd.h>
6#include <sys/stat.h>
7#include <sys/types.h>
8#include <errno.h>
9
10#include <Ecore.h>
11#include <Eeze.h>
12#include <Eeze_Disk.h>
13
14#include "eeze_udev_private.h"
15#include "eeze_disk_private.h"
16
17#define EEZE_MOUNT_DEFAULT_OPTS "noexec,nosuid,utf8"
18
19EAPI int EEZE_EVENT_DISK_MOUNT = 0;
20EAPI int EEZE_EVENT_DISK_UNMOUNT = 0;
21EAPI int EEZE_EVENT_DISK_EJECT = 0;
22EAPI int EEZE_EVENT_DISK_ERROR = 0;
23static Ecore_Event_Handler *_mount_handler = NULL;
24Eina_List *eeze_events = NULL;
25
26/*
27 *
28 * PRIVATE
29 *
30 */
31
32static void
33_eeze_disk_mount_error_free(void *data EINA_UNUSED, Eeze_Event_Disk_Error *de)
34{
35 if (!de)
36 return;
37
38 eina_stringshare_del(de->message);
39 free(de);
40}
41
42static void
43_eeze_disk_mount_error_handler(Eeze_Disk *disk, const char *error)
44{
45 Eeze_Event_Disk_Error *de;
46
47 ERR("%s", error);
48 if (!(de = calloc(1, sizeof(Eeze_Event_Disk_Error))))
49 return;
50
51 de->disk = disk;
52 de->message = eina_stringshare_add(error);
53 /* FIXME: placeholder since currently there are only mount-type errors */
54 ecore_event_add(EEZE_EVENT_DISK_ERROR, de, (Ecore_End_Cb)_eeze_disk_mount_error_free, NULL);
55}
56
57static Eina_Bool
58_eeze_disk_mount_result_handler(void *data EINA_UNUSED, int type EINA_UNUSED, Ecore_Exe_Event_Del *ev)
59{
60 Eeze_Disk *disk;
61 Eina_List *l;
62 Eeze_Event_Disk_Mount *e;
63
64 if ((!ev) || (!ev->exe))
65 return ECORE_CALLBACK_RENEW;
66 disk = ecore_exe_data_get(ev->exe);
67
68 if ((!disk) || (!eeze_events) || (!(l = eina_list_data_find_list(eeze_events, disk))))
69 return ECORE_CALLBACK_RENEW;
70
71 eeze_events = eina_list_remove_list(eeze_events, l);
72 if (!disk->mounter) /* killed */
73 {
74 disk->mount_status = EEZE_DISK_NULL;
75 return ECORE_CALLBACK_RENEW;
76 }
77 if (disk->mount_status == EEZE_DISK_MOUNTING)
78 {
79 disk->mounter = NULL;
80 if (!ev->exit_code)
81 {
82 disk->mounted = EINA_TRUE;
83 e = malloc(sizeof(Eeze_Event_Disk_Mount));
84 EINA_SAFETY_ON_NULL_RETURN_VAL(e, ECORE_CALLBACK_RENEW);
85 e->disk = disk;
86 ecore_event_add(EEZE_EVENT_DISK_MOUNT, e, NULL, NULL);
87 }
88 else if (ev->exit_code & 2)
89 _eeze_disk_mount_error_handler(disk, "system error (out of memory, cannot fork, no more loop devices)");
90 else if (ev->exit_code & 4)
91 _eeze_disk_mount_error_handler(disk, "internal mount bug");
92 else if (ev->exit_code & 8)
93 _eeze_disk_mount_error_handler(disk, "user interrupt");
94 else if (ev->exit_code & 16)
95 _eeze_disk_mount_error_handler(disk, "problems writing or locking /etc/mtab");
96 else if (ev->exit_code & 32)
97 _eeze_disk_mount_error_handler(disk, "mount failure");
98 else if (ev->exit_code & 64)
99 _eeze_disk_mount_error_handler(disk, "some mount succeeded");
100 else
101 _eeze_disk_mount_error_handler(disk, "incorrect invocation or permissions");
102 }
103 else if (disk->mount_status == EEZE_DISK_UNMOUNTING)
104 switch (ev->exit_code)
105 {
106 case 0:
107 e = malloc(sizeof(Eeze_Event_Disk_Unmount));
108 EINA_SAFETY_ON_NULL_RETURN_VAL(e, ECORE_CALLBACK_RENEW);
109 e->disk = disk;
110 disk->mounter = NULL;
111 disk->mounted = EINA_FALSE;
112 ecore_event_add(EEZE_EVENT_DISK_UNMOUNT, e, NULL, NULL);
113 break;
114
115 default:
116 if (disk->mount_fail_count++ < 3)
117 {
118 INF("Could not unmount disk, retrying");
119 disk->mounter = ecore_exe_run(eina_strbuf_string_get(disk->unmount_cmd), disk);
120 eeze_events = eina_list_append(eeze_events, disk);
121 }
122 else
123 {
124 disk->mount_fail_count = 0;
125 _eeze_disk_mount_error_handler(disk, "Maximimum number of mount-related failures reached");
126 }
127 return ECORE_CALLBACK_RENEW;
128 }
129 else
130 switch (ev->exit_code)
131 {
132 case 0:
133 e = malloc(sizeof(Eeze_Event_Disk_Eject));
134 EINA_SAFETY_ON_NULL_RETURN_VAL(e, ECORE_CALLBACK_RENEW);
135 e->disk = disk;
136 disk->mounter = NULL;
137 if (disk->mount_status & EEZE_DISK_UNMOUNTING)
138 {
139 disk->mount_status |= EEZE_DISK_UNMOUNTING;
140 disk->mounted = EINA_FALSE;
141 ecore_event_add(EEZE_EVENT_DISK_UNMOUNT, e, NULL, NULL);
142 eeze_disk_eject(disk);
143 }
144 else
145 ecore_event_add(EEZE_EVENT_DISK_EJECT, e, NULL, NULL);
146 break;
147
148 default:
149 if (disk->mount_fail_count++ < 3)
150 {
151 INF("Could not eject disk, retrying");
152 if (disk->mount_status & EEZE_DISK_UNMOUNTING)
153 disk->mounter = ecore_exe_run(eina_strbuf_string_get(disk->unmount_cmd), disk);
154 else
155 disk->mounter = ecore_exe_run(eina_strbuf_string_get(disk->eject_cmd), disk);
156 eeze_events = eina_list_append(eeze_events, disk);
157 }
158 else
159 {
160 disk->mount_fail_count = 0;
161 _eeze_disk_mount_error_handler(disk, "Maximimum number of mount-related failures reached");
162 }
163 return ECORE_CALLBACK_RENEW;
164 }
165 return ECORE_CALLBACK_RENEW;
166}
167
168/*
169 *
170 * INVISIBLE
171 *
172 */
173
174Eina_Bool
175eeze_mount_init(void)
176{
177 EEZE_EVENT_DISK_MOUNT = ecore_event_type_new();
178 EEZE_EVENT_DISK_UNMOUNT = ecore_event_type_new();
179 EEZE_EVENT_DISK_EJECT = ecore_event_type_new();
180 EEZE_EVENT_DISK_ERROR = ecore_event_type_new();
181 _mount_handler = ecore_event_handler_add(ECORE_EXE_EVENT_DEL,
182 (Ecore_Event_Handler_Cb)_eeze_disk_mount_result_handler, NULL);
183 return eeze_libmount_init();
184}
185
186void
187eeze_mount_shutdown(void)
188{
189 eeze_libmount_shutdown();
190 ecore_event_handler_del(_mount_handler);
191 _mount_handler = NULL;
192}
193
194/*
195 *
196 * API
197 *
198 */
199
200EAPI Eina_Bool
201eeze_disk_mounted_get(Eeze_Disk *disk)
202{
203 EINA_SAFETY_ON_NULL_RETURN_VAL(disk, EINA_FALSE);
204
205 return eeze_disk_libmount_mounted_get(disk);
206}
207
208EAPI Eina_Bool
209eeze_disk_mountopts_set(Eeze_Disk *disk, unsigned long opts)
210{
211 EINA_SAFETY_ON_NULL_RETURN_VAL(disk, EINA_FALSE);
212 if (opts != disk->mount_opts)
213 disk->mount_cmd_changed = EINA_TRUE;
214 disk->mount_opts = opts;
215 if (opts & EEZE_DISK_MOUNTOPT_UID)
216 disk->uid = getuid();
217 return EINA_TRUE;
218}
219
220EAPI unsigned long
221eeze_disk_mountopts_get(Eeze_Disk *disk)
222{
223 EINA_SAFETY_ON_NULL_RETURN_VAL(disk, 0);
224 return disk->mount_opts;
225}
226
227EAPI Eina_Bool
228eeze_disk_mount_wrapper_set(Eeze_Disk *disk, const char *wrapper)
229{
230 EINA_SAFETY_ON_NULL_RETURN_VAL(disk, EINA_FALSE);
231 if (wrapper) EINA_SAFETY_ON_TRUE_RETURN_VAL(!*wrapper, EINA_FALSE);
232 else
233 {
234 eina_stringshare_del(disk->mount_wrapper);
235 disk->mount_wrapper = NULL;
236 return EINA_TRUE;
237 }
238 eina_stringshare_replace(&disk->mount_wrapper, wrapper);
239 return EINA_TRUE;
240}
241
242EAPI const char *
243eeze_disk_mount_wrapper_get(Eeze_Disk *disk)
244{
245 EINA_SAFETY_ON_NULL_RETURN_VAL(disk, NULL);
246 return disk->mount_wrapper;
247}
248
249EAPI Eina_Bool
250eeze_disk_mount(Eeze_Disk *disk)
251{
252 struct stat st;
253 EINA_SAFETY_ON_NULL_RETURN_VAL(disk, EINA_FALSE);
254
255 if ((!disk->mount_point) && eeze_disk_libmount_mounted_get(disk))
256 return EINA_FALSE;
257
258 if (!disk->mount_cmd)
259 disk->mount_cmd = eina_strbuf_new();
260
261 if (disk->mount_cmd_changed)
262 {
263 const char *dev, *str;
264 eina_strbuf_string_free(disk->mount_cmd);
265 dev = eeze_disk_uuid_get(disk);
266 if (dev) str = "UUID=";
267 else
268 {
269 dev = eeze_disk_devpath_get(disk);
270 str = NULL;
271 }
272
273 if (!disk->mount_point)
274 {
275 const char *mp;
276 /* here we attempt to guess the mount point using libmount */
277 mp = eeze_disk_libmount_mp_lookup_by_uuid(disk->cache.uuid);
278 if (!mp)
279 {
280 const char *devpath;
281
282 devpath = eeze_disk_devpath_get(disk);
283 if (devpath)
284 {
285 mp = eeze_disk_libmount_mp_lookup_by_devpath(devpath);
286 eina_stringshare_del(devpath);
287 }
288 }
289 if (!eeze_disk_mount_point_set(disk, mp))
290 /* sometimes we fail */
291 return EINA_FALSE;
292 }
293
294 if ((!disk->mount_point) || (!disk->mount_point[0])) return EINA_FALSE;
295 if (disk->mount_wrapper)
296 eina_strbuf_append_printf(disk->mount_cmd, "%s ", disk->mount_wrapper);
297 if (disk->mount_opts == EEZE_DISK_MOUNTOPT_DEFAULTS)
298 eina_strbuf_append_printf(disk->mount_cmd, EEZE_MOUNT_BIN" -o "EEZE_MOUNT_DEFAULT_OPTS" %s%s %s", str ?: "", dev, disk->mount_point);
299 else if (!disk->mount_opts)
300 eina_strbuf_append_printf(disk->mount_cmd, EEZE_MOUNT_BIN" %s%s %s", str ?: "", dev, disk->mount_point);
301 else
302 {
303 eina_strbuf_append(disk->mount_cmd, EEZE_MOUNT_BIN" -o ");
304 /* trailing commas are okay */
305 if (disk->mount_opts & EEZE_DISK_MOUNTOPT_LOOP)
306 eina_strbuf_append(disk->mount_cmd, "loop,");
307 if (disk->mount_opts & EEZE_DISK_MOUNTOPT_UTF8)
308 {
309 const char *fstype;
310 eina_strbuf_append(disk->mount_cmd, "utf8,");
311 fstype = eeze_disk_fstype_get(disk);
312 if (fstype && (!strcmp(fstype, "jfs")))
313 eina_strbuf_append(disk->mount_cmd, "iocharset=utf8,");
314 }
315 if (disk->mount_opts & EEZE_DISK_MOUNTOPT_NOEXEC)
316 eina_strbuf_append(disk->mount_cmd, "noexec,");
317 if (disk->mount_opts & EEZE_DISK_MOUNTOPT_NODEV)
318 eina_strbuf_append(disk->mount_cmd, "nodev,");
319 if (disk->mount_opts & EEZE_DISK_MOUNTOPT_NOSUID)
320 eina_strbuf_append(disk->mount_cmd, "nosuid,");
321 if (disk->mount_opts & EEZE_DISK_MOUNTOPT_REMOUNT)
322 eina_strbuf_append(disk->mount_cmd, "remount,");
323 if (disk->mount_opts & EEZE_DISK_MOUNTOPT_UID)
324 eina_strbuf_append_printf(disk->mount_cmd, "uid=%i,", (int)disk->uid);
325 eina_strbuf_append_printf(disk->mount_cmd, " %s%s %s", str ?: "", dev, disk->mount_point);
326 }
327 disk->mount_cmd_changed = EINA_FALSE;
328 }
329
330 if (stat(disk->mount_point, &st))
331 {
332 INF("Creating not-existing mount point directory '%s'", disk->mount_point);
333 if (mkdir(disk->mount_point, S_IROTH | S_IWOTH | S_IXOTH))
334 ERR("Could not create directory: %s; hopefully this is handled by your mounter!", strerror(errno));
335 }
336 else if (!S_ISDIR(st.st_mode))
337 {
338 ERR("%s is not a directory!", disk->mount_point);
339 return EINA_FALSE;
340 }
341 INF("Mounting: %s", eina_strbuf_string_get(disk->mount_cmd));
342 disk->mounter = ecore_exe_run(eina_strbuf_string_get(disk->mount_cmd), disk);
343 if (!disk->mounter)
344 return EINA_FALSE;
345 eeze_events = eina_list_append(eeze_events, disk);
346 disk->mount_status = EEZE_DISK_MOUNTING;
347
348 return EINA_TRUE;
349}
350
351EAPI Eina_Bool
352eeze_disk_unmount(Eeze_Disk *disk)
353{
354 EINA_SAFETY_ON_NULL_RETURN_VAL(disk, EINA_FALSE);
355
356 if (!eeze_disk_libmount_mounted_get(disk))
357 return EINA_TRUE;
358
359 if (!disk->unmount_cmd)
360 disk->unmount_cmd = eina_strbuf_new();
361
362 if (disk->unmount_cmd_changed)
363 {
364 eina_strbuf_string_free(disk->unmount_cmd);
365 if (disk->mount_wrapper)
366 eina_strbuf_append_printf(disk->unmount_cmd, "%s ", disk->mount_wrapper);
367 eina_strbuf_append_printf(disk->unmount_cmd, EEZE_UNMOUNT_BIN" %s", eeze_disk_devpath_get(disk));
368 disk->unmount_cmd_changed = EINA_FALSE;
369 }
370
371 INF("Unmounting: %s", eina_strbuf_string_get(disk->unmount_cmd));
372 disk->mounter = ecore_exe_run(eina_strbuf_string_get(disk->unmount_cmd), disk);
373 if (!disk->mounter)
374 return EINA_FALSE;
375
376 eeze_events = eina_list_append(eeze_events, disk);
377 disk->mount_status = EEZE_DISK_UNMOUNTING;
378 return EINA_TRUE;
379}
380
381EAPI Eina_Bool
382eeze_disk_eject(Eeze_Disk *disk)
383{
384 EINA_SAFETY_ON_NULL_RETURN_VAL(disk, EINA_FALSE);
385
386 if (!disk->eject_cmd)
387 {
388 disk->eject_cmd = eina_strbuf_new();
389 if (disk->mount_wrapper)
390 eina_strbuf_append_printf(disk->eject_cmd, "%s ", disk->mount_wrapper);
391 eina_strbuf_append_printf(disk->eject_cmd, EEZE_EJECT_BIN" %s", eeze_disk_devpath_get(disk));
392 }
393
394 INF("Ejecting: %s", eina_strbuf_string_get(disk->eject_cmd));
395 if (eeze_disk_libmount_mounted_get(disk))
396 {
397 Eina_Bool ret;
398
399 ret = eeze_disk_unmount(disk);
400 if (ret) disk->mount_status |= EEZE_DISK_EJECTING;
401 return ret;
402 }
403 disk->mounter = ecore_exe_run(eina_strbuf_string_get(disk->eject_cmd), disk);
404 if (!disk->mounter)
405 return EINA_FALSE;
406
407 eeze_events = eina_list_append(eeze_events, disk);
408 disk->mount_status = EEZE_DISK_EJECTING;
409 return EINA_TRUE;
410}
411
412EAPI void
413eeze_disk_cancel(Eeze_Disk *disk)
414{
415 EINA_SAFETY_ON_NULL_RETURN(disk);
416 if ((!disk->mount_status) || (!disk->mounter)) return;
417 disk->mount_status = EEZE_DISK_NULL;
418 ecore_exe_kill(disk->mounter);
419 disk->mounter = NULL;
420}
421
422EAPI const char *
423eeze_disk_mount_point_get(Eeze_Disk *disk)
424{
425 const char *mp;
426 EINA_SAFETY_ON_NULL_RETURN_VAL(disk, NULL);
427
428 if (disk->mount_point)
429 return disk->mount_point;
430
431 mp = eeze_disk_libmount_mp_lookup_by_devpath(eeze_disk_devpath_get(disk));
432 if (mp)
433 {
434 disk->mount_point = eina_stringshare_add(mp);
435 return disk->mount_point;
436 }
437 mp = eeze_disk_libmount_mp_lookup_by_uuid(eeze_disk_uuid_get(disk));
438 if (mp)
439 {
440 disk->mount_point = eina_stringshare_add(mp);
441 return disk->mount_point;
442 }
443 mp = eeze_disk_libmount_mp_lookup_by_label(eeze_disk_label_get(disk));
444 if (mp)
445 {
446 disk->mount_point = eina_stringshare_add(mp);
447 return disk->mount_point;
448 }
449 return NULL;
450}
451
452EAPI Eina_Bool
453eeze_disk_mount_point_set(Eeze_Disk *disk, const char *mount_point)
454{
455 EINA_SAFETY_ON_NULL_RETURN_VAL(disk, EINA_FALSE);
456
457 eina_stringshare_replace(&disk->mount_point, mount_point);
458 disk->mount_cmd_changed = EINA_TRUE;
459 disk->unmount_cmd_changed = EINA_TRUE;
460 return EINA_TRUE;
461}
diff --git a/src/lib/eeze/eeze_disk_private.h b/src/lib/eeze/eeze_disk_private.h
new file mode 100644
index 0000000000..0174b9e30d
--- /dev/null
+++ b/src/lib/eeze/eeze_disk_private.h
@@ -0,0 +1,93 @@
1#ifndef EEZE_DISK_PRIVATE_H
2#define EEZE_DISK_PRIVATE_H
3#include <Eeze.h>
4#include <Ecore_File.h>
5
6#ifndef EEZE_DISK_COLOR_DEFAULT
7#define EEZE_DISK_COLOR_DEFAULT EINA_COLOR_LIGHTBLUE
8#endif
9extern int _eeze_disk_log_dom;
10#ifdef CRI
11#undef CRI
12#endif
13
14#ifdef ERR
15#undef ERR
16#endif
17#ifdef INF
18#undef INF
19#endif
20#ifdef WARN
21#undef WARN
22#endif
23#ifdef DBG
24#undef DBG
25#endif
26
27#define CRI(...) EINA_LOG_DOM_CRIT(_eeze_disk_log_dom, __VA_ARGS__)
28#define DBG(...) EINA_LOG_DOM_DBG(_eeze_disk_log_dom, __VA_ARGS__)
29#define INF(...) EINA_LOG_DOM_INFO(_eeze_disk_log_dom, __VA_ARGS__)
30#define WARN(...) EINA_LOG_DOM_WARN(_eeze_disk_log_dom, __VA_ARGS__)
31#define ERR(...) EINA_LOG_DOM_ERR(_eeze_disk_log_dom, __VA_ARGS__)
32
33typedef enum
34{
35 EEZE_DISK_NULL = 0,
36 EEZE_DISK_MOUNTING = 1,
37 EEZE_DISK_UNMOUNTING = 2,
38 EEZE_DISK_EJECTING = 4
39} Eeze_Disk_Status;
40
41struct _Eeze_Disk
42{
43 _udev_device *device;
44 void *data;
45
46 int mount_status;
47 Eina_Strbuf *mount_cmd;
48 Eina_Strbuf *unmount_cmd;
49 Eina_Strbuf *eject_cmd;
50 Eina_Bool mount_cmd_changed : 1;
51 Eina_Bool unmount_cmd_changed : 1;
52 Eina_Bool mounted : 1;
53 Ecore_Exe *mounter;
54 unsigned int mount_fail_count;
55
56 const char *syspath;
57 const char *devpath;
58 const char *fstype;
59 const char *mount_point;
60 const char *mount_wrapper;
61 unsigned long mount_opts;
62 uid_t uid;
63
64 struct
65 {
66 Eeze_Disk_Type type;
67 Eina_Bool removable : 1;
68 const char *vendor;
69 const char *model;
70 const char *serial;
71 const char *uuid;
72 const char *label;
73 Eina_Bool filled : 1;
74 } cache;
75};
76
77Eina_Bool eeze_disk_init(void);
78void eeze_disk_shutdown(void);
79
80Eina_Bool eeze_mount_init(void);
81void eeze_mount_shutdown(void);
82
83Eina_Bool eeze_libmount_init(void);
84void eeze_libmount_shutdown(void);
85Eina_Bool eeze_disk_libmount_mounted_get(Eeze_Disk *disk);
86unsigned long eeze_disk_libmount_opts_get(Eeze_Disk *disk);
87const char *eeze_disk_libmount_mp_find_source(const char *mount_point);
88
89const char *eeze_disk_libmount_mp_lookup_by_uuid(const char *uuid);
90const char *eeze_disk_libmount_mp_lookup_by_label(const char *label);
91const char *eeze_disk_libmount_mp_lookup_by_devpath(const char *devpath);
92
93#endif
diff --git a/src/lib/eeze/eeze_disk_udev.c b/src/lib/eeze/eeze_disk_udev.c
new file mode 100644
index 0000000000..ef7b16029e
--- /dev/null
+++ b/src/lib/eeze/eeze_disk_udev.c
@@ -0,0 +1,90 @@
1#ifdef HAVE_CONFIG_H
2#include "config.h"
3#endif
4
5#include <Ecore.h>
6#include <Eeze.h>
7#include <Eeze_Disk.h>
8
9#include "eeze_udev_private.h"
10#include "eeze_disk_private.h"
11
12EAPI const char *
13eeze_disk_udev_get_property(Eeze_Disk *disk, const char *property)
14{
15 const char *ret;
16 EINA_SAFETY_ON_NULL_RETURN_VAL(disk, NULL);
17 EINA_SAFETY_ON_NULL_RETURN_VAL(property, NULL);
18 EINA_SAFETY_ON_TRUE_RETURN_VAL(!*property, NULL);
19
20 ret = udev_device_get_property_value(disk->device, property);
21 return eina_stringshare_add(ret);
22}
23
24EAPI const char *
25eeze_disk_udev_get_sysattr(Eeze_Disk *disk, const char *sysattr)
26{
27 const char *ret;
28 EINA_SAFETY_ON_NULL_RETURN_VAL(disk, NULL);
29 EINA_SAFETY_ON_NULL_RETURN_VAL(sysattr, NULL);
30 EINA_SAFETY_ON_TRUE_RETURN_VAL(!*sysattr, NULL);
31
32 ret = udev_device_get_sysattr_value(disk->device, sysattr);
33 return eina_stringshare_add(ret);
34}
35
36EAPI const char *
37eeze_disk_udev_get_parent(Eeze_Disk *disk)
38{
39 _udev_device *parent;
40 EINA_SAFETY_ON_NULL_RETURN_VAL(disk, NULL);
41
42 parent = udev_device_get_parent(disk->device);
43 return eina_stringshare_add(udev_device_get_syspath(parent));
44}
45
46EAPI Eina_Bool
47eeze_disk_udev_walk_check_sysattr(Eeze_Disk *disk,
48 const char *sysattr,
49 const char *value)
50{
51 _udev_device *child, *parent;
52 const char *test = NULL;
53
54 EINA_SAFETY_ON_NULL_RETURN_VAL(disk, EINA_FALSE);
55 EINA_SAFETY_ON_NULL_RETURN_VAL(sysattr, EINA_FALSE);
56 EINA_SAFETY_ON_TRUE_RETURN_VAL(!*sysattr, EINA_FALSE);
57
58 for (parent = disk->device; parent;
59 child = parent, parent = udev_device_get_parent(child))
60 {
61 if (!(test = udev_device_get_sysattr_value(parent, sysattr)))
62 continue;
63 if ((value && (!strcmp(test, value))) || (!value))
64 {
65 return EINA_TRUE;
66 break;
67 }
68 }
69 return EINA_FALSE;
70}
71
72EAPI const char *
73eeze_disk_udev_walk_get_sysattr(Eeze_Disk *disk,
74 const char *sysattr)
75{
76 _udev_device *child, *parent;
77 const char *test = NULL;
78
79 EINA_SAFETY_ON_NULL_RETURN_VAL(disk, NULL);
80 EINA_SAFETY_ON_NULL_RETURN_VAL(sysattr, NULL);
81 EINA_SAFETY_ON_TRUE_RETURN_VAL(!*sysattr, NULL);
82
83 for (parent = disk->device; parent;
84 child = parent, parent = udev_device_get_parent(child))
85 {
86 test = udev_device_get_sysattr_value(parent, sysattr);
87 if (test) return eina_stringshare_add(test);
88 }
89 return EINA_FALSE;
90}
diff --git a/src/lib/eeze/eeze_main.c b/src/lib/eeze/eeze_main.c
new file mode 100644
index 0000000000..1b2bfc2571
--- /dev/null
+++ b/src/lib/eeze/eeze_main.c
@@ -0,0 +1,123 @@
1#ifdef HAVE_CONFIG_H
2#include "config.h"
3#endif
4
5#include <Ecore.h>
6#include <Eeze.h>
7#include <Eeze_Disk.h>
8#include <Eeze_Sensor.h>
9#include "eeze_udev_private.h"
10#include "eeze_net_private.h"
11#include "eeze_disk_private.h"
12
13_udev *udev;
14
15int _eeze_udev_log_dom = -1;
16int _eeze_net_log_dom = -1;
17EAPI int _eeze_sensor_log_dom = -1;
18int _eeze_init_count = 0;
19
20static Eeze_Version _version = { VMAJ, VMIN, VMIC, VREV };
21EAPI Eeze_Version *eeze_version = &_version;
22
23EAPI int
24eeze_init(void)
25{
26 if (++_eeze_init_count != 1)
27 return _eeze_init_count;
28
29 if (!eina_init())
30 return 0;
31
32 _eeze_udev_log_dom = eina_log_domain_register("eeze_udev", EINA_COLOR_CYAN);
33 if (_eeze_udev_log_dom < 0)
34 {
35 EINA_LOG_ERR("Could not register 'eeze_udev' log domain.");
36 goto eina_fail;
37 }
38 _eeze_net_log_dom = eina_log_domain_register("eeze_net", EINA_COLOR_GREEN);
39 if (_eeze_net_log_dom < 0)
40 {
41 EINA_LOG_ERR("Could not register 'eeze_net' log domain.");
42 goto eina_net_fail;
43 }
44
45 _eeze_sensor_log_dom = eina_log_domain_register("eeze_sensor", EINA_COLOR_BLUE);
46 if (_eeze_sensor_log_dom < 0)
47 {
48 EINA_LOG_ERR("Could not register 'eeze_sensor' log domain.");
49 goto eina_sensor_fail;
50 }
51
52 if (!ecore_init())
53 goto ecore_fail;
54#ifdef HAVE_EEZE_MOUNT
55 if (!eeze_disk_init())
56 goto eeze_fail;
57#endif
58 if (!(udev = udev_new()))
59 {
60 EINA_LOG_ERR("Could not initialize udev library!");
61 goto fail;
62 }
63 if (!eeze_net_init())
64 {
65 EINA_LOG_ERR("Error initializing eeze_net subsystems!");
66 goto net_fail;
67 }
68 if (!eeze_sensor_init())
69 {
70 EINA_LOG_ERR("Error initializing eeze_sensor subsystems!");
71 goto sensor_fail;
72 }
73
74 return _eeze_init_count;
75
76sensor_fail:
77 eeze_net_shutdown();
78net_fail:
79 udev_unref(udev);
80fail:
81#ifdef HAVE_EEZE_MOUNT
82 eeze_disk_shutdown();
83eeze_fail:
84#endif
85 ecore_shutdown();
86ecore_fail:
87 eina_log_domain_unregister(_eeze_sensor_log_dom);
88 _eeze_sensor_log_dom = -1;
89eina_sensor_fail:
90 eina_log_domain_unregister(_eeze_net_log_dom);
91 _eeze_net_log_dom = -1;
92eina_net_fail:
93 eina_log_domain_unregister(_eeze_udev_log_dom);
94 _eeze_udev_log_dom = -1;
95eina_fail:
96 eina_shutdown();
97 return 0;
98}
99
100EAPI int
101eeze_shutdown(void)
102{
103 if (_eeze_init_count <= 0)
104 {
105 EINA_LOG_ERR("Init count not greater than 0 in shutdown.");
106 return 0;
107 }
108 if (--_eeze_init_count != 0)
109 return _eeze_init_count;
110
111 udev_unref(udev);
112#ifdef HAVE_EEZE_MOUNT
113 eeze_disk_shutdown();
114#endif
115 eeze_sensor_shutdown();
116 eeze_net_shutdown();
117 ecore_shutdown();
118 eina_log_domain_unregister(_eeze_udev_log_dom);
119 _eeze_udev_log_dom = -1;
120 eina_shutdown();
121 return _eeze_init_count;
122}
123
diff --git a/src/lib/eeze/eeze_net.c b/src/lib/eeze/eeze_net.c
new file mode 100644
index 0000000000..8a8826421d
--- /dev/null
+++ b/src/lib/eeze/eeze_net.c
@@ -0,0 +1,323 @@
1#ifdef HAVE_CONFIG_H
2#include "config.h"
3#endif
4
5#include <arpa/inet.h>
6#include <sys/ioctl.h>
7#include <net/if.h>
8#include <unistd.h>
9#include <Eeze_Net.h>
10
11#include "eeze_udev_private.h"
12#include "eeze_net_private.h"
13
14static Eina_Hash *eeze_nets = NULL;
15
16Eina_Bool
17eeze_net_init(void)
18{
19 eeze_nets = eina_hash_string_superfast_new(NULL);
20 return !!eeze_nets;
21}
22
23void
24eeze_net_shutdown(void)
25{
26 eina_hash_free(eeze_nets);
27 eeze_nets = NULL;
28}
29
30/**
31 * @addtogroup Eeze_Net Net
32 * @ingroup Eeze
33 * @{
34 */
35
36/**
37 * @brief Create a new net object
38 * @param name The name of the underlying device (eth0, br1, etc)
39 * @return A newly allocated net object, or NULL on failure
40 *
41 * This function creates a new net object based on @p name.
42 * Only the most minimal lookups are performed at creation in order
43 * to save memory.
44 */
45Eeze_Net *
46eeze_net_new(const char *name)
47{
48 const char *syspath = NULL;