示例#1
0
文件: vpn.c 项目: manjurajv/connman
static void remove_connection_reply(DBusPendingCall *call, void *user_data)
{
	DBusMessage *reply;
	DBusError error;

	if (dbus_pending_call_get_completed(call) == FALSE)
		return;

	DBG("");

	reply = dbus_pending_call_steal_reply(call);

	dbus_error_init(&error);

	if (dbus_set_error_from_message(&error, reply) == TRUE) {
		/*
		 * If the returned error is NotFound, it means that we
		 * have actually removed the provider in vpnd already.
		 */
		if (dbus_error_has_name(&error, CONNMAN_ERROR_INTERFACE
						".NotFound") == FALSE)
			connman_error("%s", error.message);

		dbus_error_free(&error);
	}

	dbus_message_unref(reply);

	dbus_pending_call_unref(call);
}
示例#2
0
void
services_action_cleanup(svc_action_t * op)
{
#if SUPPORT_DBUS
    if(op->opaque == NULL) {
        return;
    }

    if(op->opaque->timerid != 0) {
        crm_trace("Removing timer for call %s to %s", op->action, op->rsc);
        g_source_remove(op->opaque->timerid);
        op->opaque->timerid = 0;
    }

    if(op->opaque->pending) {
        crm_trace("Cleaning up pending dbus call %p %s for %s", op->opaque->pending, op->action, op->rsc);
        if(dbus_pending_call_get_completed(op->opaque->pending)) {
            crm_warn("Pending dbus call %s for %s did not complete", op->action, op->rsc);
        }
        dbus_pending_call_cancel(op->opaque->pending);
        dbus_pending_call_unref(op->opaque->pending);
        op->opaque->pending = NULL;
    }

    if (op->opaque->stderr_gsource) {
        mainloop_del_fd(op->opaque->stderr_gsource);
        op->opaque->stderr_gsource = NULL;
    }

    if (op->opaque->stdout_gsource) {
        mainloop_del_fd(op->opaque->stdout_gsource);
        op->opaque->stdout_gsource = NULL;
    }
#endif
}
示例#3
0
文件: vpn.c 项目: manjurajv/connman
static void disconnect_reply(DBusPendingCall *call, void *user_data)
{
	DBusMessage *reply;
	DBusError error;

	if (dbus_pending_call_get_completed(call) == FALSE)
		return;

	DBG("user %p", user_data);

	reply = dbus_pending_call_steal_reply(call);

	dbus_error_init(&error);

	if (dbus_set_error_from_message(&error, reply) == TRUE) {
		connman_error("%s", error.message);
		dbus_error_free(&error);
		goto done;
	}

done:
	dbus_message_unref(reply);

	dbus_pending_call_unref(call);
}
示例#4
0
static void finalize_call(DBusPendingCall *call)
{
	if (!dbus_pending_call_get_completed(call))
		dbus_pending_call_cancel(call);

	dbus_pending_call_unref(call);
}
示例#5
0
/*
 * Send the given method call and wait for a reply, spinning the main
 * context as necessary.
 */
DBusMessage *
test_main_context_call_and_wait (TestMainContext *ctx,
    DBusConnection *connection,
    DBusMessage *call,
    int timeout)
{
  DBusPendingCall *pc = NULL;
  DBusMessage *reply = NULL;

  if (!dbus_connection_send_with_reply (connection, call, &pc, timeout) ||
      pc == NULL)
    test_oom ();

  if (dbus_pending_call_get_completed (pc))
    test_pending_call_store_reply (pc, &reply);
  else if (!dbus_pending_call_set_notify (pc, test_pending_call_store_reply,
        &reply, NULL))
    test_oom ();

  while (reply == NULL)
    test_main_context_iterate (ctx, TRUE);

  dbus_clear_pending_call (&pc);
  return g_steal_pointer (&reply);
}
示例#6
0
static void pending_req_finalize(struct pending_req *req)
{
	if (!dbus_pending_call_get_completed(req->call))
		dbus_pending_call_cancel(req->call);

	dbus_pending_call_unref(req->call);
	g_free(req);
}
示例#7
0
static void set_property_cb(DBusPendingCall *pending, void *user_data)
{
	struct property_setting *set = user_data;
	struct connman_service *service;
	struct property_change *property;
	DBusMessage *reply;
	DBusError error;

	if (dbus_pending_call_get_completed(pending) == FALSE)
		return;

	if (set == NULL)
		return;

	service = set->data;

	service->call_modify[set->index] = NULL;

	if (service->property_set_error_cb == NULL)
		return;

	property = g_try_malloc0(sizeof(struct property_change));
	if (property == NULL)
		return;

	reply = dbus_pending_call_steal_reply(pending);
	if (reply == NULL)
		return;

	if (dbus_set_error_from_message(&error, reply) == FALSE)
		goto done;

	printf("SetProperty Error: %s\n", error.message);
	dbus_error_free(&error);

	if (service->property_set_error_cb == NULL)
		goto done;

	property = g_try_malloc0(sizeof(struct property_change));
	if (property == NULL)
		goto done;

	property->path = service->path;
	property->name = PROPERTY(set->index);
	property->error = -1;

	if (service->to_error[set->index] != 0)
		g_source_remove(service->to_error[set->index]);

	service->to_error[set->index] = g_timeout_add_full(
						G_PRIORITY_DEFAULT,
						0, property_changed_or_error,
						property, destroy_property);

done:
	dbus_message_unref(reply);
}
示例#8
0
static void nm_state_cb(DBusPendingCall *pending, void *user_data)
{
    struct connline_context *context = user_data;
    DBusMessage *reply = NULL;
    DBusMessageIter arg;
    struct nm_dbus *nm;
    unsigned int state;

    if (dbus_pending_call_get_completed(pending) == FALSE)
        return;

    nm = context->backend_data;
    nm->call = NULL;

    if (connline_dbus_setup_watch(context->dbus_cnx,
                                  NM_STATE_SIGNAL_MATCH_RULE,
                                  watch_nm_state, context) != 0)
        goto error;

    nm->state_watched = TRUE;

    reply = dbus_pending_call_steal_reply(pending);
    if (reply == NULL)
        goto error;

    if (dbus_message_iter_init(reply, &arg) == FALSE)
        goto error;

    if (connline_dbus_get_basic(&arg, DBUS_TYPE_UINT32, &state) != 0)
        goto error;

    if (is_connected(state) == TRUE) {
        if (nm_get_devices(context) != 0)
            goto error;
    } else
        __connline_call_disconnected_callback(context);

    nm->state = state;

    dbus_message_unref(reply);
    dbus_pending_call_unref(pending);

    return;

error:
    if (reply != NULL)
        dbus_message_unref(reply);

    dbus_pending_call_unref(pending);

    nm_backend_data_cleanup(context);
    __connline_call_error_callback(context, false);
}
示例#9
0
static gboolean trace_call(void *data)
{
	DBusPendingCall *call = data;

	if (dbus_pending_call_get_completed(call) == TRUE) {
		dbus_pending_call_unref(call);

		return FALSE;
	}

	return TRUE;
}
示例#10
0
static void wicd_autoconnect_cb(DBusPendingCall *pending, void *user_data)
{
	struct connline_context *context = user_data;
	struct wicd_dbus *wicd;

	if (dbus_pending_call_get_completed(pending) == FALSE)
		return;

	wicd = context->backend_data;
	wicd->call = NULL;

	dbus_pending_call_unref(pending);
}
示例#11
0
static void wicd_interface_cb(DBusPendingCall *pending, void *user_data)
{
	struct connline_context *context = user_data;
	char **properties = NULL;
	struct wicd_dbus *wicd;
	DBusMessageIter arg;
	DBusMessage *reply;
	const char *iface;

	if (dbus_pending_call_get_completed(pending) == FALSE)
		return;

	wicd = context->backend_data;
	wicd->call = NULL;

	reply = dbus_pending_call_steal_reply(pending);
	if (reply == NULL)
		goto error;

	if (dbus_message_iter_init(reply, &arg) == FALSE)
		goto error;

	if (connline_dbus_get_basic(&arg, DBUS_TYPE_STRING, &iface) != 0)
		goto error;

	properties = insert_into_property_list(properties, "bearer",
				connline_bearer_to_string(wicd->bearer));

	properties = insert_into_property_list(properties, "interface", iface);

	properties = insert_into_property_list(properties,
						"address", wicd->ip);

	if (properties != NULL)
		__connline_call_property_callback(context, properties);

	dbus_message_unref(reply);
	dbus_pending_call_unref(pending);

	return;

error:
	if (reply != NULL)
		dbus_message_unref(reply);

	dbus_pending_call_unref(pending);

	wicd_backend_data_cleanup(context);
	__connline_call_error_callback(context, false);
}
示例#12
0
static void
test_uae (Fixture *f,
          gconstpointer context)
{
    const Config *config = context;
    DBusMessage *m;
    DBusPendingCall *pc;
    DBusMessageIter args_iter;
    DBusMessageIter arr_iter;

    if (f->skip)
        return;

    m = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
                                      DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS, "UpdateActivationEnvironment");

    if (m == NULL)
        g_error ("OOM");

    dbus_message_iter_init_append (m, &args_iter);

    /* Append an empty a{ss} (string => string dictionary). */
    if (!dbus_message_iter_open_container (&args_iter, DBUS_TYPE_ARRAY,
                                           "{ss}", &arr_iter) ||
            !dbus_message_iter_close_container (&args_iter, &arr_iter))
        g_error ("OOM");

    if (!dbus_connection_send_with_reply (f->conn, m, &pc,
                                          DBUS_TIMEOUT_USE_DEFAULT) ||
            pc == NULL)
        g_error ("OOM");

    dbus_message_unref (m);
    m = NULL;

    if (dbus_pending_call_get_completed (pc))
        test_pending_call_store_reply (pc, &m);
    else if (!dbus_pending_call_set_notify (pc, test_pending_call_store_reply,
                                            &m, NULL))
        g_error ("OOM");

    while (m == NULL)
        test_main_context_iterate (f->ctx, TRUE);

    if (config->expect_success)
    {
        /* it succeeds */
        g_assert_cmpint (dbus_message_get_type (m), ==,
                         DBUS_MESSAGE_TYPE_METHOD_RETURN);
    }
