summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/eulogium.c266
-rw-r--r--src/eulogium.h8
2 files changed, 274 insertions, 0 deletions
diff --git a/src/eulogium.c b/src/eulogium.c
index 6f8bba0..c6316b4 100644
--- a/src/eulogium.c
+++ b/src/eulogium.c
@@ -1127,9 +1127,16 @@ Evas_Object *eulogium_main_menu(Evas_Object *window, struct eulogium_data *eulog
static void eulogium_setup(struct eulogium_data *eulogium)
{
+ struct mount_data *mount;
+
while (screen_data.screen[screen_data.count].type != END)
screen_data.count++;
+ /* eina_list_append() appends data to an existing list, or creates a new list. We need to know the location
+ * of the list beforehand and thus we need to create a list with a dummy entry */
+ mount = calloc(1, sizeof(struct mount_data));
+ mount->id = "sentinel";
+ eulogium->mounts = eina_list_append(NULL, mount);
eulogium->progress_data_refresh = NULL;
eulogium->print.name = NULL;
eulogium->print.file = NULL;
@@ -1325,9 +1332,241 @@ static void _on_status_changed_ret(void *data, const Eldbus_Message *msg)
_on_get_status_ret(data, msg, NULL);
}
+static void eulogium_disk_free(struct mount_data *mount)
+{
+ eeze_disk_free(mount->disk);
+ if (mount->id)
+ free(mount->id);
+ eldbus_proxy_unref(mount->proxy);
+ free(mount);
+ mount = NULL;
+}
+
+static void _on_where_ret(void *data, const Eldbus_Message *msg, Eldbus_Pending *pending EINA_UNUSED)
+{
+ struct mount_data *mount = data;
+ const char *errname, *errmsg;
+ Eldbus_Message_Iter *var = NULL;
+ char *where;
+
+ if (eldbus_message_error_get(msg, &errname, &errmsg)) {
+ EINA_LOG_ERR("%s %s", errname, errmsg);
+ return;
+ }
+ if (!eldbus_message_arguments_get(msg, "v", &var)) {
+ EINA_LOG_ERR("Message content does not match expected \"v\" signature. (%s)", eldbus_message_signature_get(msg));
+ return;
+ }
+ if (!eldbus_message_iter_arguments_get(var, "s", &where)) {
+ EINA_LOG_ERR("Message content does not match expected \"s\" signature. (%s)", eldbus_message_iter_signature_get(var));
+ return;
+ }
+ if (!where)
+ return;
+
+ /* Never use a medium that is mounted under dev, proc, run or sys. */
+ if (!(strncmp(where, "/dev/", 5) &&
+ strncmp(where, "/proc/", 6) &&
+ strncmp(where, "/run/", 5) &&
+ strncmp(where, "/sys/", 5)))
+ return;
+
+ mount->disk = eeze_disk_new_from_mount(where);
+ eeze_disk_scan(mount->disk);
+ EINA_LOG_ERR("Medium mounted at %s of type %d", where, eeze_disk_type_get(mount->disk));
+ if (eeze_disk_type_get(mount->disk) == EEZE_DISK_TYPE_USB)
+ *mount->mounts = eina_list_append(*mount->mounts, mount); /* XXX DANGER! if _append returns a new list location, eulogium->mounts won't know about it breaking everything! REWRITE!! */
+ else
+ eulogium_disk_free(mount);
+ /* TODO: UI Stuffs/signals */
+}
+
+static void _on_result_ret(void *data, const Eldbus_Message *msg, Eldbus_Pending *pending EINA_UNUSED)
+{
+ struct mount_data *mount = data;
+ const char *errname, *errmsg;
+ Eldbus_Message_Iter *var = NULL;
+ char *result;
+
+ if (eldbus_message_error_get(msg, &errname, &errmsg)) {
+ EINA_LOG_ERR("%s %s", errname, errmsg);
+ return;
+ }
+ if (!eldbus_message_arguments_get(msg, "v", &var)) {
+ EINA_LOG_ERR("Message content does not match expected \"v\" signature. (%s)", eldbus_message_signature_get(msg));
+ return;
+ }
+ if (!eldbus_message_iter_arguments_get(var, "s", &result)) {
+ EINA_LOG_ERR("Message content does not match expected \"s\" signature. (%s)", eldbus_message_iter_signature_get(var));
+ return;
+ }
+ if (strncmp(result, "success", 7)) {
+ return;
+ }
+
+ eldbus_proxy_property_get(mount->proxy, "Where", _on_where_ret, mount);
+}
+
+static void _on_unit_new_ret(void *data, const Eldbus_Message *msg)
+{
+ const char *errname, *errmsg;
+ struct eulogium_data *eulogium = data;
+ char *id, *unit, *ext;
+ size_t id_len;
+ Eldbus_Object *obj;
+ struct mount_data *mount;
+
+ if (eldbus_message_error_get(msg, &errname, &errmsg)) {
+ EINA_LOG_ERR("%s %s", errname, errmsg);
+ return;
+ }
+ if (!eldbus_message_arguments_get(msg, "so", &id, &unit)) {
+ EINA_LOG_ERR("Message content does not match expected \"so\" signature.");
+ return;
+ }
+ ext = ecore_file_ext_get(id);
+ if (strncmp(ext, "mount", 5))
+ return;
+
+ obj = eldbus_object_get(eulogium->dbus.conn, "org.freedesktop.systemd1", unit);
+ if (!obj) {
+ EINA_LOG_WARN("Could not get org.freedesktop.systemd1-mount object. (%s)", unit);
+ return;
+ }
+ mount = calloc(1, sizeof(struct mount_data));
+ if (!mount) {
+ EINA_LOG_ERR("Unable to allocate memory for mountpoint %s", id);
+ return;
+ }
+ id_len = strlen(id);
+ mount->id = malloc(id_len + 1);
+ if (!mount->id) {
+ EINA_LOG_ERR("Unable to allocate memory for id %s", id);
+ free(mount);
+ return;
+ }
+ strncpy(mount->id, id, id_len);
+ mount->proxy = eldbus_proxy_get(obj, "org.freedesktop.systemd1.Mount");
+ mount->mounts = &eulogium->mounts;
+ if (!mount->proxy) {
+ EINA_LOG_WARN("Could not get dbus proxy for (%s).", id);
+ free(mount->id);
+ free(mount);
+ return;
+ }
+ EINA_LOG_ERR("Medium inserted (%s)", id);
+ eldbus_proxy_property_get(mount->proxy, "Result", _on_result_ret, mount);
+}
+
+static void _on_list_units_ret(void *data, const Eldbus_Message *msg, Eldbus_Pending *Pending EINA_UNUSED)
+{
+ const char *errname, *errmsg;
+ struct eulogium_data *eulogium = data;
+ Eldbus_Message_Iter *array, *dbus_struct;
+ char *id, *unit;
+ char *dummy;
+ uint_fast32_t dummy_int;
+
+ if (eldbus_message_error_get(msg, &errname, &errmsg)) {
+ EINA_LOG_ERR("%s %s", errname, errmsg);
+ return;
+ }
+ if (!eldbus_message_arguments_get(msg, "a(ssssssouso)", &array)) {
+ EINA_LOG_ERR("Message content does not match expected \"a(ssssssouso)\" signature. (%s)", eldbus_message_signature_get(msg));
+ return;
+ }
+ while (eldbus_message_iter_get_and_next(array, 'r', &dbus_struct)) {
+ if (eldbus_message_iter_arguments_get(dbus_struct, "ssssssouso", &id, &dummy, &dummy, &dummy, &dummy, &dummy, &unit, &dummy_int, &dummy, &dummy)) {
+ Eldbus_Object *obj;
+ struct mount_data *mount;
+ size_t id_len;
+
+ obj = eldbus_object_get(eulogium->dbus.conn, "org.freedesktop.systemd1", unit);
+ if (!obj) {
+ EINA_LOG_WARN("Could not get org.freedesktop.systemd1-mount object. (%s)", unit);
+ return;
+ }
+ mount = calloc(1, sizeof(struct mount_data));
+ if (!mount) {
+ EINA_LOG_ERR("Unable to allocate memory for mountpoint %s", id);
+ break;
+ }
+ id_len = strlen(id);
+ mount->id = malloc(id_len + 1);
+ if (!mount->id) {
+ EINA_LOG_ERR("Unable to allocate memory for id %s", id);
+ free(mount);
+ break;
+ }
+ strncpy(mount->id, id, id_len);
+ mount->proxy = eldbus_proxy_get(obj, "org.freedesktop.systemd1.Mount");
+ if (!mount->proxy) {
+ EINA_LOG_WARN("Could not get dbus proxy for (%s).", id);
+ free(mount->id);
+ free(mount);
+ break;
+ }
+ mount->mounts = &eulogium->mounts;
+ EINA_LOG_ERR("Medium detected (%s)", id);
+ eldbus_proxy_property_get(mount->proxy, "Result", _on_result_ret, mount);
+ } else {
+ EINA_LOG_ERR("Unable to decode dbus-struct\n");
+ }
+ }
+}
+
+static int _mount_find_cb(const void *haystack, const void *needle)
+{
+ const struct mount_data *mount = haystack;
+ const char *id = needle;
+
+ return strncmp(id, mount->id, strlen(id));
+}
+
+static void _on_unit_removed_ret(void *data, const Eldbus_Message *msg)
+{
+ const char *errname, *errmsg;
+ struct eulogium_data *eulogium = data;
+ char *id, *unit, *ext;
+ Eldbus_Object *obj;
+ struct mount_data *mount;
+ Eina_List *list;
+
+ if (eldbus_message_error_get(msg, &errname, &errmsg)) {
+ EINA_LOG_ERR("%s %s", errname, errmsg);
+ return;
+ }
+ if (!eldbus_message_arguments_get(msg, "so", &id, &unit)) {
+ EINA_LOG_ERR("Message content does not match expected \"so\" signature.");
+ return;
+ }
+ ext = ecore_file_ext_get(id);
+ if (strncmp(ext, "mount", 5))
+ return;
+
+ obj = eldbus_object_get(eulogium->dbus.conn, "org.freedesktop.systemd1", unit);
+ if (!obj) {
+ EINA_LOG_WARN("Could not get org.freedesktop.systemd1-mount object (%s).", unit);
+ return;
+ }
+ EINA_LOG_ERR("Medium remove request (%s)", id);
+ list = eina_list_search_unsorted_list(eulogium->mounts, _mount_find_cb, id);
+ mount = eina_list_data_get(list);
+ if (!mount) {
+ EINA_LOG_CRIT("Mount %s is NULL, this should not happen!", id);
+ } else {
+ eulogium_disk_free(mount);
+ eulogium->mounts = eina_list_remove_list(eulogium->mounts, list);
+ }
+ /* TODO: UI Stuff/signals */
+}
+
static int eulogium_dbus_init(struct eulogium_data *eulogium)
{
Eldbus_Object *obj;
+ Eldbus_Proxy *proxy;
+ Eldbus_Message_Iter *iter, *array;
+ Eldbus_Message *msg;
eulogium->dbus.conn = eldbus_connection_get(ELDBUS_CONNECTION_TYPE_SYSTEM);
if (!eulogium->dbus.conn) {
@@ -1335,6 +1574,20 @@ static int eulogium_dbus_init(struct eulogium_data *eulogium)
return -ECONNREFUSED;
}
+ obj = eldbus_object_get(eulogium->dbus.conn, "org.freedesktop.systemd1", "/org/freedesktop/systemd1");
+ if (!obj) {
+ EINA_LOG_WARN("Could not get org.freedesktop.systemd1 object.");
+ return -EFAULT;
+ }
+
+ /* XXX We currently monitor systemd for new mounts. This functionality should really be handled by eeze and once it may does, this has to be re-written. */
+ proxy = eldbus_proxy_get(obj, "org.freedesktop.systemd1.Manager");
+ if (!proxy) {
+ EINA_LOG_WARN("Could not get dbus systemd-manager proxy.");
+ return -EFAULT;
+ }
+ eldbus_name_owner_changed_callback_add(eulogium->dbus.conn, "org.freedesktop.systemd1.Manager", on_name_owner_changed, eulogium->dbus.conn, EINA_TRUE);
+
/* TODO: Make nice loop that gets BUS/PATH from a predefined array? */
obj = eldbus_object_get(eulogium->dbus.conn, "nl.ultimaker.harma", "/nl/ultimaker/harma");
if (!obj) {
@@ -1382,6 +1635,19 @@ static int eulogium_dbus_init(struct eulogium_data *eulogium)
eldbus_proxy_call(eulogium->dbus.proxy[PRINTER], "getStatus", _on_get_status_ret, eulogium, -1, "");
eldbus_proxy_signal_handler_add(eulogium->dbus.proxy[PRINTER], "statusChanged", _on_status_changed_ret, eulogium);
+ eldbus_proxy_signal_handler_add(proxy, "UnitNew", _on_unit_new_ret, eulogium);
+ eldbus_proxy_signal_handler_add(proxy, "UnitRemoved", _on_unit_removed_ret, eulogium);
+
+ msg = eldbus_proxy_method_call_new(proxy, "ListUnitsFiltered");
+ iter = eldbus_message_iter_get(msg);
+ array = eldbus_message_iter_container_new(iter, 'a', "s");
+ if (!array)
+ EINA_LOG_ERR("Empty container");
+ eldbus_message_iter_basic_append(array, 's', "mounted");
+ eldbus_message_iter_container_close(iter, array);
+ eldbus_proxy_send(proxy, msg, _on_list_units_ret, eulogium, -1);
+ /* eldbus_proxy_call(proxy, "ListUnitsFiltered", _on_list_units_ret, eulogium, -1, "as", "{mounted}"); */
+
return 0;
}
diff --git a/src/eulogium.h b/src/eulogium.h
index a4c16b0..ca9c1b6 100644
--- a/src/eulogium.h
+++ b/src/eulogium.h
@@ -68,6 +68,13 @@ struct dbus_data {
Eldbus_Proxy *proxy[LAST];
};
+struct mount_data {
+ char *id;
+ Eldbus_Proxy *proxy;
+ Eeze_Disk *disk;
+ Eina_List **mounts;
+};
+
struct eulogium_data {
Evas_Object *navi;
Evas_Object *time;
@@ -78,6 +85,7 @@ struct eulogium_data {
struct printer_data printer;
struct print_data print;
struct dbus_data dbus;
+ Eina_List *mounts;
void *data;
};