1 #include "e_fm_device.h"
2 #include "e_fm_shared_codec.h"
3 #include "e_fm_shared_device.h"
5 #define TEBIBYTE_SIZE 1099511627776LL
6 #define GIBIBYTE_SIZE 1073741824
7 #define MEBIBYTE_SIZE 1048576
8 #define KIBIBYTE_SIZE 1024
10 static void _e_fm2_volume_write(E_Volume *v) EINA_ARG_NONNULL(1);
11 static void _e_fm2_volume_erase(E_Volume *v) EINA_ARG_NONNULL(1);
12 static void _e_fm2_device_mount_free(E_Fm2_Mount *m) EINA_ARG_NONNULL(1);
13 static void _e_fm2_device_mount_ok(E_Fm2_Mount *m) EINA_ARG_NONNULL(1);
14 static void _e_fm2_device_mount_fail(E_Fm2_Mount *m) EINA_ARG_NONNULL(1);
15 static void _e_fm2_device_unmount_ok(E_Fm2_Mount *m) EINA_ARG_NONNULL(1);
16 static void _e_fm2_device_unmount_fail(E_Fm2_Mount *m) EINA_ARG_NONNULL(1);
18 static Eina_List *_e_stores = NULL;
19 static Eina_List *_e_vols = NULL;
22 _e_fm2_device_volume_setup(E_Volume *v)
24 char label[1024] = {0};
26 const char *icon = NULL;
27 unsigned long long sz;
29 /* Compute the size in a readable form */
32 if ((sz = (v->size / TEBIBYTE_SIZE)) > 0)
33 snprintf(size, sizeof(size) - 1, _("%llu TiB"), sz);
34 else if ((sz = (v->size / GIBIBYTE_SIZE)) > 0)
35 snprintf(size, sizeof(size) - 1, _("%llu GiB"), sz);
36 else if ((sz = (v->size / MEBIBYTE_SIZE)) > 0)
37 snprintf(size, sizeof(size) - 1, _("%llu MiB"), sz);
38 else if ((sz = (v->size / KIBIBYTE_SIZE)) > 0)
39 snprintf(size, sizeof(size) - 1, _("%llu KiB"), sz);
41 snprintf(size, sizeof(size) - 1, _("%llu B"), v->size);
44 /* Choose the label */
45 if ((v->label) && (v->label[0]))
47 else if ((v->partition_label) && (v->partition_label[0]))
48 snprintf(label, sizeof(label) - 1, "%s", v->partition_label);
49 else if (((v->storage->vendor) && (v->storage->vendor[0])) &&
50 ((v->storage->model) && (v->storage->model[0])))
53 snprintf(label, sizeof(label) - 1, "%s %s - %s", v->storage->vendor, v->storage->model, size);
55 snprintf(label, sizeof(label) - 1, "%s %s", v->storage->vendor, v->storage->model);
57 else if ((v->storage->model) && (v->storage->model[0]))
60 snprintf(label, sizeof(label) - 1, "%s - %s", v->storage->model, size);
62 snprintf(label, sizeof(label) - 1, "%s", v->storage->model);
64 else if ((v->storage->vendor) && (v->storage->vendor[0]))
67 snprintf(label, sizeof(label) - 1, "%s - %s", v->storage->vendor, size);
69 snprintf(label, sizeof(label) - 1, "%s", v->storage->vendor);
71 else if (v->storage->drive_type && (!strcmp(v->storage->drive_type, "sd_mmc")))
72 snprintf(label, sizeof(label) - 1, "Flash Card - %s", size);
74 snprintf(label, sizeof(label), _("Unknown Volume"));
76 if (label[0]) eina_stringshare_replace(&v->label, label);
79 /* http://standards.freedesktop.org/icon-naming-spec/icon-naming-spec-latest.html */
80 if (v->storage->icon.volume)
81 icon = v->storage->icon.volume;
84 if ((!v->storage->drive_type) || (!strcmp(v->storage->drive_type, "disk")) || (!strcmp(v->storage->drive_type, "partition")))
86 if (v->storage->removable == 0)
87 icon = "drive-harddisk";
89 icon = "drive-removable-media";
91 else if ((!strcmp(v->storage->drive_type, "cdrom")) || (!strncmp(v->storage->drive_type, "optical", 7)))
92 icon = "drive-optical";
93 else if (!strncmp(v->storage->drive_type, "floppy", 6))
94 icon = "media-floppy";
95 else if (!strcmp(v->storage->drive_type, "tape"))
97 else if (!strcmp(v->storage->drive_type, "compact_flash")
98 || !strcmp(v->storage->drive_type, "memory_stick")
99 || !strcmp(v->storage->drive_type, "smart_media")
100 || !strcmp(v->storage->drive_type, "sd_mmc")
101 || !strncmp(v->storage->drive_type, "flash", 5))
102 icon = "media-flash";
104 if (icon) eina_stringshare_replace(&v->icon, icon);
106 if ((!v->mount_point) ||
107 (strcmp(v->mount_point, "/") &&
108 strcmp(v->mount_point, "/home") &&
109 strcmp(v->mount_point, "/tmp")))
110 _e_fm2_volume_write(v);
114 e_fm2_device_storage_add(E_Storage *s)
119 if (e_fm2_device_storage_find(s->udi)) return;
121 s->validated = EINA_TRUE;
122 _e_stores = eina_list_append(_e_stores, s);
132 " media_available: %i\n"
133 " media_size: %lli\n"
134 " requires_eject: %i\n"
135 " hotpluggable: %i\n"
136 " media_check_enabled: %i\n"
138 " icon.volume: %s\n\n"
151 s->media_check_enabled,
155 if ((s->removable == 0) &&
156 (s->media_available == 0) &&
157 (s->media_size == 0) &&
158 (s->requires_eject == 0) &&
159 (s->hotpluggable == 0) &&
160 (s->media_check_enabled == 0))
162 // printf(" Ignore this storage\n");
166 s->trackable = EINA_TRUE;
169 EINA_LIST_FOREACH(_e_vols, l, v) /* catch volumes which were added before their storage */
171 if ((!v->storage) && (s->udi == v->parent))
174 _e_fm2_device_volume_setup(v);
180 e_fm2_device_storage_del(E_Storage *s)
182 // printf("STO- %s\n", s->udi);
183 _e_stores = eina_list_remove(_e_stores, s);
184 _e_fm_shared_device_storage_free(s);
188 e_fm2_device_storage_find(const char *udi)
193 if (!udi) return NULL;
194 EINA_LIST_FOREACH(_e_stores, l, s)
196 if (!strcmp(udi, s->udi)) return s;
203 e_fm2_device_volume_add(E_Volume *v)
207 if (e_fm2_device_volume_find(v->udi)) return;
209 v->validated = EINA_TRUE;
210 _e_vols = eina_list_append(_e_vols, v);
219 " partition_number: %d\n"
220 " partition_label: %s\n"
232 v->partition ? v->partition_label : "(not a partition)",
237 /* Check mount point */
238 if ((v->efm_mode == EFM_MODE_USING_HAL_MOUNT) &&
239 ((!v->mount_point) || (!v->mount_point[0])))
241 if (v->mount_point) eina_stringshare_del(v->mount_point);
242 v->mount_point = NULL;
243 v->mount_point = e_fm2_device_volume_mountpoint_get(v);
244 if ((!v->mount_point) || (!v->mount_point[0]))
249 if (v->mount_point) eina_stringshare_del(v->mount_point);
250 v->mount_point = NULL;
252 if ((v->uuid) && (v->uuid[0])) id = v->uuid;
253 if (ecore_file_is_dir("/media"))
254 snprintf(buf, sizeof(buf), "/media/%s", id);
255 else if (ecore_file_is_dir("/mnt"))
256 snprintf(buf, sizeof(buf), "/mnt/%s", id);
257 else if (ecore_file_is_dir("/tmp"))
258 snprintf(buf, sizeof(buf), "/tmp/%s", id);
261 v->mount_point = eina_stringshare_add(buf);
265 /* Search parent storage */
266 if ((s = e_fm2_device_storage_find(v->parent)))
269 s->volumes = eina_list_append(s->volumes, v);
272 if (v->storage) _e_fm2_device_volume_setup(v);
277 e_fm2_device_volume_del(E_Volume *v)
281 // printf("VOL- %s\n", v->udi);
282 _e_vols = eina_list_remove(_e_vols, v);
283 _e_fm2_volume_erase(v);
286 v->storage->volumes = eina_list_remove(v->storage->volumes, v);
289 EINA_LIST_FREE(v->mounts, m)
291 _e_fm2_device_unmount_ok(m);
292 _e_fm2_device_mount_free(m);
294 _e_fm_shared_device_volume_free(v);
298 _e_fm2_volume_write(E_Volume *v)
300 char buf[PATH_MAX], buf2[PATH_MAX];
304 if (!v->storage) return;
305 id = ecore_file_file_get(v->storage->udi);
306 // printf("vol write %s\n", id);
307 e_user_dir_snprintf(buf, sizeof(buf), "fileman/favorites/|%s_%d.desktop",
308 id, v->partition_number);
317 "X-Enlightenment-Type=Removable\n"
318 "X-Enlightenment-Removable-State=Full\n"
326 _("Removable Device"),
330 if (e_config->device_desktop)
332 e_user_homedir_snprintf(buf2, sizeof(buf2),
334 _("Desktop"), id, v->partition_number);
335 ecore_file_symlink(buf, buf2);
338 /* FIXME: manipulate icon directly */
339 _e_fm2_file_force_update(buf);
340 //_e_fm2_file_force_update(buf2);
350 _e_fm2_volume_erase(E_Volume *v)
352 char buf[PATH_MAX] = {0};
355 if (!v->storage) return;
356 id = ecore_file_file_get(v->storage->udi);
357 e_user_homedir_snprintf(buf, sizeof(buf), "%s/|%s_%d.desktop",
358 _("Desktop"), id, v->partition_number);
359 ecore_file_unlink(buf);
360 _e_fm2_file_force_update(buf);
362 if (e_config->device_desktop)
364 e_user_dir_snprintf(buf, sizeof(buf),
365 "fileman/favorites/|%s_%d.desktop",
366 id, v->partition_number);
367 ecore_file_unlink(buf);
368 _e_fm2_file_force_update(buf);
373 e_fm2_device_volume_find(const char *udi)
378 if (!udi) return NULL;
380 EINA_LIST_FOREACH(_e_vols, l, v)
382 if (!v->udi) continue;
383 if (!strcmp(udi, v->udi)) return v;
390 e_fm2_device_volume_mountpoint_get(E_Volume *v)
392 char buf[PATH_MAX] = {0};
397 // printf("GET MOUNTPOINT = %s\n", v->mount_point);
398 return eina_stringshare_add(v->mount_point);
400 else if (v->efm_mode != EFM_MODE_USING_HAL_MOUNT)
403 if (v->label && v->label[0] != '\0')
404 snprintf(buf, sizeof(buf) - 1, "/media/%s", v->label);
405 else if (v->uuid && v->uuid[0] != '\0')
406 snprintf(buf, sizeof(buf) - 1, "/media/%s", v->uuid);
407 else if ((v->storage) && (v->storage->serial) && v->storage->serial[0] != '\0')
408 snprintf(buf, sizeof(buf) - 1, "/media/%s", v->storage->serial);
411 static int mount_count = 1;
412 snprintf(buf, sizeof(buf) - 1, "/media/unknown-%i", mount_count++);
414 // printf("GET MOUNTPOINT = %s\n", buf);
415 return eina_stringshare_add(buf);
419 e_fm2_device_mount_add(E_Volume *v,
420 const char *mountpoint)
425 v->mounted = EINA_TRUE;
426 if (mountpoint && (mountpoint[0]))
427 eina_stringshare_replace(&v->mount_point, mountpoint);
429 EINA_LIST_FOREACH(v->mounts, l, m)
430 _e_fm2_device_mount_ok(m);
432 // printf("MOUNT %s %s\n", v->udi, v->mount_point);
436 e_fm2_device_mount_del(E_Volume *v)
440 v->mounted = EINA_FALSE;
443 eina_stringshare_del(v->mount_point);
444 v->mount_point = NULL;
447 EINA_LIST_FREE(v->mounts, m)
449 _e_fm2_device_unmount_ok(m);
450 _e_fm2_device_mount_free(m);
455 _e_fm2_device_mount_free(E_Fm2_Mount *m)
459 if (m->udi) eina_stringshare_del(m->udi);
460 if (m->mount_point) eina_stringshare_del(m->mount_point);
466 e_fm2_device_mount_find(const char *path)
471 EINA_LIST_FOREACH(_e_vols, l, v)
475 && !strncmp(path, v->mount_point, strlen(v->mount_point))
477 return eina_list_data_get(v->mounts);
483 e_fm2_device_mount(E_Volume *v,
487 Ecore_Cb unmount_fail,
494 m = calloc(1, sizeof(E_Fm2_Mount));
496 m->udi = eina_stringshare_add(v->udi);
497 m->mount_ok = mount_ok;
498 m->mount_fail = mount_fail;
499 m->unmount_ok = unmount_ok;
500 m->unmount_fail = unmount_fail;
503 m->mounted = v->mounted;
505 v->mounts = eina_list_prepend(v->mounts, m);
507 // printf("BEGIN MOUNT %p '%s'\n", m, v->mount_point);
511 v->auto_unmount = EINA_TRUE;
512 _e_fm2_client_mount(v->udi, v->mount_point);
516 v->auto_unmount = EINA_FALSE;
517 m->mount_point = eina_stringshare_add(v->mount_point);
524 e_fm2_device_mount_fail(E_Volume *v)
528 v->mounted = EINA_FALSE;
531 eina_stringshare_del(v->mount_point);
532 v->mount_point = NULL;
535 EINA_LIST_FREE(v->mounts, m)
537 _e_fm2_device_mount_fail(m);
538 _e_fm2_device_mount_free(m);
543 e_fm2_device_unmount(E_Fm2_Mount *m)
547 if (!(v = m->volume)) return;
548 v->mounts = eina_list_remove(v->mounts, m);
549 _e_fm2_device_mount_free(m);
551 if (v->auto_unmount && v->mounted && !eina_list_count(v->mounts))
552 _e_fm2_client_unmount(v->udi);
556 e_fm2_device_unmount_fail(E_Volume *v)
561 v->mounted = EINA_TRUE;
563 EINA_LIST_FOREACH(v->mounts, l, m)
564 _e_fm2_device_unmount_fail(m);
568 _e_fm2_device_mount_ok(E_Fm2_Mount *m)
570 if (m->mounted) return;
571 m->mounted = EINA_TRUE;
573 m->mount_point = eina_stringshare_add(m->volume->mount_point);
575 m->mount_ok(m->data);
576 // printf("MOUNT OK '%s'\n", m->mount_point);
580 _e_fm2_device_mount_fail(E_Fm2_Mount *m)
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)