示例#13
0
static void
test_echo (Fixture *f,
    gconstpointer context G_GNUC_UNUSED)
{
  guint count = 2000;
  guint sent;
  guint received = 0;
  double elapsed;

  if (g_test_perf ())
    count = 100000;

  add_echo_filter (f);

  g_test_timer_start ();

  for (sent = 0; sent < count; sent++)
    {
      DBusMessage *m = dbus_message_new_method_call (
          dbus_bus_get_unique_name (f->right_conn), "/",
          "com.example", "Spam");
      DBusPendingCall *pc;

      if (m == NULL)
        g_error ("OOM");

      if (!dbus_connection_send_with_reply (f->left_conn, m, &pc,
                                            DBUS_TIMEOUT_INFINITE) ||
          pc == NULL)
        g_error ("OOM");

      if (dbus_pending_call_get_completed (pc))
        pc_count (pc, &received);
      else if (!dbus_pending_call_set_notify (pc, pc_count, &received,
            NULL))
        g_error ("OOM");

      dbus_pending_call_unref (pc);
      dbus_message_unref (m);
    }

  while (received < count)
    g_main_context_iteration (NULL, TRUE);

  elapsed = g_test_timer_elapsed ();

  g_test_maximized_result (count / elapsed, "%u messages / %f seconds",
      count, elapsed);
}
示例#14
0
文件: dbus.c 项目: tradej/pacemaker
DBusPendingCall* pcmk_dbus_send(DBusMessage *msg, DBusConnection *connection,
                    void(*done)(DBusPendingCall *pending, void *user_data), void *user_data, int timeout)
{
    DBusError error;
    const char *method = NULL;
    DBusPendingCall* pending = NULL;

    dbus_error_init(&error);

    CRM_ASSERT(done);
    CRM_ASSERT(dbus_message_get_type (msg) == DBUS_MESSAGE_TYPE_METHOD_CALL);
    method = dbus_message_get_member (msg);


    if (timeout <= 0) {
        timeout = DBUS_TIMEOUT_USE_DEFAULT;
    }

    // send message and get a handle for a reply
    if (!dbus_connection_send_with_reply (connection, msg, &pending, timeout/* -1 is default timeout, aka. DBUS_TIMEOUT_USE_DEFAULT */)) {
        crm_err("Send with reply failed for %s", method);
        return NULL;

    } else if (pending == NULL) {
        crm_err("No pending call found for %s", method);
        return NULL;
    }

    crm_trace("DBus %s call sent", method);
    if (dbus_pending_call_get_completed(pending)) {
        crm_info("DBus %s call completed too soon", method);
        if(done) {
#if 0
        /* This sounds like a good idea, but allegedly it breaks things */
        done(pending, user_data);
        pending = NULL;
#else
        CRM_ASSERT(dbus_pending_call_set_notify(pending, done, user_data, NULL));
#endif
        }

    } else if(done) {
        CRM_ASSERT(dbus_pending_call_set_notify(pending, done, user_data, NULL));
    }
    return pending;
}
示例#15
0
文件: vpn.c 项目: manjurajv/connman
static void connect_reply(DBusPendingCall *call, void *user_data)
{
	DBusMessage *reply;
	DBusError error;
	struct connection_data *data = user_data;
	struct config_create_data *cb_data = data->cb_data;

	if (dbus_pending_call_get_completed(call) == FALSE)
		return;

	DBG("user_data %p path %s", user_data, cb_data ? cb_data->path : NULL);

	reply = dbus_pending_call_steal_reply(call);

	dbus_error_init(&error);

	if (dbus_set_error_from_message(&error, reply) == TRUE) {
		int err = errorstr2val(error.name);
		if (err != -EINPROGRESS) {
			connman_error("Connect reply: %s (%s)", error.message,
								error.name);
			dbus_error_free(&error);

			DBG("data %p cb_data %p", data, cb_data);
			if (cb_data != NULL) {
				cb_data->callback(cb_data->message, err, NULL);
				free_config_cb_data(cb_data);
				data->cb_data = NULL;
			}
			goto done;
		}
		dbus_error_free(&error);
	}

	/*
	 * The vpn connection is up when we get a "ready" state
	 * property so at this point we do nothing for the provider
	 * state.
	 */

done:
	dbus_message_unref(reply);

	dbus_pending_call_unref(call);
}
示例#16
0
static void
cb_pending(DBusPendingCall *pending, void *user_data)
{
  DBusMessage *msg;
  DBusError err;
  E_DBus_Pending_Call_Data *data = user_data;

  if (!dbus_pending_call_get_completed(pending))
  {
    INFO("E-dbus: NOT COMPLETED");
    free(data);
    dbus_pending_call_unref(pending);
    return;
  }

  dbus_error_init(&err);
  msg = dbus_pending_call_steal_reply(pending);
  if (!msg)
  {
    if (data->cb_return)
    {
      dbus_set_error(&err, "org.enlightenment.DBus.NoReply", "There was no reply to this method call.");
      data->cb_return(data->data, NULL, &err);
      dbus_error_free(&err);
    }
    return;
  }

  if (dbus_set_error_from_message(&err, msg))
  {
    if (data->cb_return)
      data->cb_return(data->data, NULL, &err);
    dbus_error_free(&err);
  }
  else
  {
    if (data->cb_return)
      data->cb_return(data->data, msg, &err);
  }

  dbus_message_unref(msg);
  dbus_pending_call_unref(pending);
}
示例#17
0
static void
cb_pending(DBusPendingCall *dbus_pending, void *user_data)
{
   Eldbus_Message *msg;
   Eldbus_Pending *pending = user_data;

   if (!dbus_pending_call_get_completed(dbus_pending))
     {
        INF("timeout to pending %p", pending);
        dbus_pending_call_cancel(dbus_pending);
        msg = eldbus_message_error_new(pending->msg_sent,
                                       ELDBUS_ERROR_PENDING_TIMEOUT,
                                       "This call was not completed in time.");
        eldbus_pending_dispatch(pending, msg);
        return;
     }

   msg = eldbus_message_new(EINA_FALSE);
   EINA_SAFETY_ON_NULL_RETURN(msg);
   msg->dbus_msg = dbus_pending_call_steal_reply(dbus_pending);
   if (!msg->dbus_msg)
     {
        EINA_SAFETY_ON_NULL_GOTO(pending->cb, cleanup);

        msg->dbus_msg = dbus_message_new_error(NULL,
                            "org.enlightenment.DBus.NoReply",
                            "There was no reply to this method call.");
        EINA_SAFETY_ON_NULL_GOTO(msg->dbus_msg, cleanup);
     }

   dbus_message_iter_init(msg->dbus_msg, &msg->iterator->dbus_iterator);
   eldbus_pending_dispatch(pending, msg);

   return;

cleanup:
   eldbus_message_unref(msg);
}
示例#18
0
static void register_agent_cb(DBusPendingCall *pending, void *user_data)
{
	DBusMessage *reply;

	if (dbus_pending_call_get_completed(pending) == FALSE)
		return;

	register_call = NULL;

	reply = dbus_pending_call_steal_reply(pending);
	if (reply == NULL)
		goto out;

	if (dbus_message_get_type(reply) == DBUS_MESSAGE_TYPE_ERROR) {
		g_dbus_unregister_interface(connection,
					AGENT_PATH, NEARD_AGENT_INTERFACE);
	} else
		agent_registered = TRUE;

	dbus_message_unref(reply);
out:
	dbus_pending_call_unref(pending);
}
MateKeyringResult
gkr_operation_block_and_unref (GkrOperation *op)
{
	DBusPendingCall *pending;
	g_return_val_if_fail (op, BROKEN);

	while ((int) gkr_operation_get_result (op) == INCOMPLETE) {
		if (op->pending) {
			/*
			 * DBus has strange behavior that can complete a pending call
			 * in another thread and somehow does this without calling our
			 * on_pending_call_notify. So guard against this brokenness.
			 */
			pending = op->pending;
			dbus_pending_call_block (pending);
			if (op->pending == pending) {
				g_return_val_if_fail (dbus_pending_call_get_completed (pending), BROKEN);
				on_pending_call_notify (pending, op);
				g_assert (op->pending != pending);
			}
		} else if (op->prompting) {
			dbus_connection_flush (op->conn);
			while (op->prompting && (int) gkr_operation_get_result (op) == INCOMPLETE) {
				if (!dbus_connection_read_write_dispatch (op->conn, 200))
					break;
			}
		} else {
			g_assert_not_reached ();
		}
	}

	/* Make sure we have run our callbacks if complete */
	if (!g_queue_is_empty (&op->callbacks))
		on_complete (op);

	return gkr_operation_unref_get_result (op);
}
示例#20
0
static void wicd_connection_status_cb(DBusPendingCall *pending, void *user_data)
{
	struct connline_context *context = user_data;
	DBusMessage *reply = NULL;
	struct wicd_dbus *wicd;
	DBusMessageIter arg;
	unsigned int state;
	char **ip = NULL;
	int len, ret;

	if (dbus_pending_call_get_completed(pending) == FALSE)
		return;

	wicd = context->backend_data;
	wicd->call = NULL;

	/* Watch connection status signals */
	if (connline_dbus_setup_watch(context->dbus_cnx,
				WICD_STATUS_MATCH_RULE,
				watch_wicd_status, context) != 0)
		goto error;

	wicd->status_watched = TRUE;

	reply = dbus_pending_call_steal_reply(pending);
	if (reply == NULL)
		goto error;

	if (dbus_message_iter_init(reply, &arg) == FALSE)
		goto error;

	if (connline_dbus_get_struct_entry_basic(&arg, 1,
					DBUS_TYPE_UINT32, &state) != 0)
		goto error;

	if (connline_dbus_get_struct_entry_array(&arg, 2,
					DBUS_TYPE_STRING, &len, &ip) != 0)
		goto error;

	if (is_connected(state) == TRUE) {
		ret = process_with_connection(context, state, ip, len);
		if (ret < 0)
			goto error;

		if (ret > 0)
			__connline_call_connected_callback(context);
		else
			__connline_call_disconnected_callback(context);

		goto out;
	}

	if (context->background_connection == FALSE) {
		if (wicd_autoconnect(context) != 0)
			goto error;
	} else
		__connline_call_disconnected_callback(context);

out:
	free(ip);

	dbus_message_unref(reply);
	dbus_pending_call_unref(pending);

	return;

error:
	free(ip);

	if (reply != NULL)
		dbus_message_unref(reply);

	dbus_pending_call_unref(pending);

	wicd_backend_data_cleanup(context);
	__connline_call_error_callback(context, false);
}
示例#21
0
static int dbus_selector_process_post_reply( DBusConnection* conn,
                                             DBusPendingCall** pendingargptr )
{
   DBusMessage* msg = NULL;
   DBusMessageIter args = {0};
   dbus_bool_t stat = FALSE;
   dbus_uint32_t level = 0;
   DBusPendingCall* pending = *pendingargptr;

   // block until we recieve a reply
   /* dbus_pending_call_block(pending); Note: this would block. use dispatch. */
    if ( ! dbus_pending_call_get_completed(pending) ) {
        dbus_pending_call_unref(pending);
        *pendingargptr = NULL;
        fprintf(stderr, " error Reply incomplete\n");
        exit(1);
    }
    /* timeout notes:
     *   it always reaches here, _completed() always return true.
     *   if destination name does not exist, it consumes 0 time and returns
     *           a string indicating the possible error.
     *   if destination replies late, it consumes full timeout duration and
     *           returns a string about the possible error.
     */

    /* can use cancel at top level. still safe to call cancel here: 
    dbus_pending_call_cancel(pending);
     */

   // get the reply message
   msg = dbus_pending_call_steal_reply(pending);
   if (NULL == msg) {
      fprintf(stderr, "Reply Null\n");
      exit(1);
   }
   // free the pending message handle
   dbus_pending_call_unref(pending);
    *pendingargptr = NULL;

    /* */
    int validerror = 0;
    { int mtype = dbus_message_get_type(msg);
        if ( mtype == DBUS_MESSAGE_TYPE_ERROR ) {
            fprintf(stderr, " error Reply with a valid error detected!\n");
            validerror = 1;
        } else if ( mtype != DBUS_MESSAGE_TYPE_METHOD_RETURN ) {
            fprintf(stderr, " error Reply not a valid return type!"
                    " received message type %d\n", mtype);
        }
    }

   // read the parameters
   if (!dbus_message_iter_init(msg, &args))
      fprintf(stderr, "Message has no arguments!\n");
   else if (DBUS_TYPE_BOOLEAN != dbus_message_iter_get_arg_type(&args))
    {
      fprintf(stderr, "Argument is not boolean!\n");
        if (DBUS_TYPE_STRING == dbus_message_iter_get_arg_type(&args) ) {
            fprintf(stderr, "Argument 1 is string!\n");
            if ( validerror ) {
                char * strval = (char*)"<init-unknown>";
                dbus_message_iter_get_basic(&args, &strval);
                if ( strval != NULL && strnlen(strval, 160) < 160 ) {
                    printf("RPC reply arg 0 is c%u %s\n", 160, strval);
                } else {
                    printf("RPC reply arg 0 error \n");
                }
            }
        } else if (DBUS_TYPE_UINT32 == dbus_message_iter_get_arg_type(&args) ) {
            fprintf(stderr, "Argument 1 is uint32!\n");
        } else {
            fprintf(stderr, "Argument 1 is not recognized!\n");
        }
    }
   else
      dbus_message_iter_get_basic(&args, &stat);

   if (!dbus_message_iter_next(&args))
      fprintf(stderr, "Message has too few arguments!\n");
   else if (DBUS_TYPE_UINT32 != dbus_message_iter_get_arg_type(&args))
      fprintf(stderr, "Argument is not int!\n");
   else
      dbus_message_iter_get_basic(&args, &level);

   printf("Got Reply: %d, %d\n", stat, level);

   // free reply
   dbus_message_unref(msg);

   return 0;
}
void
my_com_netsplit_Nih_Test_property_get_notify (DBusPendingCall *   pending_call,
                                              NihDBusPendingData *pending_data)
{
	DBusMessage *   reply;
	DBusMessageIter iter;
	DBusMessageIter variter;
	NihDBusMessage *message;
	DBusError       error;
	const char *    value_dbus;
	char *          value;

	nih_assert (pending_call != NULL);
	nih_assert (pending_data != NULL);

	nih_assert (dbus_pending_call_get_completed (pending_call));

	/* Steal the reply from the pending call. */
	reply = dbus_pending_call_steal_reply (pending_call);
	nih_assert (reply != NULL);

	/* Handle error replies */
	if (dbus_message_get_type (reply) == DBUS_MESSAGE_TYPE_ERROR) {
		message = NIH_MUST (nih_dbus_message_new (pending_data, pending_data->connection, reply));

		dbus_error_init (&error);
		dbus_set_error_from_message (&error, message->message);

		nih_error_push_context ();
		nih_dbus_error_raise (error.name, error.message);
		pending_data->error_handler (pending_data->data, message);
		nih_error_pop_context ();

		dbus_error_free (&error);
		nih_free (message);
		dbus_message_unref (reply);
		return;
	}

	nih_assert (dbus_message_get_type (reply) == DBUS_MESSAGE_TYPE_METHOD_RETURN);

	do {
		__label__ enomem;

		/* Create a message context for the reply, and iterate
		 * over and recurse into the arguments.
		 */
		message = nih_dbus_message_new (pending_data, pending_data->connection, reply);
		if (! message)
			goto enomem;

		dbus_message_iter_init (message->message, &iter);

		if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_VARIANT) {
			nih_error_push_context ();
			nih_error_raise (NIH_DBUS_INVALID_ARGS,
			                 _(NIH_DBUS_INVALID_ARGS_STR));
			pending_data->error_handler (pending_data->data, message);
			nih_error_pop_context ();

			nih_free (message);
			dbus_message_unref (reply);
			return;
		}

		dbus_message_iter_recurse (&iter, &variter);

		/* Demarshal a char * from the message */
		if (dbus_message_iter_get_arg_type (&variter) != DBUS_TYPE_STRING) {
			nih_error_push_context ();
			nih_error_raise (NIH_DBUS_INVALID_ARGS,
			                 _(NIH_DBUS_INVALID_ARGS_STR));
			pending_data->error_handler (pending_data->data, message);
			nih_error_pop_context ();

			nih_free (message);
			dbus_message_unref (reply);
			return;
		}

		dbus_message_iter_get_basic (&variter, &value_dbus);

		value = nih_strdup (message, value_dbus);
		if (! value) {
			nih_free (message);
			message = NULL;
			goto enomem;
		}

		dbus_message_iter_next (&variter);

		dbus_message_iter_next (&iter);

		if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_INVALID) {
			nih_error_push_context ();
			nih_error_raise (NIH_DBUS_INVALID_ARGS,
			                 _(NIH_DBUS_INVALID_ARGS_STR));
			pending_data->error_handler (pending_data->data, message);
			nih_error_pop_context ();

			nih_free (message);
			dbus_message_unref (reply);
			return;
		}

	enomem: __attribute__ ((unused));
	} while (! message);

	/* Call the handler function */
	nih_error_push_context ();
	((MyGetPropertyReply)pending_data->handler) (pending_data->data, message, value);
	nih_error_pop_context ();

	nih_free (message);
	dbus_message_unref (reply);
}
示例#23
0
文件: vpn.c 项目: manjurajv/connman
static void configuration_create_reply(DBusPendingCall *call, void *user_data)
{
	DBusMessage *reply;
	DBusError error;
	DBusMessageIter iter;
	const char *signature = DBUS_TYPE_OBJECT_PATH_AS_STRING;
	const char *path;
	char *ident;
	struct connection_data *data;
	struct config_create_data *cb_data = user_data;

	if (dbus_pending_call_get_completed(call) == FALSE)
		return;

	DBG("user %p", cb_data);

	reply = dbus_pending_call_steal_reply(call);

	dbus_error_init(&error);

	if (dbus_set_error_from_message(&error, reply) == TRUE) {
		connman_error("dbus error: %s", error.message);
		dbus_error_free(&error);
		goto done;
	}

	if (dbus_message_has_signature(reply, signature) == FALSE) {
		connman_error("vpn configuration signature \"%s\" does not "
						"match expected \"%s\"",
			dbus_message_get_signature(reply), signature);
		goto done;
	}

	if (dbus_message_iter_init(reply, &iter) == FALSE)
		goto done;

	dbus_message_iter_get_basic(&iter, &path);

	/*
	 * Then try to connect the VPN as expected by ConnectProvider API
	 */
	ident = get_ident(path);

	data = g_hash_table_lookup(vpn_connections, ident);
	if (data == NULL) {
		/*
		 * Someone removed the data. We cannot really continue.
		 */
		DBG("Pending data not found for %s, cannot continue!", ident);
	} else {
		data->call = NULL;
		data->connect_pending = TRUE;

		if (data->cb_data == NULL)
			data->cb_data = cb_data;
		else
			DBG("Connection callback data already in use!");

		/*
		 * Connection is created in add_connections() after
		 * we have received the ConnectionAdded signal.
		 */

		DBG("cb %p msg %p", data->cb_data,
			data->cb_data ? data->cb_data->message : NULL);
	}

done:
	dbus_message_unref(reply);

	dbus_pending_call_unref(call);
}
示例#24
0
    static void nm_device_all_cb(DBusPendingCall *pending, void *user_data)
{
    struct connline_context *context = user_data;
    char ip[INET_ADDRSTRLEN+1];
    char **properties = NULL;
    unsigned int dev_state;
    unsigned int dev_type;
    const char *interface;
    dbus_bool_t managed;
    DBusMessageIter arg;
    DBusMessage *reply;
    struct nm_dbus *nm;
    struct in_addr in4;
    unsigned int ip4;

    if (dbus_pending_call_get_completed(pending) == FALSE)
        return;

    nm = context->backend_data;
    nm->call = NULL;

    reply = dbus_pending_call_steal_reply(pending);
    if (reply == NULL)
        goto error;

    if (dbus_message_iter_init(reply, &arg) == FALSE)
        goto error;

    if (connline_dbus_get_dict_entry_basic(&arg, "Managed",
                                           DBUS_TYPE_BOOLEAN, &managed) < 0)
        goto error;

    if (managed == FALSE)
        goto next;

    if (connline_dbus_get_dict_entry_basic(&arg, "State",
                                           DBUS_TYPE_UINT32, &dev_state) < 0)
        goto error;

    if (dev_state != NM_DEVICE_STATE_ACTIVATED)
        goto next;

    if (connline_dbus_get_dict_entry_basic(&arg, "DeviceType",
                                           DBUS_TYPE_UINT32, &dev_type) < 0)
        goto error;

    nm->bearer = nm_device_type_to_bearer(dev_type);
    if (!(context->bearer_type == CONNLINE_BEARER_UNKNOWN ||
            nm->bearer & context->bearer_type))
        goto next;

    __connline_call_connected_callback(context);

    free_devices(nm);

    if (connline_dbus_get_dict_entry_basic(&arg, "Ip4Address",
                                           DBUS_TYPE_UINT32, &ip4) < 0)
        goto error;

    memset(ip, 0, INET_ADDRSTRLEN+1);

    in4.s_addr = ip4;

    if (inet_ntop(AF_INET, &in4, ip, INET_ADDRSTRLEN+1) == NULL)
        goto error;

    if (connline_dbus_get_dict_entry_basic(&arg, "IpInterface",
                                           DBUS_TYPE_STRING, &interface) < 0)
        goto error;

    properties = insert_into_property_list(properties, "bearer",
                                           connline_bearer_to_string(nm->bearer));

    properties = insert_into_property_list(properties,
                                           "interface", interface);

    properties = insert_into_property_list(properties, "address", ip);

    if (properties != NULL)
        __connline_call_property_callback(context, properties);

    goto out;

next:
    nm->current_device++;

    if (nm->current_device < nm->nb_devices) {
        if (nm_device_get_all(context) < 0)
            goto error;
    } else {
        free_devices(nm);

        __connline_call_disconnected_callback(context);
    }

out:
    dbus_message_unref(reply);
    dbus_pending_call_unref(pending);

    return;

error:
    if (reply != NULL)
        dbus_message_unref(reply);

    dbus_pending_call_unref(pending);

    nm_backend_data_cleanup(context);
    __connline_call_error_callback(context, false);
}
示例#25
0
static void nm_devices_cb(DBusPendingCall *pending, void *user_data)
{
    struct connline_context *context = user_data;
    char **devices_obj = NULL;
    DBusMessageIter arg;
    DBusMessage *reply;
    struct nm_dbus *nm;
    int len;
    int i;

    if (dbus_pending_call_get_completed(pending) == FALSE)
        return;

    nm = context->backend_data;
    nm->call = NULL;

    reply = dbus_pending_call_steal_reply(pending);
    if (reply == NULL)
        goto error;

    if (dbus_message_iter_init(reply, &arg) == FALSE)
        goto error;

    if (connline_dbus_get_array(&arg, DBUS_TYPE_OBJECT_PATH,
                                &len, &devices_obj) < 0)
        goto error;

    if (devices_obj != NULL && len > 0) {
        free_devices(nm);

        nm->nb_devices = len;
        nm->devices = calloc(nm->nb_devices, sizeof(char *));
        if (nm->devices == NULL)
            goto error;

        for (i = 0; i < len; i++) {
            nm->devices[i] = strdup(devices_obj[i]);
            if (nm->devices[i] == NULL) {
                nm->nb_devices = i;
                goto error;
            }
        }

        nm->current_device = 0;

        if (nm_device_get_all(context) < 0)
            goto error;

        free(devices_obj);
    }

    dbus_message_unref(reply);
    dbus_pending_call_unref(pending);

    return;

error:
    free(devices_obj);

    if (reply != NULL)
        dbus_message_unref(reply);

    dbus_pending_call_unref(pending);

    nm_backend_data_cleanup(context);
    __connline_call_error_callback(context, false);
}
示例#26
0
文件: vpn.c 项目: manjurajv/connman
static void get_connections_reply(DBusPendingCall *call, void *user_data)
{
	DBusMessage *reply;
	DBusError error;
	DBusMessageIter array, dict;
	const char *signature = DBUS_TYPE_ARRAY_AS_STRING
		DBUS_STRUCT_BEGIN_CHAR_AS_STRING
		DBUS_TYPE_OBJECT_PATH_AS_STRING
		DBUS_TYPE_ARRAY_AS_STRING
		DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
		DBUS_TYPE_STRING_AS_STRING
		DBUS_TYPE_VARIANT_AS_STRING
		DBUS_DICT_ENTRY_END_CHAR_AS_STRING
		DBUS_STRUCT_END_CHAR_AS_STRING;

	if (dbus_pending_call_get_completed(call) == FALSE)
		return;

	DBG("");

	reply = dbus_pending_call_steal_reply(call);

	dbus_error_init(&error);

	if (dbus_set_error_from_message(&error, reply) == TRUE) {
		connman_error("%s", error.message);
		dbus_error_free(&error);
		goto done;
	}

	if (dbus_message_has_signature(reply, signature) == FALSE) {
		connman_error("vpnd signature \"%s\" does not match "
							"expected \"%s\"",
			dbus_message_get_signature(reply), signature);
		goto done;
	}

	if (dbus_message_iter_init(reply, &array) == FALSE)
		goto done;

	dbus_message_iter_recurse(&array, &dict);

	while (dbus_message_iter_get_arg_type(&dict) == DBUS_TYPE_STRUCT) {
		DBusMessageIter value, properties;
		const char *path;

		dbus_message_iter_recurse(&dict, &value);
		dbus_message_iter_get_basic(&value, &path);

		dbus_message_iter_next(&value);
		dbus_message_iter_recurse(&value, &properties);

		add_connection(path, &properties, user_data);

		dbus_message_iter_next(&dict);
	}

done:
	dbus_message_unref(reply);

	dbus_pending_call_unref(call);
}
示例#27
0
/**
 * Call a method on a remote object
 */
