8 # define alloca __builtin_alloca
10 # define alloca __alloca
11 #elif defined _MSC_VER
13 # define alloca _alloca
29 #include <sys/types.h>
32 #include <sys/param.h>
45 #include <Ecore_Ipc.h>
46 #include <Ecore_File.h>
51 #include "e_fm_shared_device.h"
52 #include "e_fm_shared_codec.h"
54 #include "e_fm_device.h"
56 #include "e_fm_main_hal.h"
57 #ifdef HAVE_UDISKS_MOUNT
58 # include "e_fm_main_udisks.h"
61 #include "e_fm_main.h"
63 static E_DBus_Signal_Handler *_hal_poll = NULL;
64 static E_DBus_Connection *_e_fm_main_hal_conn = NULL;
65 static Eina_List *_e_stores = NULL;
67 static void _e_fm_main_hal_cb_dev_all(void *user_data,
70 static void _e_fm_main_hal_cb_dev_store(void *user_data,
73 static void _e_fm_main_hal_cb_dev_vol(void *user_data,
76 static void _e_fm_main_hal_cb_store_is(void *user_data,
79 static void _e_fm_main_hal_cb_vol_is(void *user_data,
82 static void _e_fm_main_hal_cb_dev_add(void *data,
84 static void _e_fm_main_hal_cb_dev_del(void *data,
86 static void _e_fm_main_hal_cb_cap_add(void *data,
88 static void _e_fm_main_hal_cb_prop_modified(void *data,
90 static void _e_fm_main_hal_cb_store_prop(void *data,
93 static void _e_fm_main_hal_cb_vol_prop(void *data,
96 static void _e_fm_main_hal_cb_vol_prop_mount_modified(void *data,
99 static void _e_fm_main_hal_cb_vol_mounted(void *user_data,
102 static void _e_fm_main_hal_cb_vol_unmounted(void *user_data,
105 static void _e_fm_main_hal_cb_vol_unmounted_before_eject(void *user_data,
109 static Eina_Bool _e_fm_main_hal_vb_vol_ejecting_after_unmount(void *data);
110 static void _e_fm_main_hal_cb_vol_ejected(void *user_data,
113 static int _e_fm_main_hal_format_error_msg(char **buf,
116 static void _e_fm_main_hal_test(void *data,
119 static void _e_fm_main_hal_poll(void *data,
122 static Eina_Bool _e_fm_main_hal_vol_mount_timeout(void *data);
123 static Eina_Bool _e_fm_main_hal_vol_unmount_timeout(void *data);
124 static Eina_Bool _e_fm_main_hal_vol_eject_timeout(void *data);
127 _e_fm_main_hal_poll(void *data __UNUSED__,
131 const char *name, *from, *to;
133 dbus_error_init(&err);
134 if (!dbus_message_get_args(msg, &err,
135 DBUS_TYPE_STRING, &name,
136 DBUS_TYPE_STRING, &from,
137 DBUS_TYPE_STRING, &to,
139 dbus_error_free(&err);
141 //printf("name: %s\nfrom: %s\nto: %s\n", name, from, to);
142 if ((name) && !strcmp(name, E_HAL_SENDER))
143 _e_fm_main_hal_test(NULL, NULL, NULL);
147 _e_fm_main_hal_test(void *data __UNUSED__,
148 DBusMessage *msg __UNUSED__,
151 if ((error) && (dbus_error_is_set(error)))
153 dbus_error_free(error);
155 _hal_poll = e_dbus_signal_handler_add(_e_fm_main_hal_conn,
156 E_DBUS_FDO_BUS, E_DBUS_FDO_PATH,
157 E_DBUS_FDO_INTERFACE,
158 "NameOwnerChanged", _e_fm_main_hal_poll, NULL);
159 #ifdef HAVE_UDISKS_MOUNT
160 _e_fm_main_udisks_init(); /* check for udisks while listening for hal */
162 _e_fm_main_hal_catch(EINA_FALSE);
167 e_dbus_signal_handler_del(_e_fm_main_hal_conn, _hal_poll);
169 e_hal_manager_get_all_devices(_e_fm_main_hal_conn, _e_fm_main_hal_cb_dev_all, NULL);
170 e_hal_manager_find_device_by_capability(_e_fm_main_hal_conn, "storage",
171 _e_fm_main_hal_cb_dev_store, NULL);
172 e_hal_manager_find_device_by_capability(_e_fm_main_hal_conn, "volume",
173 _e_fm_main_hal_cb_dev_vol, NULL);
175 e_dbus_signal_handler_add(_e_fm_main_hal_conn, E_HAL_SENDER,
177 E_HAL_MANAGER_INTERFACE,
178 "DeviceAdded", _e_fm_main_hal_cb_dev_add, NULL);
179 e_dbus_signal_handler_add(_e_fm_main_hal_conn, E_HAL_SENDER,
181 E_HAL_MANAGER_INTERFACE,
182 "DeviceRemoved", _e_fm_main_hal_cb_dev_del, NULL);
183 e_dbus_signal_handler_add(_e_fm_main_hal_conn, E_HAL_SENDER,
185 E_HAL_MANAGER_INTERFACE,
186 "NewCapability", _e_fm_main_hal_cb_cap_add, NULL);
187 _e_fm_main_hal_catch(EINA_TRUE); /* signal usage of HAL for mounting */
191 _e_fm_main_hal_cb_dev_all(void *user_data __UNUSED__,
195 E_Hal_Manager_Get_All_Devices_Return *ret = reply_data;
199 if (!ret || !ret->strings) return;
201 if (dbus_error_is_set(error))
203 dbus_error_free(error);
207 EINA_LIST_FOREACH(ret->strings, l, udi)
209 // printf("DB INIT DEV+: %s\n", udi);
210 e_hal_device_query_capability(_e_fm_main_hal_conn, udi, "storage",
211 _e_fm_main_hal_cb_store_is, (void *)eina_stringshare_add(udi));
212 e_hal_device_query_capability(_e_fm_main_hal_conn, udi, "volume",
213 _e_fm_main_hal_cb_vol_is, (void *)eina_stringshare_add(udi));
218 _e_fm_main_hal_cb_dev_store(void *user_data __UNUSED__,
222 E_Hal_Manager_Find_Device_By_Capability_Return *ret = reply_data;
226 if (!ret || !ret->strings) return;
228 if (dbus_error_is_set(error))
230 dbus_error_free(error);
234 EINA_LIST_FOREACH(ret->strings, l, device)
236 // printf("DB STORE+: %s\n", device);
237 _e_fm_main_hal_storage_add(device);
242 _e_fm_main_hal_cb_dev_vol(void *user_data __UNUSED__,
246 E_Hal_Manager_Find_Device_By_Capability_Return *ret = reply_data;
250 if (!ret || !ret->strings) return;
252 if (dbus_error_is_set(error))
254 dbus_error_free(error);
258 EINA_LIST_FOREACH(ret->strings, l, device)
260 // printf("DB VOL+: %s\n", device);
261 _e_fm_main_hal_volume_add(device, 1);
266 _e_fm_main_hal_cb_store_is(void *user_data,
270 char *udi = user_data;
271 E_Hal_Device_Query_Capability_Return *ret = reply_data;
273 if (dbus_error_is_set(error))
275 dbus_error_free(error);
279 if (ret && ret->boolean)
281 // printf("DB STORE IS+: %s\n", udi);
282 _e_fm_main_hal_storage_add(udi);
286 eina_stringshare_del(udi);
290 _e_fm_main_hal_cb_vol_is(void *user_data,
294 char *udi = user_data;
295 E_Hal_Device_Query_Capability_Return *ret = reply_data;
297 if (dbus_error_is_set(error))
299 dbus_error_free(error);
303 if (ret && ret->boolean)
305 // printf("DB VOL IS+: %s\n", udi);
306 _e_fm_main_hal_volume_add(udi, 0);
310 eina_stringshare_del(udi);
314 _e_fm_main_hal_cb_dev_add(void *data __UNUSED__,
320 dbus_error_init(&err);
321 dbus_message_get_args(msg, &err, DBUS_TYPE_STRING, &udi, DBUS_TYPE_INVALID);
323 e_hal_device_query_capability(_e_fm_main_hal_conn, udi, "storage",
324 _e_fm_main_hal_cb_store_is, (void *)eina_stringshare_add(udi));
325 e_hal_device_query_capability(_e_fm_main_hal_conn, udi, "volume",
326 _e_fm_main_hal_cb_vol_is, (void *)eina_stringshare_add(udi));
330 _e_fm_main_hal_cb_dev_del(void *data __UNUSED__,
336 dbus_error_init(&err);
338 dbus_message_get_args(msg,
339 &err, DBUS_TYPE_STRING,
340 &udi, DBUS_TYPE_INVALID);
341 // printf("DB DEV-: %s\n", udi);
342 _e_fm_main_hal_storage_del(udi);
343 _e_fm_main_hal_volume_del(udi);
347 _e_fm_main_hal_cb_cap_add(void *data __UNUSED__,
351 char *udi, *capability;
353 dbus_error_init(&err);
355 dbus_message_get_args(msg,
356 &err, DBUS_TYPE_STRING,
357 &udi, DBUS_TYPE_STRING,
358 &capability, DBUS_TYPE_INVALID);
359 if (!strcmp(capability, "storage"))
361 // printf("DB STORE CAP+: %s\n", udi);
362 _e_fm_main_hal_storage_add(udi);
367 _e_fm_main_hal_cb_prop_modified(void *data,
371 DBusMessageIter iter, sub, subsub;
378 int num_changes = 0, i;
380 if (!(v = data)) return;
382 if (dbus_message_get_error_name(msg))
384 printf("DBUS ERROR: %s\n", dbus_message_get_error_name(msg));
387 if (!dbus_message_iter_init(msg, &iter)) return;
389 if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_INT32) return;
390 dbus_message_iter_get_basic(&iter, &num_changes);
391 if (num_changes == 0) return;
393 dbus_message_iter_next(&iter);
394 if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY) return;
395 dbus_message_iter_recurse(&iter, &sub);
397 for (i = 0; i < num_changes; i++, dbus_message_iter_next(&sub))
399 dbus_message_iter_recurse(&sub, &subsub);
401 if (dbus_message_iter_get_arg_type(&subsub) != DBUS_TYPE_STRING) break;
402 dbus_message_iter_get_basic(&subsub, &(prop.name));
403 if (!strcmp(prop.name, "volume.mount_point"))
405 e_hal_device_get_all_properties(_e_fm_main_hal_conn, v->udi,
406 _e_fm_main_hal_cb_vol_prop_mount_modified,
411 dbus_message_iter_next(&subsub);
412 dbus_message_iter_next(&subsub);
417 _e_fm_main_hal_cb_store_prop(void *data,
422 E_Hal_Properties *ret = reply_data;
425 if (!ret) goto error;
427 if (dbus_error_is_set(error))
429 dbus_error_free(error);
433 s->bus = e_hal_property_string_get(ret, "storage.bus", &err);
435 s->bus = eina_stringshare_add(s->bus);
436 s->drive_type = e_hal_property_string_get(ret, "storage.drive_type", &err);
438 s->drive_type = eina_stringshare_add(s->drive_type);
439 s->model = e_hal_property_string_get(ret, "storage.model", &err);
441 s->model = eina_stringshare_add(s->model);
442 s->vendor = e_hal_property_string_get(ret, "storage.vendor", &err);
444 s->vendor = eina_stringshare_add(s->vendor);
445 s->serial = e_hal_property_string_get(ret, "storage.serial", &err);
446 // if (err) goto error;
447 if (err) printf("Error getting serial for %s\n", s->udi);
448 s->serial = eina_stringshare_add(s->serial);
450 s->removable = e_hal_property_bool_get(ret, "storage.removable", &err);
454 s->media_available = e_hal_property_bool_get(ret, "storage.removable.media_available", &err);
455 s->media_size = e_hal_property_uint64_get(ret, "storage.removable.media_size", &err);
458 s->requires_eject = e_hal_property_bool_get(ret, "storage.requires_eject", &err);
459 s->hotpluggable = e_hal_property_bool_get(ret, "storage.hotpluggable", &err);
460 s->media_check_enabled = e_hal_property_bool_get(ret, "storage.media_check_enabled", &err);
462 s->icon.drive = e_hal_property_string_get(ret, "storage.icon.drive", &err);
463 s->icon.drive = eina_stringshare_add(s->icon.drive);
464 s->icon.volume = e_hal_property_string_get(ret, "storage.icon.volume", &err);
465 s->icon.volume = eina_stringshare_add(s->icon.volume);
467 // printf("++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\n", s->udi, s->bus, s->drive_type, s->model, s->vendor, s->serial, s->icon.drive, s->icon.volume);
468 s->validated = EINA_TRUE;
473 msg_data = _e_fm_shared_codec_storage_encode(s, &msg_size);
476 ecore_ipc_server_send(_e_fm_ipc_server,
477 6 /*E_IPC_DOMAIN_FM*/,
479 0, 0, 0, msg_data, msg_size);
486 // printf("ERR %s\n", s->udi);
487 _e_fm_main_hal_storage_del(s->udi);
491 _e_fm_main_hal_cb_vol_prop(void *data,
497 E_Hal_Device_Get_All_Properties_Return *ret = reply_data;
499 const char *str = NULL;
501 if (!ret) goto error;
502 if (dbus_error_is_set(error))
504 dbus_error_free(error);
508 /* skip volumes with volume.ignore set */
509 if (e_hal_property_bool_get(ret, "volume.ignore", &err) || err)
512 /* skip volumes that aren't filesystems */
513 str = e_hal_property_string_get(ret, "volume.fsusage", &err);
514 if (err || !str) goto error;
515 if (strcmp(str, "filesystem")) goto error;
518 v->uuid = e_hal_property_string_get(ret, "volume.uuid", &err);
520 v->uuid = eina_stringshare_add(v->uuid);
522 v->label = e_hal_property_string_get(ret, "volume.label", &err);
523 // if (err) goto error;
524 v->label = eina_stringshare_add(v->label);
526 v->fstype = e_hal_property_string_get(ret, "volume.fstype", &err);
527 // if (err) goto error;
528 v->fstype = eina_stringshare_add(v->fstype);
530 v->size = e_hal_property_uint64_get(ret, "volume.size", &err);
532 v->mounted = e_hal_property_bool_get(ret, "volume.is_mounted", &err);
535 v->partition = e_hal_property_bool_get(ret, "volume.is_partition", &err);
538 v->mount_point = e_hal_property_string_get(ret, "volume.mount_point", &err);
540 v->mount_point = eina_stringshare_add(v->mount_point);
544 v->partition_number = e_hal_property_int_get(ret, "volume.partition.number", NULL);
545 v->partition_label = e_hal_property_string_get(ret, "volume.partition.label", NULL);
546 v->partition_label = eina_stringshare_add(v->partition_label);
549 v->parent = e_hal_property_string_get(ret, "info.parent", &err);
550 if ((!err) && (v->parent))
552 s = e_storage_find(v->parent);
556 s->volumes = eina_list_append(s->volumes, v);
559 v->parent = eina_stringshare_add(v->parent);
561 // printf("++VOL:\n udi: %s\n uuid: %s\n fstype: %s\n size: %llu\n label: %s\n partition: %d\n partition_number: %d\n partition_label: %s\n mounted: %d\n mount_point: %s\n", v->udi, v->uuid, v->fstype, v->size, v->label, v->partition, v->partition_number, v->partition ? v->partition_label : "(not a partition)", v->mounted, v->mount_point);
562 // if (s) printf(" for storage: %s\n", s->udi);
563 // else printf(" storage unknown\n");
564 v->validated = EINA_TRUE;
569 msg_data = _e_fm_shared_codec_volume_encode(v, &msg_size);
572 ecore_ipc_server_send(_e_fm_ipc_server,
573 6 /*E_IPC_DOMAIN_FM*/,
575 0, 0, 0, msg_data, msg_size);
582 _e_fm_main_hal_volume_del(v->udi);
587 _e_fm_main_hal_format_error_msg(char **buf,
591 int size, vu, vm, en;
594 vu = strlen(v->udi) + 1;
595 vm = strlen(v->mount_point) + 1;
596 en = strlen(error->name) + 1;
597 size = vu + vm + en + strlen(error->message) + 1;
598 tmp = *buf = malloc(size);
602 strcpy(tmp, v->mount_point);
604 strcpy(tmp, error->name);
606 strcpy(tmp, error->message);
612 _e_fm_main_hal_cb_vol_prop_mount_modified(void *data,
617 E_Hal_Device_Get_All_Properties_Return *ret = reply_data;
621 if (dbus_error_is_set(error))
626 size = _e_fm_main_hal_format_error_msg(&buf, v, error);
628 ecore_ipc_server_send(_e_fm_ipc_server, 6 /*E_IPC_DOMAIN_FM*/, E_FM_OP_UNMOUNT_ERROR,
631 ecore_ipc_server_send(_e_fm_ipc_server, 6 /*E_IPC_DOMAIN_FM*/, E_FM_OP_MOUNT_ERROR,
633 dbus_error_free(error);
638 v->mounted = e_hal_property_bool_get(ret, "volume.is_mounted", &err);
639 if (err) printf("HAL Error : can't get volume.is_mounted property");
641 if (v->mount_point) eina_stringshare_del(v->mount_point);
642 v->mount_point = e_hal_property_string_get(ret, "volume.mount_point", &err);
643 if (err) printf("HAL Error : can't get volume.is_mount_point property");
644 v->mount_point = eina_stringshare_add(v->mount_point);
646 // printf("**VOL udi: %s mount_point: %s mounted: %d\n", v->udi, v->mount_point, v->mounted);
651 size = strlen(v->udi) + 1 + strlen(v->mount_point) + 1;
654 strcpy(buf + strlen(buf) + 1, v->mount_point);
656 ecore_ipc_server_send(_e_fm_ipc_server,
657 6 /*E_IPC_DOMAIN_FM*/,
661 ecore_ipc_server_send(_e_fm_ipc_server,
662 6 /*E_IPC_DOMAIN_FM*/,
663 E_FM_OP_UNMOUNT_DONE,
670 _e_fm_main_hal_vol_mount_timeout(void *data)
678 dbus_pending_call_cancel(v->op);
679 error.name = "org.enlightenment.fm2.MountTimeout";
680 error.message = "Unable to mount the volume with specified time-out.";
681 size = _e_fm_main_hal_format_error_msg(&buf, v, &error);
682 ecore_ipc_server_send(_e_fm_ipc_server, 6 /*E_IPC_DOMAIN_FM*/, E_FM_OP_MOUNT_ERROR,
686 return ECORE_CALLBACK_CANCEL;
690 _e_fm_main_hal_cb_vol_mounted(void *user_data,
691 void *method_return __UNUSED__,
694 E_Volume *v = user_data;
700 ecore_timer_del(v->guard);
704 if (dbus_error_is_set(error))
706 size = _e_fm_main_hal_format_error_msg(&buf, v, error);
707 ecore_ipc_server_send(_e_fm_ipc_server, 6 /*E_IPC_DOMAIN_FM*/, E_FM_OP_MOUNT_ERROR,
709 dbus_error_free(error);
715 v->mounted = EINA_TRUE;
716 // printf("MOUNT: %s from %s\n", v->udi, v->mount_point);
717 size = strlen(v->udi) + 1 + strlen(v->mount_point) + 1;
720 strcpy(buf + strlen(buf) + 1, v->mount_point);
721 ecore_ipc_server_send(_e_fm_ipc_server,
722 6 /*E_IPC_DOMAIN_FM*/,
729 _e_fm_main_hal_vol_unmount_timeout(void *data)
737 dbus_pending_call_cancel(v->op);
738 error.name = "org.enlightenment.fm2.UnmountTimeout";
739 error.message = "Unable to unmount the volume with specified time-out.";
740 size = _e_fm_main_hal_format_error_msg(&buf, v, &error);
741 ecore_ipc_server_send(_e_fm_ipc_server, 6 /*E_IPC_DOMAIN_FM*/, E_FM_OP_UNMOUNT_ERROR,
745 return ECORE_CALLBACK_CANCEL;
749 _e_fm_main_hal_cb_vol_unmounted(void *user_data,
750 void *method_return __UNUSED__,
753 E_Volume *v = user_data;
759 ecore_timer_del(v->guard);
763 if (dbus_error_is_set(error))
765 size = _e_fm_main_hal_format_error_msg(&buf, v, error);
766 ecore_ipc_server_send(_e_fm_ipc_server, 6 /*E_IPC_DOMAIN_FM*/, E_FM_OP_UNMOUNT_ERROR,
768 dbus_error_free(error);
774 v->mounted = EINA_FALSE;
775 // printf("UNMOUNT: %s from %s\n", v->udi, v->mount_point);
776 size = strlen(v->udi) + 1 + strlen(v->mount_point) + 1;
779 strcpy(buf + strlen(buf) + 1, v->mount_point);
780 ecore_ipc_server_send(_e_fm_ipc_server,
781 6 /*E_IPC_DOMAIN_FM*/,
782 E_FM_OP_UNMOUNT_DONE,
788 _e_fm_main_hal_vol_eject_timeout(void *data)
796 dbus_pending_call_cancel(v->op);
797 error.name = "org.enlightenment.fm2.EjectTimeout";
798 error.message = "Unable to eject the media with specified time-out.";
799 size = _e_fm_main_hal_format_error_msg(&buf, v, &error);
800 ecore_ipc_server_send(_e_fm_ipc_server, 6 /*E_IPC_DOMAIN_FM*/, E_FM_OP_EJECT_ERROR,
804 return ECORE_CALLBACK_CANCEL;
808 _e_fm_main_hal_vb_vol_ejecting_after_unmount(void *data)
812 v->guard = ecore_timer_add(E_FM_EJECT_TIMEOUT, _e_fm_main_hal_vol_eject_timeout, v);
813 v->op = e_hal_device_volume_eject(_e_fm_main_hal_conn, v->udi, NULL,
814 _e_fm_main_hal_cb_vol_ejected, v);
816 return ECORE_CALLBACK_CANCEL;
820 _e_fm_main_hal_cb_vol_unmounted_before_eject(void *user_data,
824 E_Volume *v = user_data;
827 err = dbus_error_is_set(error) ? 1 : 0;
828 _e_fm_main_hal_cb_vol_unmounted(user_data, method_return, error);
830 // delay is required for all message handlers were executed after unmount
832 ecore_timer_add(1.0, _e_fm_main_hal_vb_vol_ejecting_after_unmount, v);
836 _e_fm_main_hal_cb_vol_ejected(void *user_data,
837 void *method_return __UNUSED__,
840 E_Volume *v = user_data;
846 ecore_timer_del(v->guard);
850 if (dbus_error_is_set(error))
852 size = _e_fm_main_hal_format_error_msg(&buf, v, error);
853 ecore_ipc_server_send(_e_fm_ipc_server, 6 /*E_IPC_DOMAIN_FM*/, E_FM_OP_EJECT_ERROR,
855 dbus_error_free(error);
860 size = strlen(v->udi) + 1;
863 ecore_ipc_server_send(_e_fm_ipc_server,
864 6 /*E_IPC_DOMAIN_FM*/,
869 static Eina_List *_e_vols = NULL;
872 _e_fm_main_hal_volume_add(const char *udi,
873 Eina_Bool first_time)
877 if (!udi) return NULL;
878 if (e_volume_find(udi)) return NULL;
879 v = calloc(1, sizeof(E_Volume));
881 // printf("VOL+ %s\n", udi);
882 v->udi = eina_stringshare_add(udi);
883 v->efm_mode = EFM_MODE_USING_HAL_MOUNT;
885 v->first_time = first_time;
886 _e_vols = eina_list_append(_e_vols, v);
887 e_hal_device_get_all_properties(_e_fm_main_hal_conn, v->udi,
888 _e_fm_main_hal_cb_vol_prop, v);
889 v->prop_handler = e_dbus_signal_handler_add(_e_fm_main_hal_conn,
892 E_HAL_DEVICE_INTERFACE,
894 _e_fm_main_hal_cb_prop_modified, v);
901 _e_fm_main_hal_volume_del(const char *udi)
905 v = e_volume_find(udi);
909 ecore_timer_del(v->guard);
912 if (v->prop_handler) e_dbus_signal_handler_del(_e_fm_main_hal_conn, v->prop_handler);
915 // printf("--VOL %s\n", v->udi);
916 /* FIXME: send event of storage volume (disk) removed */
917 ecore_ipc_server_send(_e_fm_ipc_server,
918 6 /*E_IPC_DOMAIN_FM*/,
920 0, 0, 0, v->udi, eina_stringshare_strlen(v->udi) + 1);
922 _e_vols = eina_list_remove(_e_vols, v);
923 _e_fm_shared_device_volume_free(v);
927 _e_fm_main_hal_volume_find(const char *udi)
932 if (!udi) return NULL;
933 EINA_LIST_FOREACH(_e_vols, l, v)
935 if (!v->udi) continue;
936 if (!strcmp(udi, v->udi)) return v;
942 _e_fm_main_hal_volume_eject(E_Volume *v)
944 if (!v || v->guard) return;
947 v->guard = ecore_timer_add(E_FM_UNMOUNT_TIMEOUT, _e_fm_main_hal_vol_unmount_timeout, v);
948 v->op = e_hal_device_volume_unmount(_e_fm_main_hal_conn, v->udi, NULL,
949 _e_fm_main_hal_cb_vol_unmounted_before_eject, v);
953 v->guard = ecore_timer_add(E_FM_EJECT_TIMEOUT, _e_fm_main_hal_vol_eject_timeout, v);
954 v->op = e_hal_device_volume_eject(_e_fm_main_hal_conn, v->udi, NULL,
955 _e_fm_main_hal_cb_vol_ejected, v);
960 _e_fm_main_hal_volume_unmount(E_Volume *v)
962 // printf("unmount %s %s\n", v->udi, v->mount_point);
963 if (!v || v->guard) return;
965 v->guard = ecore_timer_add(E_FM_UNMOUNT_TIMEOUT, _e_fm_main_hal_vol_unmount_timeout, v);
966 v->op = e_hal_device_volume_unmount(_e_fm_main_hal_conn, v->udi, NULL,
967 _e_fm_main_hal_cb_vol_unmounted, v);
971 _e_fm_main_hal_volume_mount(E_Volume *v)
975 const char *mount_point;
976 Eina_List *opt = NULL;
978 if ((!v) || (v->guard) || (!v->mount_point) ||
979 (strncmp(v->mount_point, "/media/", 7)))
982 mount_point = v->mount_point + 7;
983 // printf("mount %s %s [fs type = %s]\n", v->udi, v->mount_point, v->fstype);
985 // for vfat and ntfs we want the uid mapped to the user mounting, if we can
986 if ((!strcmp(v->fstype, "vfat")) ||
987 (!strcmp(v->fstype, "ntfs"))
990 snprintf(buf, sizeof(buf), "uid=%i", (int)getuid());
991 opt = eina_list_append(opt, buf);
994 // force utf8 as the encoding - e only likes/handles utf8. its the
995 // pseudo-standard these days anyway for "linux" for intl text to work
996 // everywhere. problem is some fs's use differing options
997 if ((!strcmp(v->fstype, "vfat")) ||
998 (!strcmp(v->fstype, "ntfs")) ||
999 (!strcmp(v->fstype, "iso9660"))
1002 snprintf(buf2, sizeof(buf2), "utf8");
1003 opt = eina_list_append(opt, buf2);
1005 else if ((!strcmp(v->fstype, "fat")) ||
1006 (!strcmp(v->fstype, "jfs")) ||
1007 (!strcmp(v->fstype, "udf"))
1010 snprintf(buf2, sizeof(buf2), "iocharset=utf8");
1011 opt = eina_list_append(opt, buf2);
1014 v->guard = ecore_timer_add(E_FM_MOUNT_TIMEOUT,
1015 _e_fm_main_hal_vol_mount_timeout, v);
1016 v->op = e_hal_device_volume_mount(_e_fm_main_hal_conn, v->udi, mount_point,
1018 _e_fm_main_hal_cb_vol_mounted, v);
1019 eina_list_free(opt);
1023 _e_fm_main_hal_init(void)
1027 _e_fm_main_hal_conn = e_dbus_bus_get(DBUS_BUS_SYSTEM);
1028 /* previously, this assumed that if dbus was running, hal was running. */
1029 if (_e_fm_main_hal_conn)
1030 e_dbus_get_name_owner(_e_fm_main_hal_conn, E_HAL_SENDER, _e_fm_main_hal_test, NULL);
1034 _e_fm_main_hal_shutdown(void)
1036 if (_e_fm_main_hal_conn)
1037 e_dbus_connection_close(_e_fm_main_hal_conn);
1043 _e_fm_main_hal_storage_add(const char *udi)
1047 if (!udi) return NULL;
1048 if (e_storage_find(udi)) return NULL;
1049 s = calloc(1, sizeof(E_Storage));
1050 if (!s) return NULL;
1051 s->udi = eina_stringshare_add(udi);
1052 _e_stores = eina_list_append(_e_stores, s);
1053 e_hal_device_get_all_properties(_e_fm_main_hal_conn, s->udi,
1054 _e_fm_main_hal_cb_store_prop, s);
1059 _e_fm_main_hal_storage_del(const char *udi)
1063 s = e_storage_find(udi);
1067 // printf("--STO %s\n", s->udi);
1068 ecore_ipc_server_send(_e_fm_ipc_server,
1069 6 /*E_IPC_DOMAIN_FM*/,
1070 E_FM_OP_STORAGE_DEL,
1071 0, 0, 0, s->udi, strlen(s->udi) + 1);
1073 _e_stores = eina_list_remove(_e_stores, s);
1074 _e_fm_shared_device_storage_free(s);
1078 _e_fm_main_hal_storage_find(const char *udi)
1083 EINA_LIST_FOREACH(_e_stores, l, s)
1085 if (!strcmp(udi, s->udi)) return s;