/* vim: set sw=3 ts=3 sts=3 expandtab: */ #include "ecdb.h" void _ecdb_hal_device_all_cb(void *data, void *reply_data, DBusError *error); void _ecdb_hal_volume_all_cb(void *data, void *reply_data, DBusError *error); void _ecdb_hal_device_handle(void *data, void *reply_data, DBusError *error); void _ecdb_hal_volume_removed_cb(void *data, DBusMessage *msg); void _ecdb_hal_volume_added_cb(void *data, DBusMessage *msg); void _ecdb_hal_volume_prop_modified(void *data, DBusMessage *msg); void _ecdb_hal_volume_cb(void *data, void *reply_data, DBusError *error); void _ecdb_hal_volume_handle(void *data, void *reply_data, DBusError *error); void _ecdb_hal_unmount_cb(void *data, void *reply_data, DBusError *error); static void _ecdb_hal_volumes_init(void); void _ecdb_hal_device_handle(void *data, void *reply_data, DBusError *error) { E_Hal_Device_Get_All_Properties_Return *ret; Eina_List *l; Ecdb_Drive_Info *drive; char *udi, *str; int err = 0; ret = reply_data; udi = data; if ((!ret) || (!udi)) { EINA_ERROR_PWARN("NULL udi or reply!\n"); return; } if (dbus_error_is_set(error)) { EINA_ERROR_PWARN("DBus error: %s %s\n", error->name, error->message); dbus_error_free(error); return; } str = e_hal_property_string_get(ret, "block.device", &err); if (!str) return; if (!err) { EINA_LIST_FOREACH(em->drives, l, drive) { if (!strcmp(drive->location, str)) { if (!ecdb_update_drive_info(drive, ret)) { EINA_ERROR_PWARN("Couldn't update old drive info!\n"); } ecdb_print_drive_info(); return; } } /* * Create the drive information here, as we will have already * returned if it previously exists */ if (!ecdb_aquire_drive_info(ret, str, udi)) { EINA_ERROR_PWARN("Couldn't create new drive info!\n"); return; } ecdb_print_drive_info(); /* Check to see if we have acquired all of the drives */ if (eina_list_count(em->drives) >= em->init_count) { em->init_count = 0; _ecdb_hal_volumes_init(); } } } void _ecdb_hal_volume_removed_cb(void *data __UNUSED__, DBusMessage *msg) { DBusError err; Eina_List *l; Ecdb_Drive_Info *drive; char *udi; dbus_error_init(&err); dbus_message_get_args(msg, &err, DBUS_TYPE_STRING, &udi, DBUS_TYPE_INVALID); EINA_LIST_FOREACH(em->drives, l, drive) { if (!strcmp(drive->disc_udi, udi)) { drive->fresh_info = FALSE; drive->status = 0; FREE(drive->type); } } } void _ecdb_hal_volume_added_cb(void *data __UNUSED__, DBusMessage *msg) { DBusError err; char *udi; dbus_error_init(&err); dbus_message_get_args(msg, &err, DBUS_TYPE_STRING, &udi, DBUS_TYPE_INVALID); /* XXX Do something with the error above? */ e_hal_device_query_capability(em->conn, udi, "volume", _ecdb_hal_volume_cb, (void *)strdup(udi)); } void _ecdb_hal_volume_cb(void *data, void *reply_data, DBusError *error) { char *udi; E_Hal_Device_Query_Capability_Return *ret; udi = data; ret = reply_data; if (!ret) { EINA_ERROR_PWARN("No DBus data!\n"); return; } if (dbus_error_is_set(error)) { EINA_ERROR_PWARN("DBus error: %s %s\n", error->name, error->message); dbus_error_free(error); return; } if (ret->boolean) { e_hal_device_get_all_properties(em->conn, udi, _ecdb_hal_volume_handle, udi); } } void _ecdb_hal_device_all_cb(void *data __UNUSED__, void *reply_data, DBusError *error) { char *udi; Eina_List *l; E_Hal_Manager_Find_Device_By_Capability_Return *ret; ret = reply_data; if ((!ret) || (!ret->strings)) { EINA_ERROR_PWARN("No DBus data!\n"); return; } if (dbus_error_is_set(error)) { EINA_ERROR_PWARN("DBus error: %s %s\n", error->name, error->message); dbus_error_free(error); return; } em->init_count = eina_list_count(ret->strings); EINA_LIST_FOREACH(ret->strings, l, udi) { e_hal_device_get_all_properties(em->conn, udi, _ecdb_hal_device_handle, (void *)strdup(udi)); } } int ecdb_hal_init(void) { em->conn = e_dbus_bus_get(DBUS_BUS_SYSTEM); if (!em->conn) { EINA_ERROR_PWARN("Error connecting to system bus!\n"); return 0; } e_hal_manager_find_device_by_capability(em->conn, "storage.cdrom", _ecdb_hal_device_all_cb, NULL); return 1; } void ecdb_hal_shutdown(void) { e_dbus_signal_handler_del(em->conn, em->dev_added); e_dbus_signal_handler_del(em->conn, em->dev_removed); e_dbus_connection_close(em->conn); } void ecdb_hal_request_unmount(Ecdb_Drive_Info *drive, E_DBus_Callback_Func cb, void *data) { e_hal_device_volume_unmount(em->conn, drive->disc_udi, NULL, cb, data); } static void _ecdb_hal_volumes_init() { em->dev_added = e_dbus_signal_handler_add(em->conn, "org.freedesktop.Hal", "/org/freedesktop/Hal/Manager", "org.freedesktop.Hal.Manager", "DeviceAdded", _ecdb_hal_volume_added_cb, NULL); em->dev_removed = e_dbus_signal_handler_add(em->conn, "org.freedesktop.Hal", "/org/freedesktop/Hal/Manager", "org.freedesktop.Hal.Manager", "DeviceRemoved", _ecdb_hal_volume_removed_cb, NULL); e_hal_manager_find_device_by_capability(em->conn, "volume.disc", _ecdb_hal_volume_all_cb, NULL); } void _ecdb_hal_volume_all_cb(void *data __UNUSED__, void *reply_data, DBusError *error) { char *udi; Eina_List *l; E_Hal_Manager_Find_Device_By_Capability_Return *ret; ret = reply_data; if ((!ret) || (!ret->strings)) { EINA_ERROR_PWARN("No DBus data!\n"); return; } if (dbus_error_is_set(error)) { EINA_ERROR_PWARN("DBus error: %s %s\n", error->name, error->message); dbus_error_free(error); return; } EINA_LIST_FOREACH(ret->strings, l, udi) { e_hal_device_get_all_properties(em->conn, udi, _ecdb_hal_volume_handle, (void *)strdup(udi)); } } void _ecdb_hal_volume_handle(void *data, void *reply_data, DBusError *error) { E_Hal_Device_Get_All_Properties_Return *ret; Ecdb_Drive_Info *drive; Eina_List *l; char *udi, *disc_udi; int err; ret = reply_data; disc_udi = data; if ((!ret) || (!disc_udi)) { EINA_ERROR_PWARN("No DBus data or volume data!\n"); return; } if (dbus_error_is_set(error)) { EINA_ERROR_PWARN("DBus error: %s %s\n", error->name, error->message); dbus_error_free(error); return; } /* Ignore volumes that are not discs */ if ((!e_hal_property_bool_get(ret, "volume.is_disc", &err)) || (err)) return; /* Get the parent udi */ udi = e_hal_property_string_get(ret, "info.parent", NULL); /* Find the drive this volume belongs to */ EINA_LIST_FOREACH(em->drives, l, drive) { if (!strcmp(udi, drive->udi)) { drive->fresh_info = TRUE; drive->disc_udi = disc_udi; drive->capacity = e_hal_property_uint64_get(ret, "volume.disc.capacity", NULL); if (e_hal_property_bool_get(ret, "volume.disc.is_blank", NULL)) drive->status |= ECDB_DISC_BLANK; if (e_hal_property_bool_get(ret, "volume.disc.is_appendable", NULL)) drive->status |= ECDB_DISC_APPENDABLE; if (e_hal_property_bool_get(ret, "volume.disc.is_rewritable", NULL)) drive->status |= ECDB_DISC_REWRITABLE; drive->type = e_hal_property_string_get(ret, "volume.disc.type", NULL); /* Also refresh the drive, for write speeds */ e_hal_device_get_all_properties(em->conn, udi, _ecdb_hal_device_handle, udi); break; } } FREE(udi); }