void query(char* param , int altdest, int repeatmode)
{
   DBusMessage* msg;
   DBusMessageIter args;
   DBusConnection* conn;
   DBusError err;
   DBusPendingCall* pending;
   int ret;
   dbus_bool_t stat;
   dbus_uint32_t level;
    const char * dbname = "test.method.caller";
    int nrepeats = 0;
    int ii = 0;

   printf("Calling remote method with %s\n", param);

   // initialiset the errors
   dbus_error_init(&err);

   // connect to the system bus and check for errors
   conn = dbus_bus_get(DBUS_BUS_SESSION, &err);
   if (dbus_error_is_set(&err)) { 
      fprintf(stderr, "Connection Error (%s)\n", err.message); 
      dbus_error_free(&err);
   }
   if (NULL == conn) { 
      fprintf(stderr, "Connection null\n"); 
      exit(1); 
   }

   // request our name on the bus
   ret = dbus_bus_request_name(conn, dbname, DBUS_NAME_FLAG_REPLACE_EXISTING , &err);
   if (dbus_error_is_set(&err)) { 
      fprintf(stderr, "Name Error (%s)\n", err.message); 
      dbus_error_free(&err);
   }
   if (DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER != ret) { 
      fprintf(stderr, "Name not primary\n"); 
      exit(1);
   }
 if ( repeatmode == 2 ) nrepeats = tmnmax;
 for ( ii=0; ii<=nrepeats; ii++ ) {
   // create a new method call and check for errors
    struct timeval tmn1 = {0,0}; gettimeofday(&tmn1,NULL);
    printf("time before sending    %lu.%lu\n", tmn1.tv_sec, tmn1.tv_usec);
    if ( altdest == 0 ) {
   msg = dbus_message_new_method_call("test.method.server", // target for the method call
                                      "/test/method/Object", // object to call on
                                      "test.method.Type", // interface to call on
                                      "Method"); // method name
    } else {
        msg = dbus_message_new_method_call(
                                      "test.selector.server", // target for the method call
                                      "/test/method/Object", // object to call on
                                      "test.method.Type", // interface to call on
                                      "Method"); // method name
    }

   if (NULL == msg) { 
      fprintf(stderr, "Message Null\n");
      exit(1);
   }

   // append arguments
   dbus_message_iter_init_append(msg, &args);
   if (!dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &param)) {
      fprintf(stderr, "Out Of Memory!\n"); 
      exit(1);
   }
   
    struct timeval tmn2 = {0,0}; gettimeofday(&tmn2,NULL);
    printf("time before sending    %lu.%lu\n", tmn2.tv_sec, tmn2.tv_usec);
   // send message and get a handle for a reply
   if (!dbus_connection_send_with_reply (conn, msg, &pending, -1)) { // -1 is default timeout
      fprintf(stderr, "Out Of Memory!\n"); 
      exit(1);
   }
   if (NULL == pending) { 
      fprintf(stderr, "Pending Call Null\n"); 
      exit(1); 
   }
   dbus_connection_flush(conn);
   
   printf("Request Sent\n");
    struct timeval tmn3 = {0,0}; gettimeofday(&tmn3,NULL);
    printf("time after sending     %9lu.%06lu\n", tmn3.tv_sec, tmn3.tv_usec);
   
   // free message
   dbus_message_unref(msg);
   
   // block until we recieve a reply
   dbus_pending_call_block(pending);
    if ( ! dbus_pending_call_get_completed(pending) ) {
        dbus_pending_call_unref(pending);
        fprintf(stderr, " error Reply incomplete\n");
        exit(1);
    }
    /* timeout notes:
     *   it always reaches here, _completed() always return true.
     *   if destination name does not exist, it consumes 0 time and returns
     *           a string indicating the possible error.
     *   if destination replies late, it consumes full timeout duration and
     *           returns a string about the possible error.
     */
    struct timeval tmn4 = {0,0}; gettimeofday(&tmn4,NULL);
    printf("time after receiving   %lu.%lu\n", tmn4.tv_sec, tmn4.tv_usec);


   // get the reply message
   msg = dbus_pending_call_steal_reply(pending);
   if (NULL == msg) {
      fprintf(stderr, "Reply Null\n"); 
      exit(1); 
   }
   // free the pending message handle
   dbus_pending_call_unref(pending);

    /* */
    int validerror = 0;
    { int mtype = dbus_message_get_type(msg);
        if ( mtype == DBUS_MESSAGE_TYPE_ERROR ) {
            fprintf(stderr, " error Reply with a valid error detected!\n");
            validerror = 1;
        } else if ( mtype != DBUS_MESSAGE_TYPE_METHOD_RETURN ) {
            fprintf(stderr, " error Reply not a valid return type!"
                    " received message type %d\n", mtype);
        }
    }

   // read the parameters
   if (!dbus_message_iter_init(msg, &args))
      fprintf(stderr, "Message has no arguments!\n"); 
   else if (DBUS_TYPE_BOOLEAN != dbus_message_iter_get_arg_type(&args)) 
    {
      fprintf(stderr, "Argument is not boolean!\n"); 
        if (DBUS_TYPE_STRING == dbus_message_iter_get_arg_type(&args) ) {
            fprintf(stderr, "Argument 1 is string!\n");
            if ( validerror ) {
                char * strval = (char*)"<init-unknown>";
                dbus_message_iter_get_basic(&args, &strval);
                if ( strval != NULL && strnlen(strval, 160) < 160 ) {
                    printf("RPC reply arg 0 is c%u %s\n", 160, strval);
                } else {
                    printf("RPC reply arg 0 error \n");
                }
            }
        } else if (DBUS_TYPE_UINT32 == dbus_message_iter_get_arg_type(&args) ) {
            fprintf(stderr, "Argument 1 is uint32!\n");
        } else {
            fprintf(stderr, "Argument 1 is not recognized!\n");
        }
    }
   else
      dbus_message_iter_get_basic(&args, &stat);

   if (!dbus_message_iter_next(&args))
      fprintf(stderr, "Message has too few arguments!\n"); 
   else if (DBUS_TYPE_UINT32 != dbus_message_iter_get_arg_type(&args)) 
      fprintf(stderr, "Argument is not int!\n"); 
   else
      dbus_message_iter_get_basic(&args, &level);

   printf("Got Reply: %d, %d\n", stat, level);
   
   // free reply
   dbus_message_unref(msg);   

    struct timeval tmn9 = {0,0}; gettimeofday(&tmn9,NULL);
    printf("time after receiving   %lu.%lu\n", tmn9.tv_sec, tmn9.tv_usec);
    unsigned int tmncost = usdiff(&tmn1, &tmn9);
    printf("time consumed           %19s.%06u\n", "", tmncost);

    if ( tmnlistcnt < tmnmax ) {
        tmnlist[tmnlistcnt] = tmncost;
        tmnlistcnt ++;
    } else if ( tmnlistcnt == tmnmax ) {
        unsigned int tmnavg = 0;
        unsigned int i;
        for (i=0; i<tmnmax; i++) {
            tmnavg += tmnlist[i];
        }
        tmnavg /= tmnmax;
        tmnlistcnt ++;
        printf("time consumed           %9s.%06u\n", "", tmncost);
        printf("time consumed avg       %30s.%06u tmnmax %u\n", 
               "", tmnavg, tmnmax);
    }
 } /* for ii */

    dbus_bus_release_name(conn, dbname, &err);
    dbus_connection_unref(conn);
}
示例#28
0
int tool_cmd_scan(int argc, char *argv[])
{
	int ret = 0;
	int c;
	int timeout = DEFAULT_TIMEOUT_IN_SECONDS * 1000;
	DBusConnection* connection = NULL;
	DBusMessage *message = NULL;
	DBusMessage *reply = NULL;
	DBusPendingCall *pending = NULL;
	DBusError error;
	int32_t scan_period = 0;
	uint32_t channel_mask = 0;

	dbus_error_init(&error);

	while (1) {
		static struct option long_options[] = {
			{"help", no_argument, 0, 'h'},
			{"timeout", required_argument, 0, 't'},
			{"channel", required_argument, 0, 'c'},
			{0, 0, 0, 0}
		};

		int option_index = 0;
		c = getopt_long(argc, argv, "hc:t:", long_options,
				&option_index);

		if (c == -1)
			break;

		switch (c) {
		case 'h':
			print_arg_list_help(scan_option_list, argv[0],
					    scan_cmd_syntax);
			ret = ERRORCODE_HELP;
			goto bail;

		case 't':
			timeout = strtol(optarg, NULL, 0);
			break;

		case 'c':
			channel_mask = strtomask_uint32(optarg);
			break;
		}
	}

	if (optind < argc) {
		if (scan_period == 0) {
			scan_period = strtol(argv[optind], NULL, 0);
			optind++;
		}
	}

	if (optind < argc) {
			fprintf(stderr,
			        "%s: error: Unexpected extra argument: \"%s\"\n",
			argv[0], argv[optind]);
			ret = ERRORCODE_BADARG;
			goto bail;
		}

	if (gInterfaceName[0] == 0) {
		fprintf(stderr,
		        "%s: error: No WPAN interface set (use the `cd` command, or the `-I` argument for `wpanctl`).\n",
		        argv[0]);
		ret = ERRORCODE_BADARG;
		goto bail;
	}

	connection = dbus_bus_get(DBUS_BUS_STARTER, &error);

	if (!connection) {
		dbus_error_free(&error);
		dbus_error_init(&error);
		connection = dbus_bus_get(DBUS_BUS_SYSTEM, &error);
	}

	require_string(connection != NULL, bail, error.message);

	dbus_bus_add_match(connection, gDBusObjectManagerMatchString, &error);

	require_string(error.name == NULL, bail, error.message);

	dbus_connection_add_filter(connection, &dbus_beacon_handler, NULL, NULL);

	{
		char path[DBUS_MAXIMUM_NAME_LENGTH+1];
		char interface_dbus_name[DBUS_MAXIMUM_NAME_LENGTH+1];
		DBusMessageIter iter;
		ret = lookup_dbus_name_from_interface(interface_dbus_name, gInterfaceName);

		if (ret != 0) {
			goto bail;
		}

		snprintf(
			path,
			sizeof(path),
			"%s/%s",
			WPANTUND_DBUS_PATH,
			gInterfaceName
		);

		message = dbus_message_new_method_call(
			interface_dbus_name,
			path,
			WPANTUND_DBUS_APIv1_INTERFACE,
			WPANTUND_IF_CMD_NET_SCAN_START
		);

		dbus_message_append_args(
			message,
			DBUS_TYPE_UINT32, &channel_mask,
			DBUS_TYPE_INVALID
		);

		print_scan_header();

		gScannedNetworkCount = 0;

		if(!dbus_connection_send_with_reply(
		    connection,
		    message,
			&pending,
		    timeout
	    )) {
			fprintf(stderr, "%s: error: IPC failure\n", argv[0]);
			ret = ERRORCODE_UNKNOWN;
			goto bail;
		}

		while ((dbus_connection_get_dispatch_status(connection) == DBUS_DISPATCH_DATA_REMAINS)
			|| dbus_connection_has_messages_to_send(connection)
			|| !dbus_pending_call_get_completed(pending)
		) {
			dbus_connection_read_write_dispatch(connection, 5000 /*ms*/);
		}

		reply = dbus_pending_call_steal_reply(pending);

		require(reply!=NULL, bail);


		dbus_message_iter_init(reply, &iter);

		if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_INT32) {
			fprintf(stderr, "%s: error: Server returned a bad response ('%c')\n",
			        argv[0], dbus_message_iter_get_arg_type(&iter));
			ret = ERRORCODE_UNKNOWN;
			goto bail;
		}

		// Get return code
		dbus_message_iter_get_basic(&iter, &ret);

		if (ret) {
			fprintf(stderr, "%s failed with error %d. %s\n", argv[0], ret, wpantund_status_to_cstr(ret));
			print_error_diagnosis(ret);
			goto bail;
		}
	}


