1 #include "e_fm_device.h"
2 #include "e_fm_shared_codec.h"
3 #include "e_fm_shared_device.h"
5 static void _e_fm2_volume_write(E_Volume *v) EINA_ARG_NONNULL(1);
6 static void _e_fm2_volume_erase(E_Volume *v) EINA_ARG_NONNULL(1);
7 static void _e_fm2_device_mount_free(E_Fm2_Mount *m) EINA_ARG_NONNULL(1);
8 static void _e_fm2_device_mount_ok(E_Fm2_Mount *m) EINA_ARG_NONNULL(1);
9 static void _e_fm2_device_mount_fail(E_Fm2_Mount *m) EINA_ARG_NONNULL(1);
10 static void _e_fm2_device_unmount_ok(E_Fm2_Mount *m) EINA_ARG_NONNULL(1);
11 static void _e_fm2_device_unmount_fail(E_Fm2_Mount *m) EINA_ARG_NONNULL(1);
13 static Eina_List *_e_stores = NULL;
14 static Eina_List *_e_vols = NULL;
17 _e_fm2_device_volume_setup(E_Volume *v)
19 char label[1024] = {0};
21 const char *icon = NULL;
22 /* unsigned long long sz; */
24 /* Compute the size in a readable form */
26 size = e_util_size_string_get(v->size);
28 /* Choose the label */
29 if ((v->label) && (v->label[0]))
31 else if ((v->partition_label) && (v->partition_label[0]))
32 snprintf(label, sizeof(label) - 1, "%s", v->partition_label);
33 else if (((v->storage->vendor) && (v->storage->vendor[0])) &&
34 ((v->storage->model) && (v->storage->model[0])))
36 if (size && (size[0] != '\0'))
37 snprintf(label, sizeof(label) - 1, _("%s %s—%s"), v->storage->vendor, v->storage->model, size);
39 snprintf(label, sizeof(label) - 1, "%s %s", v->storage->vendor, v->storage->model);
41 else if ((v->storage->model) && (v->storage->model[0]))
43 if (size && (size[0] != '\0'))
44 snprintf(label, sizeof(label) - 1, _("%s—%s"), v->storage->model, size);
46 snprintf(label, sizeof(label) - 1, "%s", v->storage->model);
48 else if ((v->storage->vendor) && (v->storage->vendor[0]))
50 if (size && (size[0] != '\0'))
51 snprintf(label, sizeof(label) - 1, _("%s—%s"), v->storage->vendor, size);
53 snprintf(label, sizeof(label) - 1, "%s", v->storage->vendor);
55 else if (v->storage->drive_type && (!strcmp(v->storage->drive_type, "sd_mmc")))
56 snprintf(label, sizeof(label) - 1, _("Flash Card—%s"), size);
58 snprintf(label, sizeof(label), _("Unknown Volume"));
60 if (label[0]) eina_stringshare_replace(&v->label, label);
63 /* http://standards.freedesktop.org/icon-naming-spec/icon-naming-spec-latest.html */
64 if (v->storage->icon.volume)
65 icon = v->storage->icon.volume;
68 if ((!v->storage->drive_type) || (!strcmp(v->storage->drive_type, "disk")) || (!strcmp(v->storage->drive_type, "partition")))
70 if (v->storage->removable == 0)
71 icon = "drive-harddisk";
73 icon = "drive-removable-media";
75 else if ((!strcmp(v->storage->drive_type, "cdrom")) || (!strncmp(v->storage->drive_type, "optical", 7)))
76 icon = "drive-optical";
77 else if (!strncmp(v->storage->drive_type, "floppy", 6))
78 icon = "media-floppy";
79 else if (!strcmp(v->storage->drive_type, "tape"))
81 else if (!strcmp(v->storage->drive_type, "compact_flash")
82 || !strcmp(v->storage->drive_type, "memory_stick")
83 || !strcmp(v->storage->drive_type, "smart_media")
84 || !strcmp(v->storage->drive_type, "sd_mmc")
85 || !strncmp(v->storage->drive_type, "flash", 5))
88 if (icon) eina_stringshare_replace(&v->icon, icon);
90 if ((!v->mount_point) ||
91 // filter out these mountouts - hack hack
92 (strcmp(v->mount_point, "/") &&
93 strcmp(v->mount_point, "/home") &&
94 strcmp(v->mount_point, "/tmp")))
95 _e_fm2_volume_write(v);
101 e_fm2_device_storage_add(E_Storage *s)
106 if (e_fm2_device_storage_find(s->udi)) return;
108 s->validated = EINA_TRUE;
109 _e_stores = eina_list_append(_e_stores, s);
119 " media_available: %i\n"
120 " media_size: %lli\n"
121 " requires_eject: %i\n"
122 " hotpluggable: %i\n"
123 " media_check_enabled: %i\n"
125 " icon.volume: %s\n\n"
138 s->media_check_enabled,
142 if ((s->removable == 0) &&
143 (s->media_available == 0) &&
144 (s->media_size == 0) &&
145 (s->requires_eject == 0) &&
146 (s->hotpluggable == 0) &&
147 (s->media_check_enabled == 0))
149 // printf(" Ignore this storage\n");
153 s->trackable = EINA_TRUE;
156 EINA_LIST_FOREACH(_e_vols, l, v) /* catch volumes which were added before their storage */
158 if ((!v->storage) && (s->udi == v->parent))
161 _e_fm2_device_volume_setup(v);
167 e_fm2_device_storage_del(E_Storage *s)
169 // printf("STO- %s\n", s->udi);
170 _e_stores = eina_list_remove(_e_stores, s);
171 _e_fm_shared_device_storage_free(s);
175 e_fm2_device_storage_find(const char *udi)
180 if (!udi) return NULL;
181 EINA_LIST_FOREACH(_e_stores, l, s)
183 if (!strcmp(udi, s->udi)) return s;
190 e_fm2_device_volume_add(E_Volume *v)
194 if (e_fm2_device_volume_find(v->udi)) return;
196 v->validated = EINA_TRUE;
197 _e_vols = eina_list_append(_e_vols, v);
206 " partition_number: %d\n"
207 " partition_label: %s\n"
219 v->partition ? v->partition_label : "(not a partition)",
224 /* Check mount point */
225 if ((v->efm_mode == EFM_MODE_USING_HAL_MOUNT) &&
226 ((!v->mount_point) || (!v->mount_point[0])))
228 eina_stringshare_del(v->mount_point);
229 v->mount_point = NULL;
230 v->mount_point = e_fm2_device_volume_mountpoint_get(v);
231 if ((!v->mount_point) || (!v->mount_point[0]))
236 if (v->mount_point) eina_stringshare_del(v->mount_point);
237 v->mount_point = NULL;
239 if ((v->uuid) && (v->uuid[0])) id = v->uuid;
240 if (ecore_file_is_dir("/media"))
241 snprintf(buf, sizeof(buf), "/media/%s", id);
242 else if (ecore_file_is_dir("/mnt"))
243 snprintf(buf, sizeof(buf), "/mnt/%s", id);
244 else if (ecore_file_is_dir("/tmp"))
245 snprintf(buf, sizeof(buf), "/tmp/%s", id);
248 v->mount_point = eina_stringshare_add(buf);
252 /* Search parent storage */
253 if ((s = e_fm2_device_storage_find(v->parent)))
256 s->volumes = eina_list_append(s->volumes, v);
259 if (v->storage) _e_fm2_device_volume_setup(v);
264 e_fm2_device_volume_del(E_Volume *v)
268 // printf("VOL- %s\n", v->udi);
269 _e_vols = eina_list_remove(_e_vols, v);
270 _e_fm2_volume_erase(v);
273 v->storage->volumes = eina_list_remove(v->storage->volumes, v);
276 EINA_LIST_FREE(v->mounts, m)
278 _e_fm2_device_unmount_ok(m);
279 _e_fm2_device_mount_free(m);
281 _e_fm_shared_device_volume_free(v);
285 _e_fm2_volume_write(E_Volume *v)
287 char buf[PATH_MAX], buf2[PATH_MAX];
291 if (!v->storage) return;
292 id = ecore_file_file_get(v->storage->udi);
293 e_user_dir_snprintf(buf, sizeof(buf), "fileman/favorites/|%s_%d.desktop",
294 id, v->partition_number);
303 "X-Enlightenment-Type=Removable\n"
304 "X-Enlightenment-Removable-State=Full\n"
312 _("Removable Device"),
316 if (e_config->device_desktop)
318 e_user_homedir_snprintf(buf2, sizeof(buf2),
320 _("Desktop"), id, v->partition_number);
321 ecore_file_symlink(buf, buf2);
324 /* FIXME: manipulate icon directly */
325 _e_fm2_file_force_update(buf);
326 _e_fm2_file_force_update(buf2);
331 _e_fm2_volume_erase(E_Volume *v)
333 char buf[PATH_MAX] = {0};
336 if (!v->storage) return;
337 id = ecore_file_file_get(v->storage->udi);
338 if (e_config->device_desktop)
340 e_user_homedir_snprintf(buf, sizeof(buf), "%s/|%s_%d.desktop",
341 _("Desktop"), id, v->partition_number);
342 ecore_file_unlink(buf);
343 _e_fm2_file_force_update(buf);
345 e_user_dir_snprintf(buf, sizeof(buf),
346 "fileman/favorites/|%s_%d.desktop",
347 id, v->partition_number);
348 ecore_file_unlink(buf);
349 _e_fm2_file_force_update(buf);
353 e_fm2_device_volume_find(const char *udi)
358 if (!udi) return NULL;
360 EINA_LIST_FOREACH(_e_vols, l, v)
362 if (!v->udi) continue;
363 if (!strcmp(udi, v->udi)) return v;
370 e_fm2_device_volume_find_fast(const char *udi)
375 if (!udi) return NULL;
377 EINA_LIST_FOREACH(_e_vols, l, v)
378 if (udi == v->udi) return v;
384 e_fm2_device_volume_mountpoint_get(E_Volume *v)
386 char buf[PATH_MAX] = {0};
391 // printf("GET MOUNTPOINT = %s\n", v->mount_point);
392 return eina_stringshare_add(v->mount_point);
394 else if (v->efm_mode != EFM_MODE_USING_HAL_MOUNT)
397 if (v->label && v->label[0] != '\0')
398 snprintf(buf, sizeof(buf) - 1, "/media/%s", v->label);
399 else if (v->uuid && v->uuid[0] != '\0')
400 snprintf(buf, sizeof(buf) - 1, "/media/%s", v->uuid);
401 else if ((v->storage) && (v->storage->serial) && v->storage->serial[0] != '\0')
402 snprintf(buf, sizeof(buf) - 1, "/media/%s", v->storage->serial);
405 static int mount_count = 1;
406 snprintf(buf, sizeof(buf) - 1, "/media/unknown-%i", mount_count++);
408 // printf("GET MOUNTPOINT = %s\n", buf);
409 return eina_stringshare_add(buf);
413 e_fm2_device_mount_add(E_Volume *v,
414 const char *mountpoint)
419 v->mounted = EINA_TRUE;
420 if (mountpoint && (mountpoint[0]))
421 eina_stringshare_replace(&v->mount_point, mountpoint);
423 EINA_LIST_FOREACH(v->mounts, l, m)
424 _e_fm2_device_mount_ok(m);
426 // printf("MOUNT %s %s\n", v->udi, v->mount_point);
430 e_fm2_device_mount_del(E_Volume *v)
434 v->mounted = EINA_FALSE;
437 eina_stringshare_del(v->mount_point);
438 v->mount_point = NULL;
441 EINA_LIST_FREE(v->mounts, m)
443 _e_fm2_device_unmount_ok(m);
444 _e_fm2_device_mount_free(m);
449 _e_fm2_device_mount_free(E_Fm2_Mount *m)
453 if (m->udi) eina_stringshare_del(m->udi);
454 if (m->mount_point) eina_stringshare_del(m->mount_point);
460 e_fm2_device_mount_find(const char *path)
465 if (!path) return NULL;
467 EINA_LIST_FOREACH(_e_vols, l, v)
471 && !strncmp(path, v->mount_point, strlen(v->mount_point))
473 return eina_list_data_get(v->mounts);
479 e_fm2_device_mount(E_Volume *v,
483 Ecore_Cb unmount_fail,
490 m = calloc(1, sizeof(E_Fm2_Mount));
492 m->udi = eina_stringshare_add(v->udi);
493 m->mount_ok = mount_ok;
494 m->mount_fail = mount_fail;
495 m->unmount_ok = unmount_ok;
496 m->unmount_fail = unmount_fail;
499 m->mounted = v->mounted;
501 v->mounts = eina_list_prepend(v->mounts, m);
506 //printf("BEGIN MOUNT %p '%s'\n", m, v->mount_point);
507 v->auto_unmount = EINA_TRUE;
508 _e_fm2_client_mount(v->udi, v->mount_point);
512 v->auto_unmount = EINA_FALSE;
513 m->mount_point = eina_stringshare_add(v->mount_point);
520 e_fm2_device_mount_fail(E_Volume *v)
524 v->mounted = EINA_FALSE;
527 eina_stringshare_del(v->mount_point);
528 v->mount_point = NULL;
531 EINA_LIST_FREE(v->mounts, m)
533 _e_fm2_device_mount_fail(m);
534 _e_fm2_device_mount_free(m);
539 e_fm2_device_unmount(E_Fm2_Mount *m)
543 if (!(v = m->volume)) return;
544 v->mounts = eina_list_remove(v->mounts, m);
545 _e_fm2_device_mount_free(m);
547 if (v->auto_unmount && v->mounted && !eina_list_count(v->mounts))
549 //printf("BEGIN UNMOUNT %p '%s'\n", m, v->udi);
550 _e_fm2_client_unmount(v->udi);
555 e_fm2_device_unmount_fail(E_Volume *v)
560 v->mounted = EINA_TRUE;
562 EINA_LIST_FOREACH(v->mounts, l, m)
563 _e_fm2_device_unmount_fail(m);
567 _e_fm2_device_mount_ok(E_Fm2_Mount *m)
569 if (m->mounted) return;
570 m->mounted = EINA_TRUE;
572 m->mount_point = eina_stringshare_add(m->volume->mount_point);
574 m->mount_ok(m->data);
575 //printf("MOUNT OK '%s'\n", m->mount_point);
579 _e_fm2_device_mount_fail(E_Fm2_Mount *m)
581 //printf("MOUNT FAIL '%s'\n", m->mount_point);
582 m->mounted = EINA_FALSE;
585 eina_stringshare_del(m->mount_point);
586 m->mount_point = NULL;
589 m->mount_fail(m->data);
593 _e_fm2_device_unmount_ok(E_Fm2_Mount *m)
595 if (!m->mounted) return;
596 m->mounted = EINA_FALSE;
599 eina_stringshare_del(m->mount_point);
600 m->mount_point = NULL;
603 m->unmount_ok(m->data);
607 _e_fm2_device_unmount_fail(E_Fm2_Mount *m)
609 if (m->mounted) return;
610 m->mounted = EINA_TRUE;
612 m->unmount_fail(m->data);
616 e_fm2_device_show_desktop_icons(void)
620 char buf[PATH_MAX] = {0};
621 char buf2[PATH_MAX] = {0};
624 EINA_LIST_FOREACH(_e_vols, l, v)
627 if (!v->storage) continue;
629 id = ecore_file_file_get(v->storage->udi);
631 e_user_dir_snprintf(buf, sizeof(buf),
632 "fileman/favorites/|%s_%d.desktop",
633 id, v->partition_number);
635 e_user_homedir_snprintf(buf2, sizeof(buf2),
637 _("Desktop"), id, v->partition_number);
639 if (ecore_file_exists(buf) && !ecore_file_exists(buf2))
641 ecore_file_symlink(buf, buf2);
642 _e_fm2_file_force_update(buf2);
648 e_fm2_device_hide_desktop_icons(void)
652 char buf[PATH_MAX] = {0};
655 EINA_LIST_FOREACH(_e_vols, l, v)
658 if (!v->storage) continue;
660 id = ecore_file_file_get(v->storage->udi);
662 e_user_homedir_snprintf(buf, sizeof(buf),
664 _("Desktop"), id, v->partition_number);
666 if (ecore_file_exists(buf))
668 ecore_file_unlink(buf);
669 _e_fm2_file_force_update(buf);
675 e_fm2_device_volume_list_get(void)