diff options
Diffstat (limited to 'src/nm-activation-request.c')
-rw-r--r-- | src/nm-activation-request.c | 170 |
1 files changed, 103 insertions, 67 deletions
diff --git a/src/nm-activation-request.c b/src/nm-activation-request.c index 3f31007d23..82326e884c 100644 --- a/src/nm-activation-request.c +++ b/src/nm-activation-request.c @@ -42,6 +42,11 @@ G_DEFINE_TYPE (NMActRequest, nm_act_request, NM_TYPE_ACTIVE_CONNECTION) NM_TYPE_ACT_REQUEST, \ NMActRequestPrivate)) +typedef enum { + GET_SECRETS_INFO_TYPE_REQ, + GET_SECRETS_INFO_TYPE_IDLE, +} GetSecretsInfoType; + typedef struct { char *table; char *rule; @@ -99,17 +104,37 @@ check_connection_unmodified (NMActRequest *self, GError **error) return TRUE; } -typedef struct { +/*******************************************************************/ + +struct _NMActRequestGetSecretsCallId { NMActRequest *self; - guint32 call_id; NMActRequestSecretsFunc callback; gpointer callback_data; - GError *error; -} GetSecretsInfo; + GetSecretsInfoType type; + union { + struct { + guint32 id; + } req; + struct { + guint32 id; + GError *error; + } idle; + } t; +}; + +typedef struct _NMActRequestGetSecretsCallId GetSecretsInfo; + +static void +get_secrets_info_free (GetSecretsInfo *info) +{ + if (info->type == GET_SECRETS_INFO_TYPE_IDLE) + g_clear_error (&info->t.idle.error); + g_slice_free (GetSecretsInfo, info); +} static void get_secrets_cb (NMSettingsConnection *connection, - guint32 call_id, + guint32 req_id, const char *agent_username, const char *setting_name, GError *error, @@ -119,7 +144,7 @@ get_secrets_cb (NMSettingsConnection *connection, NMActRequestPrivate *priv = NM_ACT_REQUEST_GET_PRIVATE (info->self); gs_free_error GError *local = NULL; - g_return_if_fail (info->call_id == call_id); + g_return_if_fail (info->t.req.id == req_id); priv->secrets_calls = g_slist_remove (priv->secrets_calls, info); if (!error) { @@ -127,22 +152,19 @@ get_secrets_cb (NMSettingsConnection *connection, error = local; } - info->callback (info->self, call_id, connection, error, info->callback_data); - g_free (info); + info->callback (info->self, info, connection, error, info->callback_data); + get_secrets_info_free (info); } static gboolean -not_getting_secrets_cb (gpointer user_data) +get_secrets_idle_cb (GetSecretsInfo *info) { - GetSecretsInfo *info = user_data; - - info->callback (info->self, info->call_id, NULL, info->error, info->callback_data); - g_free (info); - + info->callback (info->self, info, NULL, info->t.idle.error, info->callback_data); + get_secrets_info_free (info); return FALSE; } -guint32 +NMActRequestGetSecretsCallId nm_act_request_get_secrets (NMActRequest *self, const char *setting_name, NMSecretAgentGetSecretsFlags flags, @@ -154,73 +176,89 @@ nm_act_request_get_secrets (NMActRequest *self, GetSecretsInfo *info; NMSettingsConnection *connection; const char *hints[2] = { hint, NULL }; + GError *local = NULL; + guint32 req_id; - g_return_val_if_fail (self, 0); g_return_val_if_fail (NM_IS_ACT_REQUEST (self), 0); priv = NM_ACT_REQUEST_GET_PRIVATE (self); connection = nm_act_request_get_settings_connection (self); - info = g_malloc0 (sizeof (GetSecretsInfo)); + info = g_slice_new (GetSecretsInfo); info->self = self; info->callback = callback; info->callback_data = callback_data; - if (!check_connection_unmodified (self, &info->error)) - return info->call_id = g_idle_add_full (G_PRIORITY_DEFAULT_IDLE, - not_getting_secrets_cb, - info, - (GDestroyNotify) not_getting_secrets_cb); + priv->secrets_calls = g_slist_append (priv->secrets_calls, info); + + if (!check_connection_unmodified (self, &local)) + goto schedule_dummy; if (nm_active_connection_get_user_requested (NM_ACTIVE_CONNECTION (self))) flags |= NM_SECRET_AGENT_GET_SECRETS_FLAG_USER_REQUESTED; - info->call_id = nm_settings_connection_get_secrets (connection, - nm_active_connection_get_subject (NM_ACTIVE_CONNECTION (self)), - setting_name, - flags, - hints, - get_secrets_cb, - info, - &info->error); - if (info->call_id > 0) - priv->secrets_calls = g_slist_append (priv->secrets_calls, info); + req_id = nm_settings_connection_get_secrets (connection, + nm_active_connection_get_subject (NM_ACTIVE_CONNECTION (self)), + setting_name, + flags, + hints, + get_secrets_cb, + info, + &local); + g_assert ((req_id > 0 && !local) || (req_id == 0 && local)); + if (req_id > 0) { + info->type = GET_SECRETS_INFO_TYPE_REQ; + info->t.req.id = req_id; + } else { +schedule_dummy: + info->type = GET_SECRETS_INFO_TYPE_IDLE; + g_propagate_error (&info->t.idle.error, local); + info->t.idle.id = g_idle_add ((GSourceFunc) get_secrets_idle_cb, info); + } + return info; +} + +static void +get_secrets_cancel (NMActRequest *self, GetSecretsInfo *info, gboolean shutdown) +{ + gs_free_error GError *error = NULL; + + if (info->type == GET_SECRETS_INFO_TYPE_REQ) + nm_settings_connection_cancel_secrets (nm_act_request_get_settings_connection (self), info->t.req.id); else - info->call_id = g_idle_add_full (G_PRIORITY_DEFAULT_IDLE, - not_getting_secrets_cb, - info, - (GDestroyNotify) not_getting_secrets_cb); + g_source_remove (info->t.idle.id); + + if (shutdown) { + /* hijack an error code. G_IO_ERROR_CANCELLED is only used synchronously + * when the user calls nm_act_request_cancel_secrets(). */ + g_set_error_literal (&error, G_IO_ERROR, G_IO_ERROR_NOT_CONNECTED, + "Disposing NMActRequest instance"); + } else { + g_set_error_literal (&error, G_IO_ERROR, G_IO_ERROR_CANCELLED, + "Request cancelled"); + } - return info->call_id; + info->callback (info->self, info, NULL, error, info->callback_data); + get_secrets_info_free (info); } void -nm_act_request_cancel_secrets (NMActRequest *self, guint32 call_id) +nm_act_request_cancel_secrets (NMActRequest *self, NMActRequestGetSecretsCallId call_id) { NMActRequestPrivate *priv; - NMSettingsConnection *connection; - GSList *iter; g_return_if_fail (self); g_return_if_fail (NM_IS_ACT_REQUEST (self)); - g_return_if_fail (call_id > 0); - - priv = NM_ACT_REQUEST_GET_PRIVATE (self); - connection = nm_act_request_get_settings_connection (self); - for (iter = priv->secrets_calls; iter; iter = g_slist_next (iter)) { - GetSecretsInfo *info = iter->data; + if (!call_id) + return; - /* Remove the matching info */ - if (info->call_id == call_id) { - priv->secrets_calls = g_slist_remove_link (priv->secrets_calls, iter); - g_slist_free (iter); + priv = NM_ACT_REQUEST_GET_PRIVATE (self); - nm_settings_connection_cancel_secrets (NM_SETTINGS_CONNECTION (connection), call_id); - g_free (info); - break; - } + if (g_slist_find (priv->secrets_calls, call_id)) { + priv->secrets_calls = g_slist_remove (priv->secrets_calls, call_id); + get_secrets_cancel (self, call_id, FALSE); } } @@ -479,9 +517,18 @@ nm_act_request_init (NMActRequest *req) static void dispose (GObject *object) { - NMActRequestPrivate *priv = NM_ACT_REQUEST_GET_PRIVATE (object); + NMActRequest *self = NM_ACT_REQUEST (object); + NMActRequestPrivate *priv = NM_ACT_REQUEST_GET_PRIVATE (self); NMSettingsConnection *connection; - GSList *iter; + + /* Kill any in-progress secrets requests */ + connection = nm_act_request_get_settings_connection (NM_ACT_REQUEST (object)); + while (priv->secrets_calls) { + GetSecretsInfo *info = priv->secrets_calls->data; + + priv->secrets_calls = g_slist_delete_link (priv->secrets_calls, priv->secrets_calls); + get_secrets_cancel (self, info, TRUE); + } /* Clear any share rules */ if (priv->share_rules) { @@ -489,17 +536,6 @@ dispose (GObject *object) clear_share_rules (NM_ACT_REQUEST (object)); } - /* Kill any in-progress secrets requests */ - connection = nm_act_request_get_settings_connection (NM_ACT_REQUEST (object)); - for (iter = priv->secrets_calls; connection && iter; iter = g_slist_next (iter)) { - GetSecretsInfo *info = iter->data; - - nm_settings_connection_cancel_secrets (NM_SETTINGS_CONNECTION (connection), info->call_id); - g_free (info); - } - g_slist_free (priv->secrets_calls); - priv->secrets_calls = NULL; - G_OBJECT_CLASS (nm_act_request_parent_class)->dispose (object); } |