|
|
|
#ifdef HAVE_CONFIG_H
|
|
|
|
#include "config.h"
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef HAVE_ALLOCA_H
|
|
|
|
# include <alloca.h>
|
|
|
|
#elif defined __GNUC__
|
|
|
|
# define alloca __builtin_alloca
|
|
|
|
#elif defined _AIX
|
|
|
|
# define alloca __alloca
|
|
|
|
#elif defined _MSC_VER
|
|
|
|
# include <malloc.h>
|
|
|
|
# define alloca _alloca
|
|
|
|
#else
|
|
|
|
# include <stddef.h>
|
|
|
|
# ifdef __cplusplus
|
|
|
|
extern "C"
|
|
|
|
# endif
|
|
|
|
void *alloca(size_t);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef __linux__
|
|
|
|
#include <features.h>
|
|
|
|
#endif
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <sys/types.h>
|
|
|
|
#include <sys/stat.h>
|
|
|
|
#include <sys/time.h>
|
|
|
|
#include <sys/param.h>
|
|
|
|
#include <utime.h>
|
|
|
|
#include <math.h>
|
|
|
|
#include <fnmatch.h>
|
|
|
|
#include <limits.h>
|
|
|
|
#include <ctype.h>
|
|
|
|
#include <time.h>
|
|
|
|
#include <dirent.h>
|
|
|
|
#include <pwd.h>
|
|
|
|
#include <glob.h>
|
|
|
|
#include <errno.h>
|
|
|
|
#include <signal.h>
|
|
|
|
#include <Ecore.h>
|
|
|
|
#include <Ecore_Ipc.h>
|
|
|
|
#include <Ecore_File.h>
|
|
|
|
#include <Eet.h>
|
|
|
|
#include <Eldbus.h>
|
|
|
|
|
|
|
|
#include "e_fm_shared_device.h"
|
|
|
|
#include "e_fm_shared_codec.h"
|
|
|
|
#include "e_fm_ipc.h"
|
|
|
|
#include "e_fm_device.h"
|
|
|
|
|
|
|
|
#include "e_fm_main_udisks2.h"
|
|
|
|
#include "e_fm_main.h"
|
|
|
|
|
|
|
|
#define UDISKS2_BUS "org.freedesktop.UDisks2"
|
|
|
|
#define UDISKS2_PATH "/org/freedesktop/UDisks2"
|
|
|
|
#define UDISKS2_INTERFACE "org.freedesktop.UDisks2"
|
|
|
|
#define UDISKS2_INTERFACE_BLOCK "org.freedesktop.UDisks2.Block"
|
|
|
|
#define UDISKS2_INTERFACE_DRIVE "org.freedesktop.UDisks2.Drive"
|
|
|
|
#define UDISKS2_INTERFACE_FILESYSTEM "org.freedesktop.UDisks2.Filesystem"
|
|
|
|
|
|
|
|
typedef struct U2_Block
|
|
|
|
{
|
|
|
|
size_t Size;
|
|
|
|
Eina_Stringshare *Device;
|
|
|
|
Eina_Stringshare *parent;
|
|
|
|
Eina_Bool volume;
|
|
|
|
Eina_Stringshare *IdType;
|
|
|
|
Eina_Stringshare *IdLabel;
|
|
|
|
Eina_Stringshare *IdUUID;
|
|
|
|
Eina_Bool HintIgnore;
|
|
|
|
Eina_Bool HintSystem;
|
|
|
|
Eina_Stringshare *HintName;
|
|
|
|
Eina_Stringshare *HintIconName;
|
|
|
|
} U2_Block;
|
|
|
|
|
|
|
|
static Eldbus_Connection *_e_fm_main_udisks2_conn = NULL;
|
|
|
|
static Eldbus_Proxy *_e_fm_main_udisks2_proxy = NULL;
|
|
|
|
static Eina_List *_e_stores = NULL;
|
|
|
|
static Eina_List *_e_vols = NULL;
|
|
|
|
|
|
|
|
static void _e_fm_main_udisks2_cb_dev_all(void *data, const Eldbus_Message *msg,
|
|
|
|
Eldbus_Pending *pending);
|
|
|
|
static void _e_fm_main_udisks2_cb_dev_add(void *data, const Eldbus_Message *msg);
|
|
|
|
static void _e_fm_main_udisks2_cb_dev_del(void *data, const Eldbus_Message *msg);
|
|
|
|
static void _e_fm_main_udisks2_cb_vol_mounted(E_Volume *v);
|
|
|
|
static void _e_fm_main_udisks2_cb_vol_unmounted(E_Volume *v);
|
|
|
|
|
|
|
|
static void _e_fm_main_udisks2_cb_vol_ejected(E_Volume *v);
|
|
|
|
static int _e_fm_main_udisks2_format_error_msg(char **buf,
|
|
|
|
E_Volume *v,
|
|
|
|
const char *name,
|
|
|
|
const char *message);
|
|
|
|
static void _e_fm_main_udisks2_cb_storage_prop_modified(void *data, const Eldbus_Message *msg, Eldbus_Pending *p);
|
|
|
|
static void _e_fm_main_udisks2_volume_mounts_update(E_Volume *v, Eldbus_Message_Iter *arr3, Eina_Bool first);
|
|
|
|
static Eina_Bool _e_fm_main_udisks2_vol_mount_timeout(E_Volume *v);
|
|
|
|
static Eina_Bool _e_fm_main_udisks2_vol_unmount_timeout(E_Volume *v);
|
|
|
|
static Eina_Bool _e_fm_main_udisks2_vol_eject_timeout(E_Volume *v);
|
|
|
|
static E_Storage *_storage_find_by_dbus_path(const char *path);
|
|
|
|
static E_Volume *_volume_find_by_dbus_path(const char *path);
|
|
|
|
static void _volume_del(E_Volume *v);
|
|
|
|
static Eina_Bool _storage_del(void *data);
|
|
|
|
static void _e_fm_main_udisks2_cb_storage_prop_modified_cb(void *data, const Eldbus_Message *msg);
|
|
|
|
static E_Storage * _e_fm_main_udisks2_storage_drive_add(const char *udi, E_Storage *s, Eldbus_Message_Iter *arr3);
|
|
|
|
|
|
|
|
static Eina_List *vols_ejecting = NULL;
|
|
|
|
|
|
|
|
static Eina_List *stores_registered = NULL;
|
|
|
|
|
|
|
|
static Eina_Stringshare *
|
|
|
|
_util_fuckyouglib_convert(Eldbus_Message_Iter *fuckyouglib)
|
|
|
|
{
|
|
|
|
Eldbus_Message_Iter *no_really;
|
|
|
|
unsigned char c, buf[PATH_MAX] = {0};
|
|
|
|
unsigned int x = 0;
|
|
|
|
|
|
|
|
if (!eldbus_message_iter_arguments_get(fuckyouglib, "ay", &no_really)) return NULL;
|
|
|
|
while (eldbus_message_iter_get_and_next(no_really, 'y', &c))
|
|
|
|
{
|
|
|
|
buf[x] = c;
|
|
|
|
x++;
|
|
|
|
}
|
|
|
|
if (!buf[0]) return NULL;
|
|
|
|
return eina_stringshare_add((char*)buf);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_e_fm_main_udisks2_name_start(void *data __UNUSED__, const Eldbus_Message *msg,
|
|
|
|
Eldbus_Pending *pending __UNUSED__)
|
|
|
|
{
|
|
|
|
unsigned flag = 0;
|
|
|
|
Eldbus_Object *obj;
|
|
|
|
|
|
|
|
if (!eldbus_message_arguments_get(msg, "u", &flag) || !flag)
|
|
|
|
{
|
|
|
|
_e_fm_main_udisks2_catch(EINA_FALSE);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
obj = eldbus_object_get(_e_fm_main_udisks2_conn, UDISKS2_BUS, UDISKS2_PATH);
|
|
|
|
eldbus_object_managed_objects_get(obj, _e_fm_main_udisks2_cb_dev_all, NULL);
|
|
|
|
|
|
|
|
_e_fm_main_udisks2_proxy = eldbus_proxy_get(obj, ELDBUS_FDO_INTERFACE_OBJECT_MANAGER);
|
|
|
|
eldbus_proxy_signal_handler_add(_e_fm_main_udisks2_proxy, "InterfacesAdded",
|
|
|
|
_e_fm_main_udisks2_cb_dev_add, NULL);
|
|
|
|
eldbus_proxy_signal_handler_add(_e_fm_main_udisks2_proxy, "InterfacesRemoved",
|
|
|
|
_e_fm_main_udisks2_cb_dev_del, NULL);
|
|
|
|
//eldbus_signal_handler_add(_e_fm_main_udisks2_conn, NULL,
|
|
|
|
//NULL, ELDBUS_FDO_INTERFACE_PROPERTIES, "PropertiesChanged",
|
|
|
|
//_e_fm_main_udisks2_cb_dev_add, NULL);
|
|
|
|
_e_fm_main_udisks2_catch(EINA_TRUE); /* signal usage of udisks2 for mounting */
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_e_fm_main_udisks2_block_clear(U2_Block *u2)
|
|
|
|
{
|
|
|
|
eina_stringshare_del(u2->Device);
|
|
|
|
eina_stringshare_del(u2->parent);
|
|
|
|
eina_stringshare_del(u2->IdType);
|
|
|
|
eina_stringshare_del(u2->IdLabel);
|
|
|
|
eina_stringshare_del(u2->IdUUID);
|
|
|
|
eina_stringshare_del(u2->HintIconName);
|
|
|
|
eina_stringshare_del(u2->HintName);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_e_fm_main_udisks2_storage_block_add(E_Storage *s, U2_Block *u2)
|
|
|
|
{
|
|
|
|
s->media_size = u2->Size;
|
|
|
|
eina_stringshare_replace(&s->icon.drive, u2->HintIconName);
|
|
|
|
s->system_internal = u2->HintIgnore;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_e_fm_main_udisks2_volume_block_add(E_Volume *v, U2_Block *u2)
|
|
|
|
{
|
|
|
|
v->validated = u2->volume && u2->Device && u2->parent && (!u2->HintSystem);
|
|
|
|
if (!v->validated) return;
|
|
|
|
v->size = u2->Size;
|
|
|
|
eina_stringshare_replace(&v->udi, u2->Device);
|
|
|
|
eina_stringshare_replace(&v->parent, u2->parent);
|
|
|
|
eina_stringshare_replace(&v->icon, u2->HintIconName);
|
|
|
|
eina_stringshare_replace(&v->uuid, u2->IdUUID);
|
|
|
|
eina_stringshare_replace(&v->fstype, u2->IdType);
|
|
|
|
eina_stringshare_replace(&v->label, u2->IdLabel);
|
|
|
|
if (!v->label) v->label = eina_stringshare_ref(u2->HintName);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_e_fm_main_udisks2_storage_add_send(E_Storage *s)
|
|
|
|
{
|
|
|
|
void *msg_data;
|
|
|
|
int msg_size;
|
|
|
|
|
|
|
|
if (!s->validated) return;
|
|
|
|
if (eina_list_data_find(stores_registered, s)) return;
|
|
|
|
if ((!s->removable) && (!s->hotpluggable) && (!s->requires_eject))
|
|
|
|
{
|
|
|
|
DBG("removing likely internal storage %s", s->dbus_path);
|
|
|
|
s->validated = 0;
|
|
|
|
ecore_idler_add(_storage_del, s->dbus_path);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
stores_registered = eina_list_append(stores_registered, s);
|
|
|
|
msg_data = _e_fm_shared_codec_storage_encode(s, &msg_size);
|
|
|
|
if (msg_data)
|
|
|
|
{
|
|
|
|
ecore_ipc_server_send(_e_fm_ipc_server,
|
|
|
|
6 /*E_IPC_DOMAIN_FM*/,
|
|
|
|
E_FM_OP_STORAGE_ADD,
|
|
|
|
0, 0, 0, msg_data, msg_size);
|
|
|
|
free(msg_data);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
_e_fm_main_udisks2_block_handle(Eldbus_Message_Iter *arr3, U2_Block *u2)
|
|
|
|
{
|
|
|
|
Eldbus_Message_Iter *dict3;
|
|
|
|
int block = 0;
|
|
|
|
|
|
|
|
while (eldbus_message_iter_get_and_next(arr3, 'e', &dict3))
|
|
|
|
{
|
|
|
|
Eldbus_Message_Iter *var;
|
|
|
|
char *key2, *val, *type;
|
|
|
|
uint64_t u;
|
|
|
|
Eina_Bool b;
|
|
|
|
|
|
|
|
if (!eldbus_message_iter_arguments_get(dict3, "sv", &key2, &var))
|
|
|
|
continue;
|
|
|
|
|
|
|
|
type = eldbus_message_iter_signature_get(var);
|
|
|
|
switch (type[0])
|
|
|
|
{
|
|
|
|
case 's':
|
|
|
|
case 'o':
|
|
|
|
eldbus_message_iter_arguments_get(var, type, &val);
|
|
|
|
if ((!val) || (!val[0])) continue;
|
|
|
|
break;
|
|
|
|
case 't':
|
|
|
|
eldbus_message_iter_arguments_get(var, type, &u);
|
|
|
|
break;
|
|
|
|
case 'b':
|
|
|
|
eldbus_message_iter_arguments_get(var, type, &b);
|
|
|
|
break;
|
|
|
|
default: break;
|
|
|
|
}
|
|
|
|
if (!strcmp(key2, "Device"))
|
|
|
|
{
|
|
|
|
u2->Device = _util_fuckyouglib_convert(var);
|
|
|
|
if (!strncmp(u2->Device, "/dev/ram", 8)) return -1;
|
|
|
|
}
|
|
|
|
else if (!strcmp(key2, "Size"))
|
|
|
|
u2->Size = u;
|
|
|
|
else if (!strcmp(key2, "Drive"))
|
|
|
|
u2->parent = eina_stringshare_add(val);
|
|
|
|
else if (!strcmp(key2, "IdUsage"))
|
|
|
|
{
|
|
|
|
if (!strcmp(val, "other")) return -1;
|
|
|
|
u2->volume = !strcmp(val, "filesystem");
|
|
|
|
}
|
|
|
|
else if (!strcmp(key2, "IdType"))
|
|
|
|
u2->IdType = eina_stringshare_add(val);
|
|
|
|
else if (!strcmp(key2, "IdLabel"))
|
|
|
|
u2->IdLabel = eina_stringshare_add(val);
|
|
|
|
else if (!strcmp(key2, "IdUUID"))
|
|
|
|
u2->IdUUID = eina_stringshare_add(val);
|
|
|
|
else if (!strcmp(key2, "HintIgnore"))
|
|
|
|
u2->HintIgnore = !!b;
|
|
|
|
else if (!strcmp(key2, "HintSystem"))
|
|
|
|
u2->HintSystem = !!b;
|
|
|
|
else if (!strcmp(key2, "HintName"))
|
|
|
|
u2->HintName = eina_stringshare_add(val);
|
|
|
|
else if (!strcmp(key2, "HintIconName"))
|
|
|
|
u2->HintIconName = eina_stringshare_add(val);
|
|
|
|
block = 1;
|
|
|
|
}
|
|
|
|
return block;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_e_fm_main_udisks2_handle_device(Eldbus_Message_Iter *dict)
|
|
|
|
{
|
|
|
|
const char *udi;
|
|
|
|
Eldbus_Message_Iter *arr2, *dict2;
|
|
|
|
E_Volume *v = NULL;
|
|
|
|
E_Storage *s = NULL;
|
|
|
|
U2_Block u2;
|
|
|
|
int block = 0;
|
|
|
|
unsigned int pnum = UINT_MAX;
|
|
|
|
Eina_Stringshare *pname = NULL;
|
|
|
|
|
|
|
|
if (!eldbus_message_iter_arguments_get(dict, "oa{sa{sv}}", &udi, &arr2))
|
|
|
|
return;
|
|
|
|
memset(&u2, 0, sizeof(U2_Block));
|
|
|
|
while (eldbus_message_iter_get_and_next(arr2, 'e', &dict2))
|
|
|
|
{
|
|
|
|
Eldbus_Message_Iter *arr3, *dict3;
|
|
|
|
char *interface;
|
|
|
|
|
|
|
|
if (!eldbus_message_iter_arguments_get(dict2, "sa{sv}", &interface, &arr3))
|
|
|
|
continue;
|
|
|
|
interface += sizeof(UDISKS2_INTERFACE);
|
|
|
|
if (!strcmp(interface, "Partition"))
|
|
|
|
{
|
|
|
|
while (eldbus_message_iter_get_and_next(arr3, 'e', &dict3))
|
|
|
|
{
|
|
|
|
Eldbus_Message_Iter *var;
|
|
|
|
char *key2, *val, *type;
|
|
|
|
|
|
|
|
if (!eldbus_message_iter_arguments_get(dict3, "sv", &key2, &var))
|
|
|
|
continue;
|
|
|
|
|
|
|
|
type = eldbus_message_iter_signature_get(var);
|
|
|
|
switch (type[0])
|
|
|
|
{
|
|
|
|
case 's':
|
|
|
|
if (strcmp(key2, "Name")) continue;
|
|
|
|
if (!eldbus_message_iter_arguments_get(var, type, &val)) continue;
|
|
|
|
if (val && val[0]) pname = eina_stringshare_add(val);
|
|
|
|
break;
|
|
|
|
case 'u':
|
|
|
|
if (strcmp(key2, "Number")) continue;
|
|
|
|
eldbus_message_iter_arguments_get(var, type, &pnum);
|
|
|
|
break;
|
|
|
|
default: break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (v)
|
|
|
|
{
|
|
|
|
v->partition_label = pname;
|
|
|
|
pname = NULL;
|
|
|
|
v->partition_number = pnum;
|
|
|
|
v->partition = (v->partition_label || (pnum != UINT_MAX));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (!strcmp(interface, "Filesystem"))
|
|
|
|
{
|
|
|
|
if (!v) v = _volume_find_by_dbus_path(udi);
|
|
|
|
if (!v) v = _e_fm_main_udisks2_volume_add(udi, EINA_TRUE);
|
|
|
|
_e_fm_main_udisks2_volume_mounts_update(v, arr3, 1);
|
|
|
|
v->partition_label = pname;
|
|
|
|
pname = NULL;
|
|
|
|
if (pnum != UINT_MAX)
|
|
|
|
{
|
|
|
|
v->partition_number = pnum;
|
|
|
|
v->partition = 1;
|
|
|
|
}
|
|
|
|
if (block)
|
|
|
|
{
|
|
|
|
_e_fm_main_udisks2_volume_block_add(v, &u2);
|
|
|
|
if (!v->validated) E_FREE_FUNC(v, _volume_del);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (!strcmp(interface, "Block"))
|
|
|
|
{
|
|
|
|
block = _e_fm_main_udisks2_block_handle(arr3, &u2);
|
|
|
|
switch (block)
|
|
|
|
{
|
|
|
|
case -1: goto out;
|
|
|
|
case 0: continue;
|
|
|
|
default: break;
|
|
|
|
}
|
|
|
|
if ((!s) && (!v))
|
|
|
|
{
|
|
|
|
v = _volume_find_by_dbus_path(udi);
|
|
|
|
s = _e_fm_main_udisks2_storage_find(u2.parent);
|
|
|
|
}
|
|
|
|
if (s)
|
|
|
|
_e_fm_main_udisks2_storage_block_add(s, &u2);
|
|
|
|
if (v)
|
|
|
|
{
|
|
|
|
_e_fm_main_udisks2_volume_block_add(v, &u2);
|
|
|
|
if (!v->validated) E_FREE_FUNC(v, _volume_del);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (!strcmp(interface, "Drive"))
|
|
|
|
{
|
|
|
|
s = _e_fm_main_udisks2_storage_drive_add(udi, s, arr3);
|
|
|
|
if (block) _e_fm_main_udisks2_storage_block_add(s, &u2);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
out:
|
|
|
|
_e_fm_main_udisks2_block_clear(&u2);
|
|
|
|
eina_stringshare_del(pname);
|
|
|
|
if (v && v->validated) e_fm_ipc_volume_add(v);
|
|
|
|
if (s)
|
|
|
|
{
|
|
|
|
Eina_List *l;
|
|
|
|
|
|
|
|
if (!block) //cdrom :/
|
|
|
|
s->udi = eina_stringshare_add(udi);
|
|
|
|
EINA_LIST_FOREACH(_e_vols, l, v)
|
|
|
|
{
|
|
|
|
if ((v->parent == s->udi) || (v->parent == s->dbus_path))
|
|
|
|
{
|
|
|
|
if (!v->storage)
|
|
|
|
{
|
|
|
|
v->storage = s;
|
|
|
|
s->volumes = eina_list_append(s->volumes, v);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
_e_fm_main_udisks2_storage_add_send(s);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_e_fm_main_udisks2_cb_dev_all(void *data __UNUSED__, const Eldbus_Message *msg,
|
|
|
|
Eldbus_Pending *pending __UNUSED__)
|
|
|
|
{
|
|
|
|
const char *name, *txt;
|
|
|
|
Eldbus_Message_Iter *arr1, *dict1;
|
|
|
|
|
|
|
|
if (eldbus_message_error_get(msg, &name, &txt))
|
|
|
|
{
|
|
|
|
ERR("Error %s %s.", name, txt);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!eldbus_message_arguments_get(msg, "a{oa{sa{sv}}}", &arr1))
|
|
|
|
{
|
|
|
|
ERR("Error getting arguments.");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
while (eldbus_message_iter_get_and_next(arr1, 'e', &dict1))
|
|
|
|
_e_fm_main_udisks2_handle_device(dict1);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_e_fm_main_udisks2_cb_vol_props(void *data, const Eldbus_Message *msg, Eldbus_Pending *p EINA_UNUSED)
|
|
|
|
{
|
|
|
|
U2_Block u2;
|
|
|
|
int block;
|
|
|
|
E_Volume *v = data;
|
|
|
|
Eldbus_Message_Iter *arr;
|
|
|
|
|
|
|
|
memset(&u2, 0, sizeof(U2_Block));
|
|
|
|
if (!eldbus_message_arguments_get(msg, "a{sv}", &arr))
|
|
|
|
{
|
|
|
|
ERR("WTF");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
block = _e_fm_main_udisks2_block_handle(arr, &u2);
|
|
|
|
if (block == 1)
|
|
|
|
{
|
|
|
|
Eina_Bool valid = v->validated;
|
|
|
|
|
|
|
|
_e_fm_main_udisks2_volume_block_add(v, &u2);
|
|
|
|
if (v->validated && (valid != v->validated))
|
|
|
|
e_fm_ipc_volume_add(v);
|
|
|
|
else if (!v->validated)
|
|
|
|
_volume_del(v);
|
|
|
|
}
|
|
|
|
_e_fm_main_udisks2_block_clear(&u2);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_e_fm_main_udisks2_cb_dev_add(void *data __UNUSED__, const Eldbus_Message *msg)
|
|
|
|
{
|
|
|
|
const char *interface;
|
|
|
|
|
|
|
|
interface = eldbus_message_interface_get(msg);
|
|
|
|
//path = eldbus_message_path_get(msg);
|
|
|
|
//if (!strncmp(path, "/org/freedesktop/UDisks2/drives", sizeof("/org/freedesktop/UDisks2/drives") - 1))
|
|
|
|
//{
|
|
|
|
//E_Storage *s;
|
|
|
|
//
|
|
|
|
//if (!eldbus_message_arguments_get(msg, "sa{sv}as", &interface, &arr, &arr2))
|
|
|
|
//return;
|
|
|
|
//interface += sizeof(UDISKS2_INTERFACE);
|
|
|
|
//if (strcmp(interface, "Drive")) return;
|
|
|
|
//s = _storage_find_by_dbus_path(path);
|
|
|
|
//if (!s) return;
|
|
|
|
//valid = s->validated;
|
|
|
|
//_e_fm_main_udisks2_storage_drive_add(s->udi, s, arr);
|
|
|
|
//if (valid != s->validated)
|
|
|
|
//_e_fm_main_udisks2_storage_add_send(s);
|
|
|
|
//}
|
|
|
|
//else if (!strncmp(path, "/org/freedesktop/UDisks2/block_devices", sizeof("/org/freedesktop/UDisks2/block_devices") - 1))
|
|
|
|
//{
|
|
|
|
//E_Volume *v;
|
|
|
|
//
|
|
|
|
//if (!eldbus_message_arguments_get(msg, "sa{sv}as", &interface, &arr, &arr2))
|
|
|
|
//return;
|
|
|
|
//v = _volume_find_by_dbus_path(path);
|
|
|
|
//if (!v) v = _e_fm_main_udisks2_volume_add(path, 1);
|
|
|
|
//
|
|
|
|
//interface += sizeof(UDISKS2_INTERFACE);
|
|
|
|
//if (!strcmp(interface, "Filesystem"))
|
|
|
|
//_e_fm_main_udisks2_volume_mounts_update(v, arr, 0);
|
|
|
|
//else if (!strcmp(interface, "Block"))
|
|
|
|
//{
|
|
|
|
//U2_Block u2;
|
|
|
|
//int block;
|
|
|
|
//
|
|
|
|
//memset(&u2, 0, sizeof(U2_Block));
|
|
|
|
//block = _e_fm_main_udisks2_block_handle(arr, &u2);
|
|
|
|
//if (block == 1)
|
|
|
|
//{
|
|
|
|
//valid = v->validated;
|
|
|
|
//
|
|
|
|
//_e_fm_main_udisks2_volume_block_add(v, &u2);
|
|
|
|
//if (v->validated && (valid != v->validated))
|
|
|
|
//e_fm_ipc_volume_add(v);
|
|
|
|
//else if (!v->validated)
|
|
|
|
//_volume_del(v);
|
|
|
|
//}
|
|
|
|
//_e_fm_main_udisks2_block_clear(&u2);
|
|
|
|
//}
|
|
|
|
//}
|
|
|
|
//else
|
|
|
|
E_Storage *s = eina_list_last_data_get(_e_stores);
|
|
|
|
E_Volume *v = eina_list_last_data_get(_e_vols);
|
|
|
|
if (!strcmp(interface, ELDBUS_FDO_INTERFACE_OBJECT_MANAGER))
|
|
|
|
_e_fm_main_udisks2_handle_device(eldbus_message_iter_get(msg));
|
|
|
|
if (_e_stores && (s != eina_list_last_data_get(_e_stores)))
|
|
|
|
{
|
|
|
|
s = eina_list_last_data_get(_e_stores);
|
|
|
|
if (s->proxy)
|
|
|
|
eldbus_proxy_property_get_all(s->proxy, _e_fm_main_udisks2_cb_storage_prop_modified, s);
|
|
|
|
}
|
|
|
|
if (_e_vols && (v != eina_list_last_data_get(_e_vols)))
|
|
|
|
{
|
|
|
|
Eldbus_Message *m;
|
|
|
|
Eldbus_Object *obj;
|
|
|
|
|
|
|
|
v = eina_list_last_data_get(_e_vols);
|
|
|
|
m = eldbus_message_method_call_new(UDISKS2_BUS, v->dbus_path, ELDBUS_FDO_INTERFACE_PROPERTIES, "GetAll");
|
|
|
|
eldbus_message_arguments_append(m, "s", UDISKS2_INTERFACE_BLOCK);
|
|
|
|
obj = eldbus_proxy_object_get(v->proxy);
|
|
|
|
eldbus_object_send(obj, m, _e_fm_main_udisks2_cb_vol_props, v, -1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_e_fm_main_udisks2_cb_dev_del(void *data __UNUSED__, const Eldbus_Message *msg)
|
|
|
|
{
|
|
|
|
char *path, *interface;
|
|
|
|
Eldbus_Message_Iter *arr;
|
|
|
|
E_Volume *v;
|
|
|
|
Eina_Bool vol = EINA_FALSE, sto = EINA_FALSE;
|
|
|
|
|
|
|
|
if (!eldbus_message_arguments_get(msg, "oas", &path, &arr))
|
|
|
|
return;
|
|
|
|
DBG("DB DEV-: %s", path);
|
|
|
|
|
|
|
|
while (eldbus_message_iter_get_and_next(arr, 's', &interface))
|
|
|
|
{
|
|
|
|
interface += sizeof(UDISKS2_INTERFACE);
|
|
|
|
if (!strcmp(interface, "Filesystem"))
|
|
|
|
vol = EINA_TRUE;
|
|
|
|
else if (!strcmp(interface, "Drive"))
|
|
|
|
sto = EINA_TRUE;
|
|
|
|
}
|
|
|
|
if (vol)
|
|
|
|
{
|
|
|
|
/* TODO: Fix here: T432, T398, T380 */
|
|
|
|
v = _volume_find_by_dbus_path(path);
|
|
|
|
if (v && (!v->mounted))
|
|
|
|
{
|
|
|
|
if (v->optype == E_VOLUME_OP_TYPE_EJECT)
|
|
|
|
_e_fm_main_udisks2_cb_vol_ejected(v);
|
|
|
|
_volume_del(v);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (sto) _e_fm_main_udisks2_storage_del(path);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_e_fm_main_udisks2_cb_storage_prop_modified(void *data, const Eldbus_Message *msg, Eldbus_Pending *p EINA_UNUSED)
|
|
|
|
{
|
|
|
|
Eldbus_Message_Iter *arr;
|
|
|
|
E_Storage *s = data;
|
|
|
|
Eina_Bool valid;
|
|
|
|
|
|
|
|
{
|
|
|
|
const char *type = eldbus_message_signature_get(msg);
|
|
|
|
if (type[0] == 's')
|
|
|
|
{
|
|
|
|
char *txt;
|
|
|
|
if (eldbus_message_arguments_get(msg, type, &txt))
|
|
|
|
ERR("%s", txt);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!eldbus_message_arguments_get(msg, "a{sv}", &arr))
|
|
|
|
return;
|
|
|
|
valid = s->validated;
|
|
|
|
_e_fm_main_udisks2_storage_drive_add(s->udi, s, arr);
|
|
|
|
if (valid != s->validated)
|
|
|
|
_e_fm_main_udisks2_storage_add_send(s);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_e_fm_main_udisks2_cb_storage_prop_modified_cb(void *data, const Eldbus_Message *msg)
|
|
|
|
{
|
|
|
|
const char *interface;
|
|
|
|
Eldbus_Message_Iter *arr, *arr2;
|
|
|
|
E_Storage *s = data;
|
|
|
|
Eina_Bool valid;
|
|
|
|
|
|
|
|
if (!eldbus_message_arguments_get(msg, "sa{sv}as", &interface, &arr, &arr2))
|
|
|
|
return;
|
|
|
|
valid = s->validated;
|
|
|
|
_e_fm_main_udisks2_storage_drive_add(s->udi, s, arr);
|
|
|
|
if (valid != s->validated)
|
|
|
|
_e_fm_main_udisks2_storage_add_send(s);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_e_fm_main_udisks2_cb_vol_prop_modified(void *data, const Eldbus_Message *msg, Eldbus_Pending *p EINA_UNUSED)
|
|
|
|
{
|
|
|
|
const char *interface;
|
|
|
|
Eldbus_Message_Iter *arr, *arr2;
|
|
|
|
E_Volume *v = data;
|
|
|
|
|
|
|
|
if (!eldbus_message_arguments_get(msg, "sa{sv}as", &interface, &arr, &arr2))
|
|
|
|
return;
|
|
|
|
interface += sizeof(UDISKS2_INTERFACE);
|
|
|
|
if (!strcmp(interface, "Filesystem"))
|
|
|
|
_e_fm_main_udisks2_volume_mounts_update(v, arr, 0);
|
|
|
|
else if (!strcmp(interface, "Block"))
|
|
|
|
{
|
|
|
|
U2_Block u2;
|
|
|
|
int block;
|
|
|
|
|
|
|
|
memset(&u2, 0, sizeof(U2_Block));
|
|
|
|
block = _e_fm_main_udisks2_block_handle(arr, &u2);
|
|
|
|
if (block == 1)
|
|
|
|
{
|
|
|
|
Eina_Bool valid = v->validated;
|
|
|
|
|
|
|
|
_e_fm_main_udisks2_volume_block_add(v, &u2);
|
|
|
|
if (v->validated && (valid != v->validated))
|
|
|
|
e_fm_ipc_volume_add(v);
|
|
|
|
else if (!v->validated)
|
|
|
|
_volume_del(v);
|
|
|
|
}
|
|
|
|
_e_fm_main_udisks2_block_clear(&u2);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_e_fm_main_udisks2_cb_vol_prop_modified_cb(void *data, const Eldbus_Message *msg)
|
|
|
|
{
|
|
|
|
_e_fm_main_udisks2_cb_vol_prop_modified(data, msg, NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
static Eina_Bool
|
|
|
|
_storage_del(void *data)
|
|
|
|
{
|
|
|
|
const char *path = data;
|
|
|
|
_e_fm_main_udisks2_storage_del(path);
|
|
|
|
return ECORE_CALLBACK_CANCEL;
|
|
|
|
}
|
|
|
|
|
|
|
|
static E_Storage *
|
|
|
|
_e_fm_main_udisks2_storage_drive_add(const char *udi, E_Storage *s, Eldbus_Message_Iter *arr3)
|
|
|
|
{
|
|
|
|
Eldbus_Message_Iter *dict3;
|
|
|
|
|
|
|
|
if (!s)
|
|
|
|
{
|
|
|
|
if (!s) s = _e_fm_main_udisks2_storage_find(udi);
|
|
|
|
if (!s) s = _e_fm_main_udisks2_storage_add(udi);
|
|
|
|
if (!s) return NULL;
|
|
|
|
}
|
|
|
|
if (s->system_internal)
|
|
|
|
{
|
|
|
|
DBG("removing storage internal %s", s->dbus_path);
|
|
|
|
s->validated = 0;
|
|
|
|
ecore_idler_add(_storage_del, s->dbus_path);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
while (eldbus_message_iter_get_and_next(arr3, 'e', &dict3))
|
|
|
|
{
|
|
|
|
Eldbus_Message_Iter *var;
|
|
|
|
char *key2, *val, *type;
|
|
|
|
Eina_Bool b;
|
|
|
|
uint64_t t;
|
|
|
|
|
|
|
|
if (!eldbus_message_iter_arguments_get(dict3, "sv", &key2, &var))
|
|
|
|
continue;
|
|
|
|
|
|
|
|
type = eldbus_message_iter_signature_get(var);
|
|
|
|
switch (type[0])
|
|
|
|
{
|
|
|
|
case 's':
|
|
|
|
case 'o':
|
|
|
|
eldbus_message_iter_arguments_get(var, type, &val);
|
|
|
|
break;
|
|
|
|
case 'b':
|
|
|
|
eldbus_message_iter_arguments_get(var, type, &b);
|
|
|
|
break;
|
|
|
|
case 't':
|
|
|
|
eldbus_message_iter_arguments_get(var, type, &t);
|
|
|
|
break;
|
|
|
|
default: break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!strcmp(key2, "ConnectionBus"))
|
|
|
|
eina_stringshare_replace(&s->bus, val);
|
|
|
|
else if (!strcmp(key2, "MediaCompatibility"))
|
|
|
|
{
|
|
|
|
Eldbus_Message_Iter *inner_array;
|
|
|
|
const char *media;
|
|
|
|
|
|
|
|
if (!eldbus_message_iter_arguments_get(var, "as", &inner_array))
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if (eldbus_message_iter_get_and_next(inner_array, 's', &media))
|
|
|
|
eina_stringshare_replace(&s->drive_type, media);
|
|
|
|
}
|
|
|
|
else if (!strcmp(key2, "Model"))
|
|
|
|
eina_stringshare_replace(&s->model, (val && val[0]) ? val : NULL);
|
|
|
|
else if (!strcmp(key2, "Vendor"))
|
|
|
|
eina_stringshare_replace(&s->vendor, (val && val[0]) ? val : NULL);
|
|
|
|
else if (!strcmp(key2, "Serial"))
|
|
|
|
eina_stringshare_replace(&s->serial, (val && val[0]) ? val : NULL);
|
|
|
|
else if (!strcmp(key2, "MediaAvailable"))
|
|
|
|
s->media_available = !!b;
|
|
|
|
else if (!strcmp(key2, "Size"))
|
|
|
|
s->media_size = t;
|
|
|
|
else if (!strcmp(key2, "Ejectable"))
|
|
|
|
s->requires_eject = !!b;
|
|
|
|
else if (!strcmp(key2, "Removable"))
|
|
|
|
s->hotpluggable = !!b;
|
|
|
|
else if (!strcmp(key2, "MediaRemovable"))
|
|
|
|
s->removable = !!b;
|
|
|
|
}
|
|
|
|
|
|
|
|
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);
|
|
|
|
s->validated = EINA_TRUE;
|
|
|
|
|
|
|
|
if (!s->proxy)
|
|
|
|
{
|
|
|
|
Eldbus_Object *obj;
|
|
|
|
|
|
|
|
obj = eldbus_object_get(_e_fm_main_udisks2_conn, UDISKS2_BUS, s->udi);
|
|
|
|
s->proxy = eldbus_proxy_get(obj, UDISKS2_INTERFACE_DRIVE);
|
|
|
|
eldbus_proxy_properties_monitor(s->proxy, 1);
|
|
|
|
eldbus_proxy_properties_changed_callback_add(s->proxy, _e_fm_main_udisks2_cb_storage_prop_modified_cb, s);
|
|
|
|
}
|
|
|
|
return s;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
_e_fm_main_udisks2_format_error_msg(char **buf,
|
|
|
|
E_Volume *v,
|
|
|
|
const char *name,
|
|
|
|
const char *message)
|
|
|
|
{
|
|
|
|
int size, vu, vm = 1, en;
|
|
|
|
char *tmp;
|
|
|
|
|
|
|
|
vu = strlen(v->udi) + 1;
|
|
|
|
if (v->mount_point) vm = strlen(v->mount_point) + 1;
|
|
|
|
en = strlen(name) + 1;
|
|
|
|
size = vu + vm + en + strlen(message) + 1;
|
|
|
|
tmp = *buf = malloc(size);
|
|
|
|
|
|
|
|
strcpy(tmp, v->udi);
|
|
|
|
tmp += vu;
|
|
|
|
if (v->mount_point)
|
|
|
|
{
|
|
|
|
strcpy(tmp, v->mount_point);
|
|
|
|
tmp += vm;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
*tmp = 0;
|
|
|
|
tmp += vm;
|
|
|
|
}
|
|
|
|
strcpy(tmp, name);
|
|
|
|
tmp += en;
|
|
|
|
strcpy(tmp, message);
|
|
|
|
|
|
|
|
return size;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Eina_Bool
|
|
|
|
_e_fm_main_udisks2_vol_mount_timeout(E_Volume *v)
|
|
|
|
{
|
|
|
|
char *buf;
|
|
|
|
int size;
|
|
|
|
|
|
|
|
v->guard = NULL;
|
|
|
|
|
|
|
|
E_FREE_FUNC(v->op, eldbus_pending_cancel);
|
|
|
|
v->optype = E_VOLUME_OP_TYPE_NONE;
|
|
|
|
size = _e_fm_main_udisks2_format_error_msg(&buf, v,
|
|
|
|
"org.enlightenment.fm2.MountTimeout",
|
|
|
|
"Unable to mount the volume with specified time-out.");
|
|
|
|
ecore_ipc_server_send(_e_fm_ipc_server, 6 /*E_IPC_DOMAIN_FM*/, E_FM_OP_MOUNT_ERROR,
|
|
|
|
0, 0, 0, buf, size);
|
|
|
|
free(buf);
|
|
|
|
|
|
|
|
return ECORE_CALLBACK_CANCEL;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_e_fm_main_udisks2_cb_vol_mounted(E_Volume *v)
|
|
|
|
{
|
|
|
|
char *buf;
|
|
|
|
int size;
|
|
|
|
|
|
|
|
E_FREE_FUNC(v->guard, ecore_timer_del);
|
|
|
|
if (!v->mount_point) return; /* come back later */
|
|
|
|
|
|
|
|
v->optype = E_VOLUME_OP_TYPE_NONE;
|
|
|
|
v->op = NULL;
|
|
|
|
v->mounted = EINA_TRUE;
|
|
|
|
INF("MOUNT: %s from %s", v->udi, v->mount_point);
|
|
|
|
size = strlen(v->udi) + 1 + strlen(v->mount_point) + 1;
|
|
|
|
buf = alloca(size);
|
|
|
|
strcpy(buf, v->udi);
|
|
|
|
strcpy(buf + strlen(buf) + 1, v->mount_point);
|
|
|
|
ecore_ipc_server_send(_e_fm_ipc_server,
|
|
|
|
6 /*E_IPC_DOMAIN_FM*/,
|
|
|
|
E_FM_OP_MOUNT_DONE,
|
|
|
|
0, 0, 0, buf, size);
|
|
|
|
}
|
|
|
|
|
|
|
|
static Eina_Bool
|
|
|
|
_e_fm_main_udisks2_vol_unmount_timeout(E_Volume *v)
|
|
|
|
{
|
|
|
|
char *buf;
|
|
|
|
int size;
|
|
|
|
|
|
|
|
v->guard = NULL;
|
|
|
|
if (v->op)
|
|
|
|
eldbus_pending_cancel(v->op);
|
|
|
|
v->op = NULL;
|
|
|
|
v->optype = E_VOLUME_OP_TYPE_NONE;
|
|
|
|
size = _e_fm_main_udisks2_format_error_msg(&buf, v,
|
|
|
|
"org.enlightenment.fm2.UnmountTimeout",
|
|
|
|
"Unable to unmount the volume with specified time-out.");
|
|
|
|
ecore_ipc_server_send(_e_fm_ipc_server, 6 /*E_IPC_DOMAIN_FM*/, E_FM_OP_UNMOUNT_ERROR,
|
|
|
|
0, 0, 0, buf, size);
|
|
|
|
free(buf);
|
|
|
|
|
|
|
|
return ECORE_CALLBACK_CANCEL;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_e_fm_main_udisks2_cb_vol_unmounted(E_Volume *v)
|
|
|
|
{
|
|
|
|
char *buf;
|
|
|
|
int size;
|
|
|
|
|
|
|
|
E_FREE_FUNC(v->guard, ecore_timer_del);
|
|
|
|
|
|
|
|
if (v->optype != E_VOLUME_OP_TYPE_EJECT)
|
|
|
|
{
|
|
|
|
v->optype = E_VOLUME_OP_TYPE_NONE;
|
|
|
|
v->op = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
v->mounted = EINA_FALSE;
|
|
|
|
INF("UNMOUNT: %s from %s", v->udi, v->mount_point);
|
|
|
|
size = strlen(v->udi) + 1 + strlen(v->mount_point) + 1;
|
|
|
|
buf = alloca(size);
|
|
|
|
strcpy(buf, v->udi);
|
|
|
|
strcpy(buf + strlen(buf) + 1, v->mount_point);
|
|
|
|
ecore_ipc_server_send(_e_fm_ipc_server,
|
|
|
|
6 /*E_IPC_DOMAIN_FM*/,
|
|
|
|
E_FM_OP_UNMOUNT_DONE,
|
|
|
|
0, 0, 0, buf, size);
|
|
|
|
}
|
|
|
|
|
|
|
|
static Eina_Bool
|
|
|
|
_e_fm_main_udisks2_vol_eject_timeout(E_Volume *v)
|
|
|
|
{
|
|
|
|
char *buf;
|
|
|
|
int size;
|
|
|
|
|
|
|
|
v->guard = NULL;
|
|
|
|
if (v->op)
|
|
|
|
eldbus_pending_cancel(v->op);
|
|
|
|
v->op = NULL;
|
|
|
|
v->optype = E_VOLUME_OP_TYPE_NONE;
|
|
|
|
size = _e_fm_main_udisks2_format_error_msg(&buf, v,
|
|
|
|
"org.enlightenment.fm2.EjectTimeout",
|
|
|
|
"Unable to eject the media with specified time-out.");
|
|
|
|
ecore_ipc_server_send(_e_fm_ipc_server, 6 /*E_IPC_DOMAIN_FM*/, E_FM_OP_EJECT_ERROR,
|
|
|
|
0, 0, 0, buf, size);
|
|
|
|
free(buf);
|
|
|
|
|
|
|
|
return ECORE_CALLBACK_CANCEL;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Eldbus_Pending *
|
|
|
|
_volume_eject(Eldbus_Proxy *proxy)
|
|
|
|
{
|
|
|
|
Eldbus_Message *msg;
|
|
|
|
Eldbus_Message_Iter *array, *main_iter;
|
|
|
|
|
|
|
|
msg = eldbus_proxy_method_call_new(proxy, "Eject");
|
|
|
|
main_iter = eldbus_message_iter_get(msg);
|
|
|
|
eldbus_message_iter_arguments_append(main_iter, "a{sv}", &array);
|
|
|
|
eldbus_message_iter_container_close(main_iter, array);
|
|
|
|
|
|
|
|
return eldbus_proxy_send(proxy, msg, NULL, NULL, -1);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_volume_eject_umount_cb(void *data, const Eldbus_Message *msg, Eldbus_Pending *pending EINA_UNUSED)
|
|
|
|
{
|
|
|
|
const char *name, *txt;
|
|
|
|
E_Volume *v = data;
|
|
|
|
|
|
|
|
if (eldbus_message_error_get(msg, &name, &txt))
|
|
|
|
ERR("%s: %s", name, txt);
|
|
|
|
else if (v->optype == E_VOLUME_OP_TYPE_EJECT)
|
|
|
|
{
|
|
|
|
vols_ejecting = eina_list_remove(vols_ejecting, v);
|
|
|
|
_volume_eject(v->storage->proxy);
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
static Eldbus_Pending *
|
|
|
|
_volume_umount(E_Volume *v)
|
|
|
|
{
|
|
|
|
Eldbus_Message *msg;
|
|
|
|
Eldbus_Message_Iter *array, *main_iter;
|
|
|
|
|
|
|
|
msg = eldbus_proxy_method_call_new(v->proxy, "Unmount");
|
|
|
|
main_iter = eldbus_message_iter_get(msg);
|
|
|
|
eldbus_message_iter_arguments_append(main_iter, "a{sv}", &array);
|
|
|
|
eldbus_message_iter_container_close(main_iter, array);
|
|
|
|
|
|
|
|
return eldbus_proxy_send(v->proxy, msg, _volume_eject_umount_cb, v, -1);
|
|
|
|
}
|
|
|
|
|
|
|
|
static Eldbus_Pending *
|
|
|
|
_volume_mount(Eldbus_Proxy *proxy, const char *fstype, const char *buf)
|
|
|
|
{
|
|
|
|
Eldbus_Message *msg;
|
|
|
|
Eldbus_Message_Iter *array, *main_iter, *dict, *var;
|
|
|
|
char opt_txt[] = "options";
|
|
|
|
char fs_txt[] = "fstype";
|
|
|
|
|
|
|
|
msg = eldbus_proxy_method_call_new(proxy, "Mount");
|
|
|
|
main_iter = eldbus_message_iter_get(msg);
|
|
|
|
if (!eldbus_message_iter_arguments_append(main_iter, "a{sv}", &array))
|
|
|
|
ERR("E");
|
|
|
|
if (fstype)
|
|
|
|
{
|
|
|
|
if (!eldbus_message_iter_arguments_append(array, "{sv}", &dict))
|
|
|
|
ERR("E");
|
|
|
|
eldbus_message_iter_basic_append(dict, 's', fs_txt);
|
|
|
|
|
|
|
|
var = eldbus_message_iter_container_new(dict, 'v', "s");
|
|
|
|
eldbus_message_iter_basic_append(var, 's', fstype);
|
|
|
|
eldbus_message_iter_container_close(dict, var);
|
|
|
|
eldbus_message_iter_container_close(array, dict);
|
|
|
|
|
|
|
|
}
|
|
|
|
if (buf[0])
|
|
|
|
{
|
|
|
|
if (!eldbus_message_iter_arguments_append(array, "{sv}", &dict))
|
|
|
|
ERR("E");
|
|
|
|
eldbus_message_iter_basic_append(dict, 's', opt_txt);
|
|
|
|
|
|
|
|
var = eldbus_message_iter_container_new(dict, 'v', "s");
|
|
|
|
eldbus_message_iter_basic_append(var, 's', buf);
|
|
|
|
eldbus_message_iter_container_close(dict, var);
|
|
|
|
eldbus_message_iter_container_close(array, dict);
|
|
|
|
}
|
|
|
|
eldbus_message_iter_container_close(main_iter, array);
|
|
|
|
|
|
|
|
return eldbus_proxy_send(proxy, msg, NULL, NULL, -1);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_e_fm_main_udisks2_cb_vol_ejected(E_Volume *v)
|
|
|
|
{
|
|
|
|
char *buf;
|
|
|
|
int size;
|
|
|
|
|
|
|
|
E_FREE_FUNC(v->guard, ecore_timer_del);
|
|
|
|
v->optype = E_VOLUME_OP_TYPE_NONE;
|
|
|
|
|
|
|
|
size = strlen(v->udi) + 1;
|
|
|
|
buf = alloca(size);
|
|
|
|
strcpy(buf, v->udi);
|
|
|
|
ecore_ipc_server_send(_e_fm_ipc_server,
|
|
|
|
6 /*E_IPC_DOMAIN_FM*/,
|
|
|
|
E_FM_OP_EJECT_DONE,
|
|
|
|
0, 0, 0, buf, size);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_e_fm_main_udisks2_volume_mounts_update(E_Volume *v, Eldbus_Message_Iter *arr3, Eina_Bool first)
|
|
|
|
{
|
|
|
|
Eldbus_Message_Iter *dict3;
|
|
|
|
Eina_List *mounts = NULL;
|
|
|
|
|
|
|
|
while (eldbus_message_iter_get_and_next(arr3, 'e', &dict3))
|
|
|
|
{
|
|
|
|
Eldbus_Message_Iter *var;
|
|
|
|
char *key2, *type;
|
|
|
|
|
|
|
|
if (!eldbus_message_iter_arguments_get(dict3, "sv", &key2, &var))
|
|
|
|
continue;
|
|
|
|
|
|
|
|
type = eldbus_message_iter_signature_get(var);
|
|
|
|
switch (type[0])
|
|
|
|
{
|
|
|
|
Eldbus_Message_Iter *fuckyouglib;
|
|
|
|
|
|
|
|
case 'a':
|
|
|
|
if (strcmp(key2, "MountPoints")) continue;
|
|
|
|
/* glib developers are assholes, so this is "aay" instead of just "as" */
|
|
|
|
if (!eldbus_message_iter_arguments_get(var, type, &fuckyouglib))
|
|
|
|
{
|
|
|
|
ERR("fucked by glib I guess");
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
do
|
|
|
|
{
|
|
|
|
Eina_Stringshare *m;
|
|
|
|
|
|
|
|
m = _util_fuckyouglib_convert(fuckyouglib);
|
|
|
|
if (m) mounts = eina_list_append(mounts, m);
|
|
|
|
}
|
|
|
|
while (eldbus_message_iter_next(fuckyouglib));
|
|
|
|
default: continue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (first)
|
|
|
|
{
|
|
|
|
eina_stringshare_replace(&v->mount_point, eina_list_last_data_get(mounts));
|
|
|
|
v->mounted = !!v->mount_point;
|
|
|
|
if (v->storage)
|
|
|
|
v->storage->media_available = v->mounted;
|
|
|
|
}
|
|
|
|
else if ((!v->mounted) || (!eina_list_data_find(mounts, v->mount_point)))
|
|
|
|
{
|
|
|
|
if (mounts)
|
|
|
|
eina_stringshare_replace(&v->mount_point, eina_list_last_data_get(mounts));
|
|
|
|
v->mounted = !!mounts;
|
|
|
|
if (v->storage)
|
|
|
|
v->storage->media_available = v->mounted;
|
|
|
|
switch (v->optype)
|
|
|
|
{
|
|
|
|
case E_VOLUME_OP_TYPE_MOUNT:
|
|
|
|
_e_fm_main_udisks2_cb_vol_mounted(v);
|
|
|
|
break;
|
|
|
|
case E_VOLUME_OP_TYPE_UNMOUNT:
|
|
|
|
_e_fm_main_udisks2_cb_vol_unmounted(v);
|
|
|
|
break;
|
|