summaryrefslogtreecommitdiff
path: root/src/nm-activation-request.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/nm-activation-request.c')
-rw-r--r--src/nm-activation-request.c170
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);
}