static struct generic_data *object_path_ref(DBusConnection *connection, const char *path) { struct generic_data *data; if (dbus_connection_get_object_path_data(connection, path, (void *) &data) == TRUE) { if (data != NULL) { data->refcount++; return data; } } data = g_new0(struct generic_data, 1); data->refcount = 1; data->introspect = g_strdup(DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE "<node></node>"); if (!dbus_connection_register_object_path(connection, path, &generic_table, data)) { g_free(data->introspect); g_free(data); return NULL; } invalidate_parent_data(connection, path); add_interface(data, DBUS_INTERFACE_INTROSPECTABLE, introspect_methods, NULL, NULL, data, NULL); return data; }
static void invalidate_parent_data(DBusConnection *conn, const char *child_path) { struct generic_data *data = NULL; char *parent_path, *slash; parent_path = g_strdup(child_path); slash = strrchr(parent_path, '/'); if (slash == NULL) goto done; if (slash == parent_path && parent_path[1] != '\0') parent_path[1] = '\0'; else *slash = '\0'; if (!strlen(parent_path)) goto done; if (dbus_connection_get_object_path_data(conn, parent_path, (void *) &data) == FALSE) { goto done; } invalidate_parent_data(conn, parent_path); if (data == NULL) goto done; g_free(data->introspect); data->introspect = NULL; done: g_free(parent_path); }
static struct generic_data *invalidate_parent_data(DBusConnection *conn, const char *child_path) { struct generic_data *data = NULL, *child = NULL, *parent = NULL; char *parent_path, *slash; parent_path = g_strdup(child_path); slash = strrchr(parent_path, '/'); if (slash == NULL) goto done; if (slash == parent_path && parent_path[1] != '\0') parent_path[1] = '\0'; else *slash = '\0'; if (!strlen(parent_path)) goto done; if (dbus_connection_get_object_path_data(conn, parent_path, (void *) &data) == FALSE) { goto done; } parent = invalidate_parent_data(conn, parent_path); if (data == NULL) { data = parent; if (data == NULL) goto done; } g_free(data->introspect); data->introspect = NULL; if (!dbus_connection_get_object_path_data(conn, child_path, (void *) &child)) goto done; if (child == NULL || g_slist_find(data->objects, child) != NULL) goto done; data->objects = g_slist_prepend(data->objects, child); child->parent = data; done: g_free(parent_path); return data; }
static struct generic_data *object_path_ref(DBusConnection *connection, const char *path) { struct generic_data *data; if (dbus_connection_get_object_path_data(connection, path, (void *) &data) == TRUE) { if (data != NULL) { data->refcount++; return data; } } data = g_new0(struct generic_data, 1); data->conn = dbus_connection_ref(connection); data->path = g_strdup(path); data->refcount = 1; data->introspect = g_strdup(DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE "<node></node>"); if (!dbus_connection_register_object_path(connection, path, &generic_table, data)) { g_free(data->introspect); g_free(data); return NULL; } invalidate_parent_data(connection, path); add_interface(data, DBUS_INTERFACE_INTROSPECTABLE, introspect_methods, NULL, NULL, data, NULL); /* Only root path export ObjectManager interface */ if (data->parent == NULL) add_interface(data, DBUS_INTERFACE_OBJECT_MANAGER, manager_methods, manager_signals, NULL, data, NULL); add_interface(data, DBUS_INTERFACE_PROPERTIES, properties_methods, properties_signals, NULL, data, NULL); return data; }
static void object_path_unref(DBusConnection *connection, const char *path) { struct generic_data *data = NULL; if (dbus_connection_get_object_path_data(connection, path, (void *) &data) == FALSE) return; if (data == NULL) return; data->refcount--; if (data->refcount > 0) return; remove_interface(data, DBUS_INTERFACE_INTROSPECTABLE); invalidate_parent_data(connection, path); dbus_connection_unregister_object_path(connection, path); }