diff options
Diffstat (limited to 'src/eulogium.c')
-rw-r--r-- | src/eulogium.c | 266 |
1 files changed, 266 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; } |