bail:

	if (reply) {
		dbus_message_unref(reply);
	}

	if (pending != NULL) {
		dbus_pending_call_unref(pending);
	}

	if (message) {
		dbus_message_unref(message);
	}

	if (connection) {
		dbus_bus_remove_match(connection, gDBusObjectManagerMatchString, NULL);
		dbus_connection_remove_filter(connection,&dbus_beacon_handler,NULL);
		dbus_connection_unref(connection);
	}

	dbus_error_free(&error);

	return ret;
}
void
my_com_netsplit_Nih_Test_get_all_notify (DBusPendingCall *   pending_call,
                                         NihDBusPendingData *pending_data)
{
	DBusMessage *   reply;
	DBusMessageIter iter;
	DBusMessageIter arrayiter;
	DBusMessageIter dictiter;
	DBusMessageIter variter;
	NihDBusMessage *message;
	DBusError       error;
	const char *    property;
	MyProperties *  properties;
	size_t          property_count;
	char *          name;
	const char *    name_dbus;
	uint32_t        size;

	nih_assert (pending_call != NULL);
	nih_assert (pending_data != NULL);

	nih_assert (dbus_pending_call_get_completed (pending_call));

	/* Steal the reply from the pending call. */
	reply = dbus_pending_call_steal_reply (pending_call);
	nih_assert (reply != NULL);

	/* Handle error replies */
	if (dbus_message_get_type (reply) == DBUS_MESSAGE_TYPE_ERROR) {
		message = NIH_MUST (nih_dbus_message_new (pending_data, pending_data->connection, reply));

		dbus_error_init (&error);
		dbus_set_error_from_message (&error, message->message);

		nih_error_push_context ();
		nih_dbus_error_raise (error.name, error.message);
		pending_data->error_handler (pending_data->data, message);
		nih_error_pop_context ();

		dbus_error_free (&error);
		nih_free (message);
		dbus_message_unref (reply);
		return;
	}

	nih_assert (dbus_message_get_type (reply) == DBUS_MESSAGE_TYPE_METHOD_RETURN);

	/* Create a message context for the reply, and iterate
	 * over and recurse into the arguments.
	 */
	message = NIH_MUST (nih_dbus_message_new (pending_data, pending_data->connection, reply));

	/* Iterate the method arguments, recursing into the array */
	dbus_message_iter_init (reply, &iter);

	if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_ARRAY) {
		nih_error_push_context ();
		nih_error_raise (NIH_DBUS_INVALID_ARGS,
		                 _(NIH_DBUS_INVALID_ARGS_STR));
		pending_data->error_handler (pending_data->data, message);
		nih_error_pop_context ();

		nih_free (message);
		dbus_message_unref (reply);
		return;
	}

	properties = NIH_MUST (nih_new (message, MyProperties));
	property_count = 0;

	dbus_message_iter_recurse (&iter, &arrayiter);

	while (dbus_message_iter_get_arg_type (&arrayiter) != DBUS_TYPE_INVALID) {
		__label__ enomem;

		if (dbus_message_iter_get_arg_type (&arrayiter) != DBUS_TYPE_DICT_ENTRY) {
			nih_error_push_context ();
			nih_error_raise (NIH_DBUS_INVALID_ARGS,
			                 _(NIH_DBUS_INVALID_ARGS_STR));
			pending_data->error_handler (pending_data->data, message);
			nih_error_pop_context ();

			nih_free (message);
			dbus_message_unref (reply);
			return;
		}

		dbus_message_iter_recurse (&arrayiter, &dictiter);

		if (dbus_message_iter_get_arg_type (&dictiter) != DBUS_TYPE_STRING) {
			nih_error_push_context ();
			nih_error_raise (NIH_DBUS_INVALID_ARGS,
			                 _(NIH_DBUS_INVALID_ARGS_STR));
			pending_data->error_handler (pending_data->data, message);
			nih_error_pop_context ();

			nih_free (message);
			dbus_message_unref (reply);
			return;
		}

		dbus_message_iter_get_basic (&dictiter, &property);

		dbus_message_iter_next (&dictiter);

		if (dbus_message_iter_get_arg_type (&dictiter) != DBUS_TYPE_VARIANT) {
			nih_error_push_context ();
			nih_error_raise (NIH_DBUS_INVALID_ARGS,
			                 _(NIH_DBUS_INVALID_ARGS_STR));
			pending_data->error_handler (pending_data->data, message);
			nih_error_pop_context ();

			nih_free (message);
			dbus_message_unref (reply);
			return;
		}

		dbus_message_iter_recurse (&dictiter, &variter);

		if (! strcmp (property, "name")) {
			/* Demarshal a char * from the message */
			if (dbus_message_iter_get_arg_type (&variter) != DBUS_TYPE_STRING) {
				nih_error_push_context ();
				nih_error_raise (NIH_DBUS_INVALID_ARGS,
				                 _(NIH_DBUS_INVALID_ARGS_STR));
				pending_data->error_handler (pending_data->data, message);
				nih_error_pop_context ();

				nih_free (message);
				dbus_message_unref (reply);
				return;
			}

			dbus_message_iter_get_basic (&variter, &name_dbus);

			name = nih_strdup (properties, name_dbus);
			if (! name) {
				goto enomem;
			}

			dbus_message_iter_next (&variter);

			properties->name = name;

			nih_assert (++property_count);
		}

		if (! strcmp (property, "size")) {
			/* Demarshal a uint32_t from the message */
			if (dbus_message_iter_get_arg_type (&variter) != DBUS_TYPE_UINT32) {
				nih_error_push_context ();
				nih_error_raise (NIH_DBUS_INVALID_ARGS,
				                 _(NIH_DBUS_INVALID_ARGS_STR));
				pending_data->error_handler (pending_data->data, message);
				nih_error_pop_context ();

				nih_free (message);
				dbus_message_unref (reply);
				return;
			}

			dbus_message_iter_get_basic (&variter, &size);

			dbus_message_iter_next (&variter);

			properties->size = size;

			nih_assert (++property_count);
		}

		dbus_message_iter_next (&dictiter);

		if (dbus_message_iter_get_arg_type (&dictiter) != DBUS_TYPE_INVALID) {
			nih_error_push_context ();
			nih_error_raise (NIH_DBUS_INVALID_ARGS,
			                 _(NIH_DBUS_INVALID_ARGS_STR));
			pending_data->error_handler (pending_data->data, message);
			nih_error_pop_context ();

			nih_free (message);
			dbus_message_unref (reply);
			return;
		}

		dbus_message_iter_next (&arrayiter);
	enomem: __attribute__ ((unused));
	}

	dbus_message_iter_next (&iter);

	if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_INVALID) {
		nih_error_push_context ();
		nih_error_raise (NIH_DBUS_INVALID_ARGS,
		                 _(NIH_DBUS_INVALID_ARGS_STR));
		pending_data->error_handler (pending_data->data, message);
		nih_error_pop_context ();

		nih_free (message);
		dbus_message_unref (reply);
		return;
	}

	if (property_count < 2) {
		nih_error_push_context ();
		nih_error_raise (NIH_DBUS_INVALID_ARGS,
		                 _(NIH_DBUS_INVALID_ARGS_STR));
		pending_data->error_handler (pending_data->data, message);
		nih_error_pop_context ();

		nih_free (message);
		dbus_message_unref (reply);
		return;
	}

	/* Call the handler function */
	nih_error_push_context ();
	((MyGetAllReply)pending_data->handler) (pending_data->data, message, properties);
	nih_error_pop_context ();

	nih_free (message);
	dbus_message_unref (reply);
}