summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog4
-rw-r--r--NEWS1
-rw-r--r--src/bin/e_fm/Makefile.am4
-rw-r--r--src/bin/e_fm/e_fm_main.c32
-rw-r--r--src/bin/e_fm/e_fm_main_udisks.c9
-rw-r--r--src/bin/e_fm/e_fm_main_udisks2.c1297
-rw-r--r--src/bin/e_fm/e_fm_main_udisks2.h21
-rw-r--r--src/bin/e_fm_shared_types.h.in1
-rw-r--r--src/modules/fileman/e_mod_config.c3
9 files changed, 1367 insertions, 5 deletions
diff --git a/ChangeLog b/ChangeLog
index e04ba3f07..ce5f52e5f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
12013-06-20 Mike Blumenkrantz
2
3 * udisks2 support
4
12013-06-19 Mike Blumenkrantz 52013-06-19 Mike Blumenkrantz
2 6
3 * added check changed to shelf config dialog 7 * added check changed to shelf config dialog
diff --git a/NEWS b/NEWS
index 523ecdc81..8e51d7e98 100644
--- a/NEWS
+++ b/NEWS
@@ -147,6 +147,7 @@ Improvements:
147 * added dnd support for text/x-moz-url 147 * added dnd support for text/x-moz-url
148 * filemanager dnd operations now show all files when dragging 148 * filemanager dnd operations now show all files when dragging
149 * added check changed to shelf config dialog 149 * added check changed to shelf config dialog
150 * udisks2 support
150 151
151Fixes: 152Fixes:
152 * IBar menu didn't allow to configure different icon sources, show contents menu even on empty IBar. 153 * IBar menu didn't allow to configure different icon sources, show contents menu even on empty IBar.
diff --git a/src/bin/e_fm/Makefile.am b/src/bin/e_fm/Makefile.am
index 55e2d089f..083839c73 100644
--- a/src/bin/e_fm/Makefile.am
+++ b/src/bin/e_fm/Makefile.am
@@ -22,7 +22,9 @@ enlightenment_fm
22if HAVE_UDISKS_MOUNT 22if HAVE_UDISKS_MOUNT
23udisks_s = \ 23udisks_s = \
24e_fm_main_udisks.h \ 24e_fm_main_udisks.h \
25e_fm_main_udisks.c 25e_fm_main_udisks.c \
26e_fm_main_udisks2.h \
27e_fm_main_udisks2.c
26else 28else
27udisks_s = 29udisks_s =
28endif 30endif
diff --git a/src/bin/e_fm/e_fm_main.c b/src/bin/e_fm/e_fm_main.c
index 3d45b063c..b78f8252a 100644
--- a/src/bin/e_fm/e_fm_main.c
+++ b/src/bin/e_fm/e_fm_main.c
@@ -56,6 +56,7 @@ void *alloca (size_t);
56#include "e_fm_shared_device.h" 56#include "e_fm_shared_device.h"
57#ifdef HAVE_UDISKS_MOUNT 57#ifdef HAVE_UDISKS_MOUNT
58# include "e_fm_main_udisks.h" 58# include "e_fm_main_udisks.h"
59# include "e_fm_main_udisks2.h"
59#endif 60#endif
60#ifdef HAVE_EEZE_MOUNT 61#ifdef HAVE_EEZE_MOUNT
61# include "e_fm_main_eeze.h" 62# include "e_fm_main_eeze.h"
@@ -91,7 +92,7 @@ static void
91_e_fm_init(void) 92_e_fm_init(void)
92{ 93{
93# ifdef HAVE_UDISKS_MOUNT 94# ifdef HAVE_UDISKS_MOUNT
94 _e_fm_main_udisks_init(); 95 _e_fm_main_udisks2_init();
95# else 96# else
96# ifdef HAVE_EEZE_MOUNT 97# ifdef HAVE_EEZE_MOUNT
97 _e_fm_main_eeze_init(); 98 _e_fm_main_eeze_init();
@@ -104,6 +105,7 @@ static void
104_e_fm_shutdown(void) 105_e_fm_shutdown(void)
105{ 106{
106# ifdef HAVE_UDISKS_MOUNT 107# ifdef HAVE_UDISKS_MOUNT
108 _e_fm_main_udisks2_shutdown();
107 _e_fm_main_udisks_shutdown(); 109 _e_fm_main_udisks_shutdown();
108# else 110# else
109# ifdef HAVE_EEZE_MOUNT 111# ifdef HAVE_EEZE_MOUNT
@@ -172,6 +174,18 @@ _e_fm_main_udisks_catch(Eina_Bool usable)
172 mode = EFM_MODE_USING_EEZE_MOUNT; 174 mode = EFM_MODE_USING_EEZE_MOUNT;
173# endif 175# endif
174} 176}
177
178void
179_e_fm_main_udisks2_catch(Eina_Bool usable)
180{
181 if (usable)
182 {
183 mode = EFM_MODE_USING_UDISKS2_MOUNT;
184 return;
185 }
186 _e_fm_main_udisks_init();
187 mode = EFM_MODE_USING_UDISKS_MOUNT;
188}
175#endif 189#endif
176 190
177void 191void
@@ -197,6 +211,9 @@ e_volume_mount(E_Volume *v)
197 case EFM_MODE_USING_UDISKS_MOUNT: 211 case EFM_MODE_USING_UDISKS_MOUNT:
198 _e_fm_main_udisks_volume_mount(v); 212 _e_fm_main_udisks_volume_mount(v);
199 break; 213 break;
214 case EFM_MODE_USING_UDISKS2_MOUNT:
215 _e_fm_main_udisks2_volume_mount(v);
216 break;
200#endif 217#endif
201#ifdef HAVE_EEZE_MOUNT 218#ifdef HAVE_EEZE_MOUNT
202 case EFM_MODE_USING_EEZE_MOUNT: 219 case EFM_MODE_USING_EEZE_MOUNT:
@@ -219,6 +236,9 @@ e_volume_unmount(E_Volume *v)
219 case EFM_MODE_USING_UDISKS_MOUNT: 236 case EFM_MODE_USING_UDISKS_MOUNT:
220 _e_fm_main_udisks_volume_unmount(v); 237 _e_fm_main_udisks_volume_unmount(v);
221 break; 238 break;
239 case EFM_MODE_USING_UDISKS2_MOUNT:
240 _e_fm_main_udisks2_volume_unmount(v);
241 break;
222#endif 242#endif
223#ifdef HAVE_EEZE_MOUNT 243#ifdef HAVE_EEZE_MOUNT
224 case EFM_MODE_USING_EEZE_MOUNT: 244 case EFM_MODE_USING_EEZE_MOUNT:
@@ -240,6 +260,9 @@ e_volume_eject(E_Volume *v)
240 case EFM_MODE_USING_UDISKS_MOUNT: 260 case EFM_MODE_USING_UDISKS_MOUNT:
241 _e_fm_main_udisks_volume_eject(v); 261 _e_fm_main_udisks_volume_eject(v);
242 break; 262 break;
263 case EFM_MODE_USING_UDISKS2_MOUNT:
264 _e_fm_main_udisks2_volume_eject(v);
265 break;
243#endif 266#endif
244#ifdef HAVE_EEZE_MOUNT 267#ifdef HAVE_EEZE_MOUNT
245 case EFM_MODE_USING_EEZE_MOUNT: 268 case EFM_MODE_USING_EEZE_MOUNT:
@@ -260,6 +283,8 @@ e_volume_find(const char *udi)
260#ifdef HAVE_UDISKS_MOUNT 283#ifdef HAVE_UDISKS_MOUNT
261 case EFM_MODE_USING_UDISKS_MOUNT: 284 case EFM_MODE_USING_UDISKS_MOUNT:
262 return _e_fm_main_udisks_volume_find(udi); 285 return _e_fm_main_udisks_volume_find(udi);
286 case EFM_MODE_USING_UDISKS2_MOUNT:
287 return _e_fm_main_udisks2_volume_find(udi);
263#endif 288#endif
264#ifdef HAVE_EEZE_MOUNT 289#ifdef HAVE_EEZE_MOUNT
265 case EFM_MODE_USING_EEZE_MOUNT: 290 case EFM_MODE_USING_EEZE_MOUNT:
@@ -281,6 +306,9 @@ e_storage_del(const char *udi)
281 case EFM_MODE_USING_UDISKS_MOUNT: 306 case EFM_MODE_USING_UDISKS_MOUNT:
282 _e_fm_main_udisks_storage_del(udi); 307 _e_fm_main_udisks_storage_del(udi);
283 break; 308 break;
309 case EFM_MODE_USING_UDISKS2_MOUNT:
310 _e_fm_main_udisks2_storage_del(udi);
311 break;
284#endif 312#endif
285#ifdef HAVE_EEZE_MOUNT 313#ifdef HAVE_EEZE_MOUNT
286 case EFM_MODE_USING_EEZE_MOUNT: 314 case EFM_MODE_USING_EEZE_MOUNT:
@@ -301,6 +329,8 @@ e_storage_find(const char *udi)
301#ifdef HAVE_UDISKS_MOUNT 329#ifdef HAVE_UDISKS_MOUNT
302 case EFM_MODE_USING_UDISKS_MOUNT: 330 case EFM_MODE_USING_UDISKS_MOUNT:
303 return _e_fm_main_udisks_storage_find(udi); 331 return _e_fm_main_udisks_storage_find(udi);
332 case EFM_MODE_USING_UDISKS2_MOUNT:
333 return _e_fm_main_udisks2_storage_find(udi);
304#endif 334#endif
305#ifdef HAVE_EEZE_MOUNT 335#ifdef HAVE_EEZE_MOUNT
306 case EFM_MODE_USING_EEZE_MOUNT: 336 case EFM_MODE_USING_EEZE_MOUNT:
diff --git a/src/bin/e_fm/e_fm_main_udisks.c b/src/bin/e_fm/e_fm_main_udisks.c
index f65515efc..804041307 100644
--- a/src/bin/e_fm/e_fm_main_udisks.c
+++ b/src/bin/e_fm/e_fm_main_udisks.c
@@ -663,15 +663,18 @@ _e_fm_main_udisks_format_error_msg(char **buf,
663 char *tmp; 663 char *tmp;
664 664
665 vu = strlen(v->udi) + 1; 665 vu = strlen(v->udi) + 1;
666 vm = strlen(v->mount_point) + 1; 666 if (v->mount_point) vm = strlen(v->mount_point) + 1;
667 en = strlen(name) + 1; 667 en = strlen(name) + 1;
668 size = vu + vm + en + strlen(message) + 1; 668 size = vu + vm + en + strlen(message) + 1;
669 tmp = *buf = malloc(size); 669 tmp = *buf = malloc(size);
670 670
671 strcpy(tmp, v->udi); 671 strcpy(tmp, v->udi);
672 tmp += vu; 672 tmp += vu;
673 strcpy(tmp, v->mount_point); 673 if (v->mount_point)
674 tmp += vm; 674 {
675 strcpy(tmp, v->mount_point);
676 tmp += vm;
677 }
675 strcpy(tmp, name); 678 strcpy(tmp, name);
676 tmp += en; 679 tmp += en;
677 strcpy(tmp, message); 680 strcpy(tmp, message);
diff --git a/src/bin/e_fm/e_fm_main_udisks2.c b/src/bin/e_fm/e_fm_main_udisks2.c
new file mode 100644
index 000000000..4b7cb3282
--- /dev/null
+++ b/src/bin/e_fm/e_fm_main_udisks2.c
@@ -0,0 +1,1297 @@
1#ifdef HAVE_CONFIG_H
2#include "config.h"
3#endif
4
5#ifdef HAVE_ALLOCA_H
6# include <alloca.h>
7#elif defined __GNUC__
8# define alloca __builtin_alloca
9#elif defined _AIX
10# define alloca __alloca
11#elif defined _MSC_VER
12# include <malloc.h>
13# define alloca _alloca
14#else
15# include <stddef.h>
16# ifdef __cplusplus
17extern "C"
18# endif
19void *alloca(size_t);
20#endif
21
22#ifdef __linux__
23#include <features.h>
24#endif
25#include <stdio.h>
26#include <stdlib.h>
27#include <unistd.h>
28#include <string.h>
29#include <sys/types.h>
30#include <sys/stat.h>
31#include <sys/time.h>
32#include <sys/param.h>
33#include <utime.h>
34#include <math.h>
35#include <fnmatch.h>
36#include <limits.h>
37#include <ctype.h>
38#include <time.h>
39#include <dirent.h>
40#include <pwd.h>
41#include <glob.h>
42#include <errno.h>
43#include <signal.h>
44#include <Ecore.h>
45#include <Ecore_Ipc.h>
46#include <Ecore_File.h>
47#include <Eet.h>
48#include <Eldbus.h>
49
50#include "e_fm_shared_device.h"
51#include "e_fm_shared_codec.h"
52#include "e_fm_ipc.h"
53#include "e_fm_device.h"
54
55#include "e_fm_main_udisks2.h"
56#include "e_fm_main.h"
57
58#define UDISKS2_BUS "org.freedesktop.UDisks2"
59#define UDISKS2_PATH "/org/freedesktop/UDisks2"
60#define UDISKS2_INTERFACE "org.freedesktop.UDisks2"
61#define UDISKS2_INTERFACE_BLOCK "org.freedesktop.UDisks2.Block"
62#define UDISKS2_INTERFACE_DRIVE "org.freedesktop.UDisks2.Drive"
63#define UDISKS2_INTERFACE_FILESYSTEM "org.freedesktop.UDisks2.Filesystem"
64
65typedef struct U2_Block
66{
67 size_t Size;
68 Eina_Stringshare *Device;
69 Eina_Stringshare *parent;
70 Eina_Bool volume;
71 Eina_Stringshare *IdType;
72 Eina_Stringshare *IdLabel;
73 Eina_Stringshare *IdUUID;
74 Eina_Bool HintIgnore;
75 Eina_Stringshare *HintName;
76 Eina_Stringshare *HintIconName;
77} U2_Block;
78
79static Eldbus_Connection *_e_fm_main_udisks2_conn = NULL;
80static Eldbus_Proxy *_e_fm_main_udisks2_proxy = NULL;
81static Eina_List *_e_stores = NULL;
82static Eina_List *_e_vols = NULL;
83
84static void _e_fm_main_udisks2_cb_dev_all(void *data, const Eldbus_Message *msg,
85 Eldbus_Pending *pending);
86static void _e_fm_main_udisks2_cb_dev_add(void *data, const Eldbus_Message *msg);
87static void _e_fm_main_udisks2_cb_dev_del(void *data, const Eldbus_Message *msg);
88static void _e_fm_main_udisks2_cb_vol_mounted(E_Volume *v);
89static void _e_fm_main_udisks2_cb_vol_unmounted(E_Volume *v);
90
91static void _e_fm_main_udisks2_cb_vol_ejected(E_Volume *v);
92static int _e_fm_main_udisks2_format_error_msg(char **buf,
93 E_Volume *v,
94 const char *name,
95 const char *message);
96static void _e_fm_main_udisks2_cb_storage_prop_modified(void *data, const Eldbus_Message *msg, Eldbus_Pending *p);
97static void _e_fm_main_udisks2_volume_mounts_update(E_Volume *v, Eldbus_Message_Iter *arr3, Eina_Bool first);
98static Eina_Bool _e_fm_main_udisks2_vol_mount_timeout(E_Volume *v);
99static Eina_Bool _e_fm_main_udisks2_vol_unmount_timeout(E_Volume *v);
100static Eina_Bool _e_fm_main_udisks2_vol_eject_timeout(E_Volume *v);
101static E_Storage *_storage_find_by_dbus_path(const char *path);
102static E_Volume *_volume_find_by_dbus_path(const char *path);
103static void _volume_del(E_Volume *v);
104static Eina_Bool _storage_del(void *data);
105static void _e_fm_main_udisks2_cb_storage_prop_modified_cb(void *data, const Eldbus_Message *msg);
106static E_Storage * _e_fm_main_udisks2_storage_drive_add(const char *udi, E_Storage *s, Eldbus_Message_Iter *arr3);
107
108static Eina_List *vols_ejecting = NULL;
109
110static Eina_List *stores_registered = NULL;
111
112static Eina_Stringshare *
113_util_fuckyouglib_convert(Eldbus_Message_Iter *fuckyouglib)
114{
115 Eldbus_Message_Iter *no_really;
116 unsigned char c, buf[PATH_MAX] = {0};
117 unsigned int x = 0;
118
119 if (!eldbus_message_iter_arguments_get(fuckyouglib, "ay", &no_really)) return NULL;
120 while (eldbus_message_iter_get_and_next(no_really, 'y', &c))
121 {
122 buf[x] = c;
123 x++;
124 }
125 if (!buf[0]) return NULL;
126 return eina_stringshare_add((char*)buf);
127}
128
129static void
130_e_fm_main_udisks2_name_start(void *data __UNUSED__, const Eldbus_Message *msg,
131 Eldbus_Pending *pending __UNUSED__)
132{
133 unsigned flag = 0;
134 Eldbus_Object *obj;
135
136 if (!eldbus_message_arguments_get(msg, "u", &flag) || !flag)
137 {
138 _e_fm_main_udisks2_catch(EINA_FALSE);
139 return;
140 }
141 obj = eldbus_object_get(_e_fm_main_udisks2_conn, UDISKS2_BUS, UDISKS2_PATH);
142 eldbus_object_managed_objects_get(obj, _e_fm_main_udisks2_cb_dev_all, NULL);
143
144 _e_fm_main_udisks2_proxy = eldbus_proxy_get(obj, ELDBUS_FDO_INTERFACE_OBJECT_MANAGER);
145 eldbus_proxy_signal_handler_add(_e_fm_main_udisks2_proxy, "InterfacesAdded",
146 _e_fm_main_udisks2_cb_dev_add, NULL);
147 eldbus_proxy_signal_handler_add(_e_fm_main_udisks2_proxy, "InterfacesRemoved",
148 _e_fm_main_udisks2_cb_dev_del, NULL);
149 //eldbus_signal_handler_add(_e_fm_main_udisks2_conn, NULL,
150 //NULL, ELDBUS_FDO_INTERFACE_PROPERTIES, "PropertiesChanged",
151 //_e_fm_main_udisks2_cb_dev_add, NULL);
152 _e_fm_main_udisks2_catch(EINA_TRUE); /* signal usage of udisks2 for mounting */
153}
154
155static void
156_e_fm_main_udisks2_block_clear(U2_Block *u2)
157{
158 eina_stringshare_del(u2->Device);
159 eina_stringshare_del(u2->parent);
160 eina_stringshare_del(u2->IdType);
161 eina_stringshare_del(u2->IdLabel);
162 eina_stringshare_del(u2->IdUUID);
163 eina_stringshare_del(u2->HintIconName);
164 eina_stringshare_del(u2->HintName);
165
166}
167
168static void
169_e_fm_main_udisks2_storage_block_add(E_Storage *s, U2_Block *u2)
170{
171 s->media_size = u2->Size;
172 eina_stringshare_replace(&s->icon.drive, u2->HintIconName);
173 s->system_internal = u2->HintIgnore;
174}
175
176static void
177_e_fm_main_udisks2_volume_block_add(E_Volume *v, U2_Block *u2)
178{
179 v->validated = u2->volume && u2->Device && u2->parent;
180 if (!v->validated) return;
181 v->size = u2->Size;
182 eina_stringshare_replace(&v->udi, u2->Device);
183 eina_stringshare_replace(&v->parent, u2->parent);
184 eina_stringshare_replace(&v->icon, u2->HintIconName);
185 eina_stringshare_replace(&v->uuid, u2->IdUUID);
186 eina_stringshare_replace(&v->fstype, u2->IdType);
187 eina_stringshare_replace(&v->label, u2->IdLabel);
188 if (!v->label) v->label = eina_stringshare_ref(u2->HintName);
189
190}
191
192static void
193_e_fm_main_udisks2_storage_add_send(E_Storage *s)
194{
195 void *msg_data;
196 int msg_size;
197
198 if (!s->validated) return;
199 if (eina_list_data_find(stores_registered, s)) return;
200 if ((!s->removable) && (!s->hotpluggable) && (!s->requires_eject))
201 {
202 DBG("removing likely internal storage %s", s->dbus_path);
203 s->validated = 0;
204 ecore_idler_add(_storage_del, s->dbus_path);
205 return;
206 }
207 stores_registered = eina_list_append(stores_registered, s);
208 msg_data = _e_fm_shared_codec_storage_encode(s, &msg_size);
209 if (msg_data)
210 {
211 ecore_ipc_server_send(_e_fm_ipc_server,
212 6 /*E_IPC_DOMAIN_FM*/,
213 E_FM_OP_STORAGE_ADD,
214 0, 0, 0, msg_data, msg_size);
215 free(msg_data);
216 }
217}
218
219static int
220_e_fm_main_udisks2_block_handle(Eldbus_Message_Iter *arr3, U2_Block *u2)
221{
222 Eldbus_Message_Iter *dict3;
223 int block = 0;
224
225 while (eldbus_message_iter_get_and_next(arr3, 'e', &dict3))
226 {
227 Eldbus_Message_Iter *var;
228 char *key2, *val, *type;
229 uint64_t u;
230 Eina_Bool b;
231
232 if (!eldbus_message_iter_arguments_get(dict3, "sv", &key2, &var))
233 continue;
234
235 type = eldbus_message_iter_signature_get(var);
236 switch (type[0])
237 {
238 case 's':
239 case 'o':
240 eldbus_message_iter_arguments_get(var, type, &val);
241 if ((!val) || (!val[0])) continue;
242 break;
243 case 't':
244 eldbus_message_iter_arguments_get(var, type, &u);
245 break;
246 case 'b':
247 eldbus_message_iter_arguments_get(var, type, &b);
248 break;
249 default: break;
250 }
251 if (!strcmp(key2, "Device"))
252 {
253 u2->Device = _util_fuckyouglib_convert(var);
254 if (!strncmp(u2->Device, "/dev/ram", 8)) return -1;
255 }
256 else if (!strcmp(key2, "Size"))
257 u2->Size = u;
258 else if (!strcmp(key2, "Drive"))
259 u2->parent = eina_stringshare_add(val);
260 else if (!strcmp(key2, "IdUsage"))
261 {
262 if (!strcmp(val, "other")) return -1;
263 u2->volume = !strcmp(val, "filesystem");
264 }
265 else if (!strcmp(key2, "IdType"))
266 u2->IdType = eina_stringshare_add(val);
267 else if (!strcmp(key2, "IdLabel"))
268 u2->IdLabel = eina_stringshare_add(val);
269 else if (!strcmp(key2, "IdUUID"))
270 u2->IdUUID = eina_stringshare_add(val);
271 else if (!strcmp(key2, "HintIgnore"))
272 u2->HintIgnore = !!b;
273 else if (!strcmp(key2, "HintName"))
274 u2->HintName = eina_stringshare_add(val);
275 else if (!strcmp(key2, "HintIconName"))
276 u2->HintIconName = eina_stringshare_add(val);
277 block = 1;
278 }
279 return block;
280}
281
282static void
283_e_fm_main_udisks2_handle_device(Eldbus_Message_Iter *dict)
284{
285 const char *udi;
286 Eldbus_Message_Iter *arr2, *dict2;
287 E_Volume *v = NULL;
288 E_Storage *s = NULL;
289 U2_Block u2;
290 int block = 0;
291 unsigned int pnum = UINT_MAX;
292 Eina_Stringshare *pname = NULL;
293
294 if (!eldbus_message_iter_arguments_get(dict, "oa{sa{sv}}", &udi, &arr2))
295 return;
296 memset(&u2, 0, sizeof(U2_Block));
297 while (eldbus_message_iter_get_and_next(arr2, 'e', &dict2))
298 {
299 Eldbus_Message_Iter *arr3, *dict3;
300 char *interface;
301
302 if (!eldbus_message_iter_arguments_get(dict2, "sa{sv}", &interface, &arr3))
303 continue;
304 interface += sizeof(UDISKS2_INTERFACE);
305 if (!strcmp(interface, "Partition"))
306 {
307 while (eldbus_message_iter_get_and_next(arr3, 'e', &dict3))
308 {
309 Eldbus_Message_Iter *var;
310 char *key2, *val, *type;
311
312 if (!eldbus_message_iter_arguments_get(dict3, "sv", &key2, &var))
313 continue;
314
315 type = eldbus_message_iter_signature_get(var);
316 switch (type[0])
317 {
318 case 's':
319 if (strcmp(key2, "Name")) continue;
320 if (!eldbus_message_iter_arguments_get(var, type, &val)) continue;
321 if (val && val[0]) pname = eina_stringshare_add(val);
322 break;
323 case 'u':
324 if (strcmp(key2, "Number")) continue;
325 eldbus_message_iter_arguments_get(var, type, &pnum);
326 break;
327 default: break;
328 }
329 }
330 if (v)
331 {
332 v->partition_label = pname;
333 pname = NULL;
334 v->partition_number = pnum;
335 v->partition = (v->partition_label || (pnum != UINT_MAX));
336 }
337 }
338 else if (!strcmp(interface, "Filesystem"))
339 {
340 if (!v) v = _volume_find_by_dbus_path(udi);
341 if (!v) v = _e_fm_main_udisks2_volume_add(udi, EINA_TRUE);
342 _e_fm_main_udisks2_volume_mounts_update(v, arr3, 1);
343 v->partition_label = pname;
344 pname = NULL;
345 if (pnum != UINT_MAX)
346 {
347 v->partition_number = pnum;
348 v->partition = 1;
349 }
350 if (block)
351 {
352 _e_fm_main_udisks2_volume_block_add(v, &u2);
353 if (!v->validated) E_FREE_FUNC(v, _volume_del);
354 }
355 }
356 else if (!strcmp(interface, "Block"))
357 {
358 block = _e_fm_main_udisks2_block_handle(arr3, &u2);
359 switch (block)
360 {
361 case -1: goto out;
362 case 0: continue;
363 default: break;
364 }
365 if ((!s) && (!v))
366 {
367 v = _volume_find_by_dbus_path(udi);
368 s = _e_fm_main_udisks2_storage_find(u2.parent);
369 }
370 if (s)
371 _e_fm_main_udisks2_storage_block_add(s, &u2);
372 if (v)
373 {
374 _e_fm_main_udisks2_volume_block_add(v, &u2);
375 if (!v->validated) E_FREE_FUNC(v, _volume_del);
376 }
377 }
378 else if (!strcmp(interface, "Drive"))
379 {
380 s = _e_fm_main_udisks2_storage_drive_add(udi, s, arr3);
381 if (block) _e_fm_main_udisks2_storage_block_add(s, &u2);
382 }
383 }
384out:
385 _e_fm_main_udisks2_block_clear(&u2);
386 eina_stringshare_del(pname);
387 if (v && v->validated) e_fm_ipc_volume_add(v);
388 if (s)
389 {
390 if (!block) //cdrom :/
391 s->udi = eina_stringshare_add(udi);
392 _e_fm_main_udisks2_storage_add_send(s);
393 }
394}
395
396static void
397_e_fm_main_udisks2_cb_dev_all(void *data __UNUSED__, const Eldbus_Message *msg,
398 Eldbus_Pending *pending __UNUSED__)
399{
400 const char *name, *txt;
401 Eldbus_Message_Iter *arr1, *dict1;
402
403 if (eldbus_message_error_get(msg, &name, &txt))
404 {
405 ERR("Error %s %s.", name, txt);
406 return;
407 }
408
409 if (!eldbus_message_arguments_get(msg, "a{oa{sa{sv}}}", &arr1))
410 {
411 ERR("Error getting arguments.");
412 return;
413 }
414
415 while (eldbus_message_iter_get_and_next(arr1, 'e', &dict1))
416 _e_fm_main_udisks2_handle_device(dict1);
417}
418
419static void
420_e_fm_main_udisks2_cb_vol_props(void *data, const Eldbus_Message *msg, Eldbus_Pending *p EINA_UNUSED)
421{
422 U2_Block u2;
423 int block;
424 E_Volume *v = data;
425 Eldbus_Message_Iter *arr;
426
427 memset(&u2, 0, sizeof(U2_Block));
428 if (!eldbus_message_arguments_get(msg, "a{sv}", &arr))
429 {
430 ERR("WTF");
431 return;
432 }
433 block = _e_fm_main_udisks2_block_handle(arr, &u2);
434 if (block == 1)
435 {
436 Eina_Bool valid = v->validated;
437
438 _e_fm_main_udisks2_volume_block_add(v, &u2);
439 if (v->validated && (valid != v->validated))
440 e_fm_ipc_volume_add(v);
441 else if (!v->validated)
442 _volume_del(v);
443 }
444 _e_fm_main_udisks2_block_clear(&u2);
445}
446
447static void
448_e_fm_main_udisks2_cb_dev_add(void *data __UNUSED__, const Eldbus_Message *msg)
449{
450 const char *interface;
451
452 interface = eldbus_message_interface_get(msg);
453 //path = eldbus_message_path_get(msg);
454 //if (!strncmp(path, "/org/freedesktop/UDisks2/drives", sizeof("/org/freedesktop/UDisks2/drives") - 1))
455 //{
456 //E_Storage *s;
457//
458 //if (!eldbus_message_arguments_get(msg, "sa{sv}as", &interface, &arr, &arr2))
459 //return;
460 //interface += sizeof(UDISKS2_INTERFACE);
461 //if (strcmp(interface, "Drive")) return;
462 //s = _storage_find_by_dbus_path(path);
463 //if (!s) return;
464 //valid = s->validated;
465 //_e_fm_main_udisks2_storage_drive_add(s->udi, s, arr);
466 //if (valid != s->validated)
467 //_e_fm_main_udisks2_storage_add_send(s);
468 //}
469 //else if (!strncmp(path, "/org/freedesktop/UDisks2/block_devices", sizeof("/org/freedesktop/UDisks2/block_devices") - 1))
470 //{
471 //E_Volume *v;
472//
473 //if (!eldbus_message_arguments_get(msg, "sa{sv}as", &interface, &arr, &arr2))
474 //return;
475 //v = _volume_find_by_dbus_path(path);
476 //if (!v) v = _e_fm_main_udisks2_volume_add(path, 1);
477//
478 //interface += sizeof(UDISKS2_INTERFACE);
479 //if (!strcmp(interface, "Filesystem"))
480 //_e_fm_main_udisks2_volume_mounts_update(v, arr, 0);
481 //else if (!strcmp(interface, "Block"))
482 //{
483 //U2_Block u2;
484 //int block;
485//
486 //memset(&u2, 0, sizeof(U2_Block));
487 //block = _e_fm_main_udisks2_block_handle(arr, &u2);
488 //if (block == 1)
489 //{
490 //valid = v->validated;
491//
492 //_e_fm_main_udisks2_volume_block_add(v, &u2);
493 //if (v->validated && (valid != v->validated))
494 //e_fm_ipc_volume_add(v);
495 //else if (!v->validated)
496 //_volume_del(v);
497 //}
498 //_e_fm_main_udisks2_block_clear(&u2);
499 //}
500 //}
501 //else
502 E_Storage *s = eina_list_last_data_get(_e_stores);
503 E_Volume *v = eina_list_last_data_get(_e_vols);
504 if (!strcmp(interface, ELDBUS_FDO_INTERFACE_OBJECT_MANAGER))
505 _e_fm_main_udisks2_handle_device(eldbus_message_iter_get(msg));
506 if (_e_stores && (s != eina_list_last_data_get(_e_stores)))
507 {
508 s = eina_list_last_data_get(_e_stores);
509 if (s->proxy)
510 eldbus_proxy_property_get_all(s->proxy, _e_fm_main_udisks2_cb_storage_prop_modified, s);
511 }
512 if (_e_vols && (v != eina_list_last_data_get(_e_vols)))
513 {
514 Eldbus_Message *m;
515 Eldbus_Object *obj;
516
517 v = eina_list_last_data_get(_e_vols);
518 m = eldbus_message_method_call_new(UDISKS2_BUS, v->dbus_path, ELDBUS_FDO_INTERFACE_PROPERTIES, "GetAll");
519 eldbus_message_arguments_append(m, "s", UDISKS2_INTERFACE_BLOCK);
520 obj = eldbus_proxy_object_get(v->proxy);
521 eldbus_object_send(obj, m, _e_fm_main_udisks2_cb_vol_props, v, -1);
522 }
523}
524
525static void
526_e_fm_main_udisks2_cb_dev_del(void *data __UNUSED__, const Eldbus_Message *msg)
527{
528 char *path, *interface;
529 Eldbus_Message_Iter *arr;
530 E_Volume *v;
531 Eina_Bool vol = EINA_FALSE, sto = EINA_FALSE;
532
533 if (!eldbus_message_arguments_get(msg, "oas", &path, &arr))
534 return;
535 DBG("DB DEV-: %s", path);
536
537 while (eldbus_message_iter_get_and_next(arr, 's', &interface))
538 {
539 interface += sizeof(UDISKS2_INTERFACE);
540 if (!strcmp(interface, "Filesystem"))
541 vol = EINA_TRUE;
542 else if (!strcmp(interface, "Drive"))
543 sto = EINA_TRUE;
544 }
545 if (vol)
546 {
547 v = _volume_find_by_dbus_path(path);
548 if (v && (!v->mounted))
549 {
550 if (v->optype == E_VOLUME_OP_TYPE_EJECT)
551 _e_fm_main_udisks2_cb_vol_ejected(v);
552 _volume_del(v);
553 }
554 }
555 if (sto) _e_fm_main_udisks2_storage_del(path);
556}
557
558static void
559_e_fm_main_udisks2_cb_storage_prop_modified(void *data, const Eldbus_Message *msg, Eldbus_Pending *p EINA_UNUSED)
560{
561 Eldbus_Message_Iter *arr;
562 E_Storage *s = data;
563 Eina_Bool valid;
564
565 {
566 const char *type = eldbus_message_signature_get(msg);
567 if (type[0] == 's')
568 {
569 char *txt;
570 if (eldbus_message_arguments_get(msg, type, &txt))
571 ERR("%s", txt);
572 }
573 }
574 if (!eldbus_message_arguments_get(msg, "a{sv}", &arr))
575 return;
576 valid = s->validated;
577 _e_fm_main_udisks2_storage_drive_add(s->udi, s, arr);
578 if (valid != s->validated)
579 _e_fm_main_udisks2_storage_add_send(s);
580}
581
582static void
583_e_fm_main_udisks2_cb_storage_prop_modified_cb(void *data, const Eldbus_Message *msg)
584{
585 const char *interface;
586 Eldbus_Message_Iter *arr, *arr2;
587 E_Storage *s = data;
588 Eina_Bool valid;
589
590 if (!eldbus_message_arguments_get(msg, "sa{sv}as", &interface, &arr, &arr2))
591 return;
592 valid = s->validated;
593 _e_fm_main_udisks2_storage_drive_add(s->udi, s, arr);
594 if (valid != s->validated)
595 _e_fm_main_udisks2_storage_add_send(s);
596}
597
598static void
599_e_fm_main_udisks2_cb_vol_prop_modified(void *data, const Eldbus_Message *msg, Eldbus_Pending *p EINA_UNUSED)
600{
601 const char *interface;
602 Eldbus_Message_Iter *arr, *arr2;
603 E_Volume *v = data;
604
605 if (!eldbus_message_arguments_get(msg, "sa{sv}as", &interface, &arr, &arr2))
606 return;
607 interface += sizeof(UDISKS2_INTERFACE);
608 if (!strcmp(interface, "Filesystem"))
609 _e_fm_main_udisks2_volume_mounts_update(v, arr, 0);
610 else if (!strcmp(interface, "Block"))
611 {
612 U2_Block u2;
613 int block;
614
615 memset(&u2, 0, sizeof(U2_Block));
616 block = _e_fm_main_udisks2_block_handle(arr, &u2);
617 if (block == 1)
618 {
619 Eina_Bool valid = v->validated;
620
621 _e_fm_main_udisks2_volume_block_add(v, &u2);
622 if (v->validated && (valid != v->validated))
623 e_fm_ipc_volume_add(v);
624 else if (!v->validated)
625 _volume_del(v);
626 }
627 _e_fm_main_udisks2_block_clear(&u2);
628 }
629}
630
631static void
632_e_fm_main_udisks2_cb_vol_prop_modified_cb(void *data, const Eldbus_Message *msg)
633{
634 _e_fm_main_udisks2_cb_vol_prop_modified(data, msg, NULL);
635}
636
637static Eina_Bool
638_storage_del(void *data)
639{
640 const char *path = data;
641 _e_fm_main_udisks2_storage_del(path);
642 return ECORE_CALLBACK_CANCEL;
643}
644
645static E_Storage *
646_e_fm_main_udisks2_storage_drive_add(const char *udi, E_Storage *s, Eldbus_Message_Iter *arr3)
647{
648 Eldbus_Message_Iter *dict3;
649
650 if (!s)
651 {
652 if (!s) s = _e_fm_main_udisks2_storage_find(udi);
653 if (!s) s = _e_fm_main_udisks2_storage_add(udi);
654 if (!s) return NULL;
655 }
656 if (s->system_internal)
657 {
658 DBG("removing storage internal %s", s->dbus_path);
659 s->validated = 0;
660 ecore_idler_add(_storage_del, s->dbus_path);
661 return NULL;
662 }
663 while (eldbus_message_iter_get_and_next(arr3, 'e', &dict3))
664 {
665 Eldbus_Message_Iter *var;
666 char *key2, *val, *type;
667 Eina_Bool b;
668 uint64_t t;
669
670 if (!eldbus_message_iter_arguments_get(dict3, "sv", &key2, &var))
671 continue;
672
673 type = eldbus_message_iter_signature_get(var);
674 switch (type[0])
675 {
676 case 's':
677 case 'o':
678 eldbus_message_iter_arguments_get(var, type, &val);
679 break;
680 case 'b':
681 eldbus_message_iter_arguments_get(var, type, &b);
682 break;
683 case 't':
684 eldbus_message_iter_arguments_get(var, type, &t);
685 break;
686 default: break;
687 }
688
689 if (!strcmp(key2, "ConnectionBus"))
690 eina_stringshare_replace(&s->bus, val);
691 else if (!strcmp(key2, "MediaCompatibility"))
692 {
693 Eldbus_Message_Iter *inner_array;
694 const char *media;
695
696 if (!eldbus_message_iter_arguments_get(var, "as", &inner_array))
697 continue;
698
699 if (eldbus_message_iter_get_and_next(inner_array, 's', &media))
700 eina_stringshare_replace(&s->drive_type, media);
701 }
702 else if (!strcmp(key2, "Model"))
703 eina_stringshare_replace(&s->model, val);
704 else if (!strcmp(key2, "Vendor"))
705 eina_stringshare_replace(&s->vendor, val);
706 else if (!strcmp(key2, "Serial"))
707 eina_stringshare_replace(&s->serial, val);
708 else if (!strcmp(key2, "MediaAvailable"))
709 s->media_available = !!b;
710 else if (!strcmp(key2, "Size"))
711 s->media_size = t;
712 else if (!strcmp(key2, "Ejectable"))
713 s->requires_eject = !!b;
714 else if (!strcmp(key2, "Removable"))
715 s->hotpluggable = !!b;
716 else if (!strcmp(key2, "MediaRemovable"))
717 s->removable = !!b;
718 }
719
720 INF("++STO:\n udi: %s\n bus: %s\n drive_type: %s\n model: %s\n vendor: %s\n serial: %s\n icon.drive: %s\n icon.volume: %s\n", s->udi, s->bus, s->drive_type, s->model, s->vendor, s->serial, s->icon.drive, s->icon.volume);
721 s->validated = EINA_TRUE;
722
723 if (!s->proxy)
724 {
725 Eldbus_Object *obj;
726
727 obj = eldbus_object_get(_e_fm_main_udisks2_conn, UDISKS2_BUS, s->udi);
728 s->proxy = eldbus_proxy_get(obj, UDISKS2_INTERFACE_DRIVE);
729 eldbus_proxy_properties_monitor(s->proxy, 1);
730 eldbus_proxy_properties_changed_callback_add(s->proxy, _e_fm_main_udisks2_cb_storage_prop_modified_cb, s);
731 }
732 return s;
733}
734
735static int
736_e_fm_main_udisks2_format_error_msg(char **buf,
737 E_Volume *v,
738 const char *name,
739 const char *message)
740{
741 int size, vu, vm, en;
742 char *tmp;
743
744 vu = strlen(v->udi) + 1;
745 if (v->mount_point) vm = strlen(v->mount_point) + 1;
746 en = strlen(name) + 1;
747 size = vu + vm + en + strlen(message) + 1;
748 tmp = *buf = malloc(size);
749
750 strcpy(tmp, v->udi);
751 tmp += vu;
752 if (v->mount_point)
753 {
754 strcpy(tmp, v->mount_point);
755 tmp += vm;
756 }
757 strcpy(tmp, name);
758 tmp += en;
759 strcpy(tmp, message);
760
761 return size;
762}
763
764static Eina_Bool
765_e_fm_main_udisks2_vol_mount_timeout(E_Volume *v)
766{
767 char *buf;
768 int size;
769
770 v->guard = NULL;
771
772 E_FREE_FUNC(v->op, eldbus_pending_cancel);
773 v->optype = E_VOLUME_OP_TYPE_NONE;
774 size = _e_fm_main_udisks2_format_error_msg(&buf, v,
775 "org.enlightenment.fm2.MountTimeout",
776 "Unable to mount the volume with specified time-out.");
777 ecore_ipc_server_send(_e_fm_ipc_server, 6 /*E_IPC_DOMAIN_FM*/, E_FM_OP_MOUNT_ERROR,
778 0, 0, 0, buf, size);
779 free(buf);
780
781 return ECORE_CALLBACK_CANCEL;
782}
783
784static void
785_e_fm_main_udisks2_cb_vol_mounted(E_Volume *v)
786{
787 char *buf;
788 int size;
789
790 E_FREE_FUNC(v->guard, ecore_timer_del);
791 if (!v->mount_point) return; /* come back later */
792
793 v->optype = E_VOLUME_OP_TYPE_NONE;
794 v->op = NULL;
795 v->mounted = EINA_TRUE;
796 INF("MOUNT: %s from %s", v->udi, v->mount_point);
797 size = strlen(v->udi) + 1 + strlen(v->mount_point) + 1;
798 buf = alloca(size);
799 strcpy(buf, v->udi);
800 strcpy(buf + strlen(buf) + 1, v->mount_point);
801 ecore_ipc_server_send(_e_fm_ipc_server,
802 6 /*E_IPC_DOMAIN_FM*/,
803 E_FM_OP_MOUNT_DONE,
804 0, 0, 0, buf, size);
805}
806
807static Eina_Bool
808_e_fm_main_udisks2_vol_unmount_timeout(E_Volume *v)
809{
810 char *buf;
811 int size;
812
813 v->guard = NULL;
814 if (v->op)
815 eldbus_pending_cancel(v->op);
816 v->op = NULL;
817 v->optype = E_VOLUME_OP_TYPE_NONE;
818 size = _e_fm_main_udisks2_format_error_msg(&buf, v,
819 "org.enlightenment.fm2.UnmountTimeout",
820 "Unable to unmount the volume with specified time-out.");
821 ecore_ipc_server_send(_e_fm_ipc_server, 6 /*E_IPC_DOMAIN_FM*/, E_FM_OP_UNMOUNT_ERROR,
822 0, 0, 0, buf, size);
823 free(buf);
824
825 return ECORE_CALLBACK_CANCEL;
826}
827
828static void
829_e_fm_main_udisks2_cb_vol_unmounted(E_Volume *v)
830{
831 char *buf;
832 int size;
833
834 E_FREE_FUNC(v->guard, ecore_timer_del);
835
836 if (v->optype != E_VOLUME_OP_TYPE_EJECT)
837 {
838 v->optype = E_VOLUME_OP_TYPE_NONE;
839 v->op = NULL;
840 }
841
842 v->mounted = EINA_FALSE;
843 INF("UNMOUNT: %s from %s", v->udi, v->mount_point);
844 size = strlen(v->udi) + 1 + strlen(v->mount_point) + 1;
845 buf = alloca(size);
846 strcpy(buf, v->udi);
847 strcpy(buf + strlen(buf) + 1, v->mount_point);
848 ecore_ipc_server_send(_e_fm_ipc_server,
849 6 /*E_IPC_DOMAIN_FM*/,
850 E_FM_OP_UNMOUNT_DONE,
851 0, 0, 0, buf, size);
852}
853
854static Eina_Bool
855_e_fm_main_udisks2_vol_eject_timeout(E_Volume *v)
856{
857 char *buf;
858 int size;
859
860 v->guard = NULL;
861 if (v->op)
862 eldbus_pending_cancel(v->op);
863 v->op = NULL;
864 v->optype = E_VOLUME_OP_TYPE_NONE;
865 size = _e_fm_main_udisks2_format_error_msg(&buf, v,
866 "org.enlightenment.fm2.EjectTimeout",
867 "Unable to eject the media with specified time-out.");
868 ecore_ipc_server_send(_e_fm_ipc_server, 6 /*E_IPC_DOMAIN_FM*/, E_FM_OP_EJECT_ERROR,
869 0, 0, 0, buf, size);
870 free(buf);
871
872 return ECORE_CALLBACK_CANCEL;
873}
874
875static Eldbus_Pending *
876_volume_eject(Eldbus_Proxy *proxy)
877{
878 Eldbus_Message *msg;
879 Eldbus_Message_Iter *array, *main_iter;
880
881 msg = eldbus_proxy_method_call_new(proxy, "Eject");
882 main_iter = eldbus_message_iter_get(msg);
883 eldbus_message_iter_arguments_append(main_iter, "a{sv}", &array);
884 eldbus_message_iter_container_close(main_iter, array);
885
886 return eldbus_proxy_send(proxy, msg, NULL, NULL, -1);
887}
888
889static void
890_volume_eject_umount_cb(void *data, const Eldbus_Message *msg, Eldbus_Pending *pending EINA_UNUSED)
891{
892 const char *name, *txt;
893 E_Volume *v = data;
894
895 if (eldbus_message_error_get(msg, &name, &txt))
896 ERR("%s: %s", name, txt);
897 else if (v->optype == E_VOLUME_OP_TYPE_EJECT)
898 {
899 vols_ejecting = eina_list_remove(vols_ejecting, v);
900 _volume_eject(v->storage->proxy);
901 }
902
903}
904
905static Eldbus_Pending *
906_volume_umount(E_Volume *v)
907{
908 Eldbus_Message *msg;
909 Eldbus_Message_Iter *array, *main_iter;
910
911 msg = eldbus_proxy_method_call_new(v->proxy, "Unmount");
912 main_iter = eldbus_message_iter_get(msg);
913 eldbus_message_iter_arguments_append(main_iter, "a{sv}", &array);
914 eldbus_message_iter_container_close(main_iter, array);
915
916 return eldbus_proxy_send(v->proxy, msg, _volume_eject_umount_cb, v, -1);
917}
918
919static Eldbus_Pending *
920_volume_mount(Eldbus_Proxy *proxy, const char *fstype, const char *buf)
921{
922 Eldbus_Message *msg;
923 Eldbus_Message_Iter *array, *main_iter, *dict, *var;
924 char opt_txt[] = "options";
925 char fs_txt[] = "fstype";
926
927 msg = eldbus_proxy_method_call_new(proxy, "Mount");
928 main_iter = eldbus_message_iter_get(msg);
929 if (!eldbus_message_iter_arguments_append(main_iter, "a{sv}", &array))
930 ERR("E");
931 if (fstype)
932 {
933 if (!eldbus_message_iter_arguments_append(array, "{sv}", &dict))
934 ERR("E");
935 eldbus_message_iter_basic_append(dict, 's', fs_txt);
936
937 var = eldbus_message_iter_container_new(dict, 'v', "s");
938 eldbus_message_iter_basic_append(var, 's', fstype);
939 eldbus_message_iter_container_close(dict, var);
940 eldbus_message_iter_container_close(array, dict);
941
942 }
943 if (buf[0])
944 {
945 if (!eldbus_message_iter_arguments_append(array, "{sv}", &dict))
946 ERR("E");
947 eldbus_message_iter_basic_append(dict, 's', opt_txt);
948
949 var = eldbus_message_iter_container_new(dict, 'v', "s");
950 eldbus_message_iter_basic_append(var, 's', buf);
951 eldbus_message_iter_container_close(dict, var);
952 eldbus_message_iter_container_close(array, dict);
953 }
954 eldbus_message_iter_container_close(main_iter, array);
955
956 return eldbus_proxy_send(proxy, msg, NULL, NULL, -1);
957}
958
959static void
960_e_fm_main_udisks2_cb_vol_ejected(E_Volume *v)
961{
962 char *buf;
963 int size;
964
965 E_FREE_FUNC(v->guard, ecore_timer_del);
966 v->optype = E_VOLUME_OP_TYPE_NONE;
967
968 size = strlen(v->udi) + 1;
969 buf = alloca(size);
970 strcpy(buf, v->udi);
971 ecore_ipc_server_send(_e_fm_ipc_server,
972 6 /*E_IPC_DOMAIN_FM*/,
973 E_FM_OP_EJECT_DONE,
974 0, 0, 0, buf, size);
975}
976
977static void
978_e_fm_main_udisks2_volume_mounts_update(E_Volume *v, Eldbus_Message_Iter *arr3, Eina_Bool first)
979{
980 Eldbus_Message_Iter *dict3;
981 Eina_List *mounts = NULL;
982
983 while (eldbus_message_iter_get_and_next(arr3, 'e', &dict3))
984 {
985 Eldbus_Message_Iter *var;
986 char *key2, *type;
987
988 if (!eldbus_message_iter_arguments_get(dict3, "sv", &key2, &var))
989 continue;
990
991 type = eldbus_message_iter_signature_get(var);
992 switch (type[0])
993 {
994 Eldbus_Message_Iter *fuckyouglib;
995
996 case 'a':
997 if (strcmp(key2, "MountPoints")) continue;
998 /* glib developers are assholes, so this is "aay" instead of just "as" */
999 if (!eldbus_message_iter_arguments_get(var, type, &fuckyouglib))
1000 {
1001 ERR("fucked by glib I guess");
1002 continue;
1003 }
1004 do
1005 {
1006 Eina_Stringshare *m;
1007
1008 m = _util_fuckyouglib_convert(fuckyouglib);
1009 if (m) mounts = eina_list_append(mounts, m);
1010 }
1011 while (eldbus_message_iter_next(fuckyouglib));
1012 default: continue;
1013 }
1014 }
1015 if (first)
1016 {
1017 eina_stringshare_replace(&v->mount_point, eina_list_last_data_get(mounts));
1018 v->mounted = !!v->mount_point;
1019 if (v->storage)
1020 v->storage->media_available = v->mounted;
1021 }
1022 else if ((!v->mounted) || (!eina_list_data_find(mounts, v->mount_point)))
1023 {
1024 if (mounts)
1025 eina_stringshare_replace(&v->mount_point, eina_list_last_data_get(mounts));
1026 v->mounted = !!mounts;
1027 if (v->storage)
1028 v->storage->media_available = v->mounted;
1029 switch (v->optype)
1030 {
1031 case E_VOLUME_OP_TYPE_MOUNT:
1032 _e_fm_main_udisks2_cb_vol_mounted(v);
1033 break;
1034 case E_VOLUME_OP_TYPE_UNMOUNT:
1035 _e_fm_main_udisks2_cb_vol_unmounted(v);
1036 break;
1037 case E_VOLUME_OP_TYPE_EJECT:
1038 if (vols_ejecting && eina_list_data_find(vols_ejecting, v))
1039 _e_fm_main_udisks2_cb_vol_unmounted(v);
1040 else
1041 _e_fm_main_udisks2_cb_vol_ejected(v);
1042 break;
1043 default: break;
1044 }
1045 }
1046 E_FREE_LIST(mounts, eina_stringshare_del);
1047}
1048
1049E_Volume *
1050_e_fm_main_udisks2_volume_add(const char *path, Eina_Bool first_time)
1051{
1052 E_Volume *v;
1053 Eldbus_Object *obj;
1054
1055 if (!path) return NULL;
1056 if (_volume_find_by_dbus_path(path)) return NULL;
1057 v = calloc(1, sizeof(E_Volume));
1058 if (!v) return NULL;
1059 v->dbus_path = eina_stringshare_add(path);
1060 INF("VOL+ %s", path);
1061 v->efm_mode = EFM_MODE_USING_UDISKS2_MOUNT;
1062 v->first_time = first_time;
1063 _e_vols = eina_list_append(_e_vols, v);
1064 obj = eldbus_object_get(_e_fm_main_udisks2_conn, UDISKS2_BUS, path);
1065 v->proxy = eldbus_proxy_get(obj, UDISKS2_INTERFACE_FILESYSTEM);
1066 eldbus_proxy_properties_monitor(v->proxy, 1);
1067 eldbus_proxy_properties_changed_callback_add(v->proxy, _e_fm_main_udisks2_cb_vol_prop_modified_cb, v);
1068
1069 return v;
1070}
1071
1072void
1073_e_fm_main_udisks2_volume_del(const char *path)
1074{
1075 E_Volume *v;
1076
1077 v = _volume_find_by_dbus_path(path);
1078 if (!v) return;
1079 _volume_del(v);
1080}
1081
1082static void
1083_volume_del(E_Volume *v)
1084{
1085 E_FREE_FUNC(v->guard, ecore_timer_del);
1086 if (v->validated)
1087 {
1088 INF("--VOL %s", v->udi);
1089 /* FIXME: send event of storage volume (disk) removed */
1090 ecore_ipc_server_send(_e_fm_ipc_server,
1091 6 /*E_IPC_DOMAIN_FM*/,
1092 E_FM_OP_VOLUME_DEL,
1093 0, 0, 0, v->udi, eina_stringshare_strlen(v->udi) + 1);
1094 }
1095 v->optype = E_VOLUME_OP_TYPE_NONE;
1096 if (v->proxy)
1097 {
1098 Eldbus_Object *obj = eldbus_proxy_object_get(v->proxy);
1099 eldbus_proxy_unref(v->proxy);
1100 eldbus_object_unref(obj);
1101 }
1102 _e_vols = eina_list_remove(_e_vols, v);
1103 _e_fm_shared_device_volume_free(v);
1104}
1105
1106E_Volume *
1107_e_fm_main_udisks2_volume_find(const char *udi)
1108{
1109 Eina_List *l;
1110 E_Volume *v;
1111
1112 if (!udi) return NULL;
1113 EINA_LIST_FOREACH(_e_vols, l, v)
1114 {
1115 if (!v->udi) continue;
1116 if (!strcmp(udi, v->udi)) return v;
1117 }
1118 return NULL;
1119}
1120
1121static E_Volume *
1122_volume_find_by_dbus_path(const char *path)
1123{
1124 Eina_List *l;
1125 E_Volume *v;
1126
1127 if (!path) return NULL;
1128 EINA_LIST_FOREACH(_e_vols, l, v)
1129 if (!strcmp(path, v->dbus_path)) return v;
1130 return NULL;
1131}
1132
1133void
1134_e_fm_main_udisks2_volume_eject(E_Volume *v)
1135{
1136 if (!v || v->guard) return;
1137 if (!v->storage) v->storage = _e_fm_main_udisks2_storage_find(v->parent);
1138 if (!v->storage)
1139 {
1140 ERR("COULD NOT FIND DISK STORAGE!!!");
1141 return;
1142 }
1143 if (v->mounted)
1144 {
1145 v->guard = ecore_timer_add(E_FM_UNMOUNT_TIMEOUT, (Ecore_Task_Cb)_e_fm_main_udisks2_vol_unmount_timeout, v);
1146 v->op = _volume_umount(v);
1147 vols_ejecting = eina_list_append(vols_ejecting, v);
1148 }
1149 else
1150 {
1151 v->guard = ecore_timer_add(E_FM_EJECT_TIMEOUT, (Ecore_Task_Cb)_e_fm_main_udisks2_vol_eject_timeout, v);
1152 v->op = _volume_eject(v->storage->proxy);
1153 }
1154 v->optype = E_VOLUME_OP_TYPE_EJECT;
1155}
1156
1157void
1158_e_fm_main_udisks2_volume_unmount(E_Volume *v)
1159{
1160 if (!v || v->guard) return;
1161 INF("unmount %s %s", v->udi, v->mount_point);
1162
1163 v->guard = ecore_timer_add(E_FM_UNMOUNT_TIMEOUT, (Ecore_Task_Cb)_e_fm_main_udisks2_vol_unmount_timeout, v);
1164 v->op = _volume_umount(v);
1165 v->optype = E_VOLUME_OP_TYPE_UNMOUNT;
1166}
1167
1168void
1169_e_fm_main_udisks2_volume_mount(E_Volume *v)
1170{
1171 char buf[256] = {0};
1172
1173 if ((!v) || (v->guard))
1174 return;
1175
1176 INF("mount %s %s [fs type = %s]", v->udi, v->mount_point, v->fstype);
1177
1178 // Map uid to current user if possible
1179 // Possible filesystems found in udisks2 source (src/udisks2linuxfilesystem.c) as of 2012-07-11
1180 if (!strcmp(v->fstype, "vfat"))
1181 snprintf(buf, sizeof(buf), "uid=%i,utf8=1", (int)getuid());
1182 else if ((!strcmp(v->fstype, "iso9660")) || (!strcmp(v->fstype, "udf")))
1183 // force utf8 as the encoding - e only likes/handles utf8. its the
1184 // pseudo-standard these days anyway for "linux" for intl text to work
1185 // everywhere. problem is some fs's use differing options and udisks2
1186 // doesn't allow some options with certain filesystems.
1187 // Valid options found in udisks2 (src/udisks2linuxfilesystem.c) as of 2012-07-11
1188 // Note that these options are default with the latest udisks2, kept here to
1189 // avoid breakage in the future (hopefully).
1190 snprintf(buf, sizeof(buf), "uid=%i,iocharset=utf8", (int)getuid());
1191 else if (!strcmp(v->fstype, "ntfs"))
1192 snprintf(buf, sizeof(buf), "uid=%i", (int)getuid());
1193
1194 v->guard = ecore_timer_add(E_FM_MOUNT_TIMEOUT, (Ecore_Task_Cb)_e_fm_main_udisks2_vol_mount_timeout, v);
1195
1196 // It was previously noted here that ubuntu 10.04 failed to mount if opt was passed to
1197 // e_udisks2_volume_mount. The reason at the time was unknown and apparently never found.
1198 // I theorize that this was due to improper mount options being passed (namely the utf8 options).
1199 // If this still fails on Ubuntu 10.04 then an actual fix should be found.
1200 v->op = _volume_mount(v->proxy, v->fstype, buf);
1201
1202 v->optype = E_VOLUME_OP_TYPE_MOUNT;
1203}
1204
1205void
1206_e_fm_main_udisks2_init(void)
1207{
1208 eldbus_init();
1209 _e_fm_main_udisks2_conn = eldbus_connection_get(ELDBUS_CONNECTION_TYPE_SYSTEM);
1210 if (!_e_fm_main_udisks2_conn) return;
1211
1212 eldbus_name_start(_e_fm_main_udisks2_conn, UDISKS2_BUS, 0,
1213 _e_fm_main_udisks2_name_start, NULL);
1214}
1215
1216void
1217_e_fm_main_udisks2_shutdown(void)
1218{
1219 if (_e_fm_main_udisks2_proxy)
1220 {
1221 Eldbus_Object *obj;
1222 obj = eldbus_proxy_object_get(_e_fm_main_udisks2_proxy);
1223 eldbus_proxy_unref(_e_fm_main_udisks2_proxy);
1224 eldbus_object_unref(obj);
1225 }
1226 if (_e_fm_main_udisks2_conn)
1227 eldbus_connection_unref(_e_fm_main_udisks2_conn);
1228 eldbus_shutdown();
1229}
1230
1231E_Storage *
1232_e_fm_main_udisks2_storage_add(const char *path)
1233{
1234 E_Storage *s;
1235
1236 if (!path) return NULL;
1237 if (_storage_find_by_dbus_path(path)) return NULL;
1238 s = calloc(1, sizeof(E_Storage));
1239 if (!s) return NULL;
1240
1241 DBG("STORAGE+=%s", path);
1242 s->dbus_path = eina_stringshare_add(path);
1243 s->udi = eina_stringshare_ref(s->dbus_path);
1244 _e_stores = eina_list_append(_e_stores, s);
1245 return s;
1246}
1247
1248void
1249_e_fm_main_udisks2_storage_del(const char *path)
1250{
1251 E_Storage *s;
1252
1253 s = _storage_find_by_dbus_path(path);
1254 if (!s) return;
1255 if (s->validated)
1256 {
1257 stores_registered = eina_list_remove(stores_registered, s);
1258 INF("--STO %s", s->udi);
1259 ecore_ipc_server_send(_e_fm_ipc_server,
1260 6 /*E_IPC_DOMAIN_FM*/,
1261 E_FM_OP_STORAGE_DEL,
1262 0, 0, 0, s->udi, strlen(s->udi) + 1);
1263 }
1264 _e_stores = eina_list_remove(_e_stores, s);
1265 if (s->proxy)
1266 {
1267 Eldbus_Object *obj = eldbus_proxy_object_get(s->proxy);
1268 eldbus_proxy_unref(s->proxy);
1269 eldbus_object_unref(obj);
1270 }
1271 _e_fm_shared_device_storage_free(s);
1272}
1273
1274static E_Storage *
1275_storage_find_by_dbus_path(const char *path)
1276{
1277 Eina_List *l;
1278 E_Storage *s;
1279
1280 EINA_LIST_FOREACH(_e_stores, l, s)
1281 if (!strcmp(path, s->dbus_path)) return s;
1282 return NULL;
1283}
1284
1285E_Storage *
1286_e_fm_main_udisks2_storage_find(const char *udi)
1287{
1288 Eina_List *l;
1289 E_Storage *s;
1290
1291 EINA_LIST_FOREACH(_e_stores, l, s)
1292 {
1293 if (!s->udi) continue;
1294 if (!strcmp(udi, s->udi)) return s;
1295 }
1296 return NULL;
1297}
diff --git a/src/bin/e_fm/e_fm_main_udisks2.h b/src/bin/e_fm/e_fm_main_udisks2.h
new file mode 100644
index 000000000..c22fb2eb6
--- /dev/null
+++ b/src/bin/e_fm/e_fm_main_udisks2.h
@@ -0,0 +1,21 @@
1#ifndef E_FM_MAIN_UDISKS2_H
2#define E_FM_MAIN_UDISKS2_H
3
4E_Volume *_e_fm_main_udisks2_volume_add(const char *udi, Eina_Bool first_time);
5void _e_fm_main_udisks2_volume_del(const char *udi);
6E_Volume *_e_fm_main_udisks2_volume_find(const char *udi);
7
8void _e_fm_main_udisks2_volume_eject(E_Volume *v);
9void _e_fm_main_udisks2_volume_unmount(E_Volume *v);
10void _e_fm_main_udisks2_volume_mount(E_Volume *v);
11
12E_Storage *_e_fm_main_udisks2_storage_add(const char *udi);
13void _e_fm_main_udisks2_storage_del(const char *udi);
14E_Storage *_e_fm_main_udisks2_storage_find(const char *udi);
15
16
17void _e_fm_main_udisks2_init(void);
18void _e_fm_main_udisks2_shutdown(void);
19void _e_fm_main_udisks2_catch(Eina_Bool usable);
20
21#endif
diff --git a/src/bin/e_fm_shared_types.h.in b/src/bin/e_fm_shared_types.h.in
index d041b9ad7..06e0de29e 100644
--- a/src/bin/e_fm_shared_types.h.in
+++ b/src/bin/e_fm_shared_types.h.in
@@ -23,6 +23,7 @@ typedef enum
23 EFM_MODE_USING_RASTER_MOUNT, 23 EFM_MODE_USING_RASTER_MOUNT,
24 EFM_MODE_USING_HAL_MOUNT, 24 EFM_MODE_USING_HAL_MOUNT,
25 EFM_MODE_USING_UDISKS_MOUNT, 25 EFM_MODE_USING_UDISKS_MOUNT,
26 EFM_MODE_USING_UDISKS2_MOUNT,
26 EFM_MODE_USING_EEZE_MOUNT 27 EFM_MODE_USING_EEZE_MOUNT
27} Efm_Mode; 28} Efm_Mode;
28 29
diff --git a/src/modules/fileman/e_mod_config.c b/src/modules/fileman/e_mod_config.c
index c84da1d2f..bce0193c8 100644
--- a/src/modules/fileman/e_mod_config.c
+++ b/src/modules/fileman/e_mod_config.c
@@ -429,6 +429,9 @@ _basic_create(E_Config_Dialog *cfd __UNUSED__,
429 case EFM_MODE_USING_UDISKS_MOUNT: 429 case EFM_MODE_USING_UDISKS_MOUNT:
430 snprintf(buf, sizeof(buf), "%s: UDISKS", _("Mode")); 430 snprintf(buf, sizeof(buf), "%s: UDISKS", _("Mode"));
431 break; 431 break;
432 case EFM_MODE_USING_UDISKS2_MOUNT:
433 snprintf(buf, sizeof(buf), "%s: UDISKS2", _("Mode"));
434 break;
432 case EFM_MODE_USING_EEZE_MOUNT: 435 case EFM_MODE_USING_EEZE_MOUNT:
433 snprintf(buf, sizeof(buf), "%s: EEZE", _("Mode")); 436 snprintf(buf, sizeof(buf), "%s: EEZE", _("Mode"));
434 break; 437 break;