static void vpn_dir_changed (GFileMonitor *monitor, GFile *file, GFile *other_file, GFileMonitorEvent event_type, gpointer user_data) { NMVpnManager *self = NM_VPN_MANAGER (user_data); NMVpnManagerPrivate *priv = NM_VPN_MANAGER_GET_PRIVATE (self); NMVpnPluginInfo *plugin_info; gs_free char *path = NULL; GError *error = NULL; path = g_file_get_path (file); if (!nm_vpn_plugin_info_validate_filename (path)) return; switch (event_type) { case G_FILE_MONITOR_EVENT_DELETED: plugin_info = nm_vpn_plugin_info_list_find_by_filename (priv->plugins, path); if (!plugin_info) break; nm_log_dbg (LOGD_VPN, "vpn: service file %s deleted", path); nm_vpn_plugin_info_list_remove (&priv->plugins, plugin_info); break; case G_FILE_MONITOR_EVENT_CREATED: case G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT: plugin_info = nm_vpn_plugin_info_list_find_by_filename (priv->plugins, path); if (plugin_info) { /* we don't support reloading an existing plugin. You can only remove the file * and re-add it. By reloading we want to support the use case of installing * a VPN plugin after NM started. No need to burden ourself with a complete * reload. */ break; } if (!_nm_vpn_plugin_info_check_file (path, TRUE, TRUE, 0, NULL, NULL, &error)) { nm_log_dbg (LOGD_VPN, "vpn: ignore changed service file %s (%s)", path, error->message); g_clear_error (&error); break; } plugin_info = nm_vpn_plugin_info_new_from_file (path, &error); if (!plugin_info) { nm_log_dbg (LOGD_VPN, "vpn: ignore changed service file %s due to invalid content (%s)", path, error->message); g_clear_error (&error); break; } nm_log_dbg (LOGD_VPN, "vpn: service file %s created or modified", path); try_add_plugin (self, plugin_info); g_object_unref (plugin_info); break; default: nm_log_dbg (LOGD_VPN, "vpn: service file %s change event %d", path, event_type); break; } }
NMVPNManager * nm_vpn_manager_get (void) { static NMVPNManager *singleton = NULL; if (!singleton) singleton = NM_VPN_MANAGER (g_object_new (NM_TYPE_VPN_MANAGER, NULL)); else g_object_ref (singleton); g_assert (singleton); return singleton; }
static void vpn_dir_changed (GFileMonitor *monitor, GFile *file, GFile *other_file, GFileMonitorEvent event_type, gpointer user_data) { NMVPNManager *self = NM_VPN_MANAGER (user_data); NMVPNManagerPrivate *priv = NM_VPN_MANAGER_GET_PRIVATE (self); NMVPNService *service; char *path; path = g_file_get_path (file); if (!g_str_has_suffix (path, ".name")) { g_free (path); return; } switch (event_type) { case G_FILE_MONITOR_EVENT_DELETED: nm_log_dbg (LOGD_VPN, "service file %s deleted", path); service = get_service_by_namefile (self, path); if (service) { const char *service_name = nm_vpn_service_get_dbus_service (service); /* Stop active VPN connections and destroy the service */ nm_vpn_service_connections_stop (service, TRUE, NM_VPN_CONNECTION_STATE_REASON_SERVICE_STOPPED); nm_log_info (LOGD_VPN, "VPN: unloaded %s", service_name, service); g_hash_table_remove (priv->services, service_name); } break; case G_FILE_MONITOR_EVENT_CREATED: case G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT: nm_log_dbg (LOGD_VPN, "service file %s created or modified", path); try_add_service (self, path); break; default: nm_log_dbg (LOGD_VPN, "service file %s change event %d", path, event_type); break; } g_free (path); }
static void connection_vpn_state_changed (NMVPNConnection *connection, NMVPNConnectionState state, NMVPNConnectionStateReason reason, gpointer user_data) { NMVPNManager *manager = NM_VPN_MANAGER (user_data); switch (state) { case NM_VPN_CONNECTION_STATE_ACTIVATED: g_signal_emit (manager, signals[CONNECTION_ACTIVATED], 0, connection); break; case NM_VPN_CONNECTION_STATE_FAILED: case NM_VPN_CONNECTION_STATE_DISCONNECTED: g_signal_emit (manager, signals[CONNECTION_DEACTIVATED], 0, connection, state, reason); break; default: break; } }
static void dispose (GObject *object) { NMVpnManagerPrivate *priv = NM_VPN_MANAGER_GET_PRIVATE (object); if (priv->monitor) { if (priv->monitor_id) g_signal_handler_disconnect (priv->monitor, priv->monitor_id); g_file_monitor_cancel (priv->monitor); g_clear_object (&priv->monitor); } if (priv->services) { stop_all_services (NM_VPN_MANAGER (object)); g_hash_table_destroy (priv->services); priv->services = NULL; } G_OBJECT_CLASS (nm_vpn_manager_parent_class)->dispose (object); }