Exemple #1
0
void DBusDestroy(void* arg) {
    FcitxDBus* dbusmodule = (FcitxDBus*)arg;
    if (dbusmodule->conn) {
        dbus_bus_release_name(dbusmodule->conn, dbusmodule->serviceName, NULL);
    }
    if (dbusmodule->privconn) {
        dbus_bus_release_name(dbusmodule->privconn, dbusmodule->serviceName, NULL);
    }
    DBusKill(&dbusmodule->daemon);
    free(dbusmodule->serviceName);
    free(dbusmodule);
}
Exemple #2
0
/*!
 * \brief Carry out all actions to finalise the D-Bus connection.
 */
void
pcb_dbus_finish (void)
{
  DBusError err;

  // Initialise the error variable
  dbus_error_init (&err);

  // TODO: Could emit a "goodbye" signal here?

  dbus_connection_flush (pcb_dbus_conn);

  dbus_connection_unregister_object_path (pcb_dbus_conn,
					  PCB_DBUS_OBJECT_PATH);

  dbus_bus_release_name (pcb_dbus_conn, PCB_DBUS_CANONICAL_NAME, &err);

  dbus_error_free (&err);

  pcb_dbus_connection_finish_with_mainloop (pcb_dbus_conn);

  dbus_connection_close (pcb_dbus_conn);
  dbus_connection_unref (pcb_dbus_conn);

  // Call DBus shutdown. This doesn't work with shared connections,
  // only private ones (like we took out earlier).
  // If any future module / plugin to PCB wants to use DBus too,
  // we must remove this call. DBus will get shut-down when the app exits.
  dbus_shutdown ();
}
static void usb_moded_app_sync_release_name(void)
{
  /* Drop the service name - if we have it */
  if( dbus_connection_ses && dbus_connection_name )
  {
    DBusError error = DBUS_ERROR_INIT;
    int ret = dbus_bus_release_name(dbus_connection_ses, USB_MODE_SERVICE, &error);

    switch( ret )
    {
    case DBUS_RELEASE_NAME_REPLY_RELEASED:
      // as expected
      log_debug("released name: %s", USB_MODE_SERVICE);
      break;
    case DBUS_RELEASE_NAME_REPLY_NON_EXISTENT:
      // weird, but since nobody owns the name ...
      log_debug("nonexisting name: %s", USB_MODE_SERVICE);
      break;
    case DBUS_RELEASE_NAME_REPLY_NOT_OWNER:
      log_warning("somebody else owns: %s", USB_MODE_SERVICE);
    }

    if( dbus_error_is_set(&error) )
    {
      log_debug("DBUS ERROR: %s, %s \n", error.name, error.message);
      dbus_error_free(&error);
    }
  }

  dbus_connection_name = FALSE;
}
Exemple #4
0
gboolean    parole_dbus_release_name        (const gchar *name)
{
    DBusConnection *bus;
    DBusError error;
    int ret;
    
    bus = parole_session_bus_get ();
    
    dbus_error_init (&error);
    
    ret =
        dbus_bus_release_name (bus,
                               name,
                               &error);

    dbus_connection_unref (bus);
    
    if ( dbus_error_is_set (&error) )
    {
        g_warning ("Error: %s\n", error.message);
        dbus_error_free (&error);
        return FALSE;
    }

    return ret == -1 ? FALSE : TRUE;
}
Exemple #5
0
void asdbus_shutdown ()
{
	if (ASDBus.session_conn)
		dbus_bus_release_name (ASDBus.session_conn,
													 AFTERSTEP_DBUS_SERVICE_NAME, NULL);

	if (ASDBus.session_conn || ASDBus.system_conn)
		dbus_shutdown ();
}
Exemple #6
0
void FcitxNotificationItemDisable(FcitxNotificationItem* notificationitem)
{
    notificationitem->callback = NULL;
    notificationitem->data = NULL;

    if (notificationitem->serviceName) {
        dbus_bus_release_name(notificationitem->conn, notificationitem->serviceName, NULL);
        free(notificationitem->serviceName);
        notificationitem->serviceName = NULL;
    }
}
Exemple #7
0
/**
 * Clean up the dbus connections on exit
 *
 */
void usb_moded_dbus_cleanup(void)
{
  /* clean up system bus connection */
  if (dbus_connection_sys != NULL) 
  {
	  dbus_bus_release_name(dbus_connection_sys, USB_MODE_SERVICE, NULL);
	  dbus_connection_remove_filter(dbus_connection_sys, msg_handler, NULL);
	  dbus_connection_unref(dbus_connection_sys);
          dbus_connection_sys = NULL;
  }
}
static void
_cs_dbus_release(void)
{
	DBusError err;

	if (!db)
		return;

	dbus_error_init(&err);
	dbus_bus_release_name(db, DBUS_CS_NAME, &err);
	dbus_error_free(&err);
	dbus_connection_unref(db);
	db = NULL;
}
Exemple #9
0
void
pre_disconnect_hook(void)
{
    DBusError error;

    dbus_error_init(&error);
    dbus_connection_unregister_object_path(connection_data->connection,
                                           connection_data->busobject);
    dbus_bus_remove_match(connection_data->connection, MATCH_RULE,
                          &error);
    dbus_bus_release_name(connection_data->connection,
                          connection_data->busname, &error);
    dbus_error_free(&error);
}
Exemple #10
0
void pcb_dbus_finish( void )
{
  DBusError err;
  dbus_error_init( err.name );
  dbus_connection_flush( &pcb_dbus_conn );
  dbus_connection_unregister_object_path( &pcb_dbus_conn, "/org/seul/geda/pcb" );
  dbus_bus_release_name( &pcb_dbus_conn, "org.seul.geda.pcb", err.name );
  dbus_error_free( err.name );
  pcb_dbus_connection_finish_with_mainloop( &pcb_dbus_conn );
  dbus_connection_close( &pcb_dbus_conn );
  dbus_connection_unref( &pcb_dbus_conn );
  dbus_shutdown( );
  return;
}
Exemple #11
0
static void
connect_hook(DBusConnection *connection, void *data)
{
    DBusError error;
    DBusObjectPathVTable vtable = { .message_function = message_handler, };
    struct connection_info *info = data;

    info->connection = connection;

    dbus_error_init(&error);

    dbus_bus_request_name(info->connection, info->busname, 0, &error);
    if (dbus_error_is_set(&error)) {
        ErrorF("[config/dbus] couldn't take over org.x.config: %s (%s)\n",
               error.name, error.message);
        goto err_start;
    }

    /* blocks until we get a reply. */
    dbus_bus_add_match(info->connection, MATCH_RULE, &error);
    if (dbus_error_is_set(&error)) {
        ErrorF("[config/dbus] couldn't add match: %s (%s)\n", error.name,
               error.message);
        goto err_name;
    }

    if (!dbus_connection_register_object_path(info->connection,
                                              info->busobject, &vtable,
                                              info)) {
        ErrorF("[config/dbus] couldn't register object path\n");
        goto err_match;
    }

    DebugF("[dbus] registered %s, %s\n", info->busname, info->busobject);

    dbus_error_free(&error);

    return;

err_match:
    dbus_bus_remove_match(info->connection, MATCH_RULE, &error);
err_name:
    dbus_bus_release_name(info->connection, info->busname, &error);
err_start:
    dbus_error_free(&error);

    reset_info(info);
}
Exemple #12
0
/**
 * wrapper_unexport:
 * @comp: the extension to unexport.
 *
 * De-registers the given component from D-Bus, frees data structures for
 * which it's responsible.
 */
static void wrapper_unexport(gpointer comp)
{
	DBusError err;
	GList *node;
	ExportedComponent *ecomp;

	ecomp = NULL;
	for (node = Exports; node; node = node->next) {
		ecomp = (ExportedComponent *)node->data;
		if (ecomp->comp == comp)
			break;
	}
	if (!ecomp)
		return;

	dbus_connection_unregister_object_path(Session_bus, ecomp->object_path);

	dbus_error_init(&err);
	switch (dbus_bus_release_name(Session_bus, ecomp->service_name, &err)){
	case DBUS_RELEASE_NAME_REPLY_NOT_OWNER:
	case DBUS_RELEASE_NAME_REPLY_NON_EXISTENT:
		g_warning("dbus_bus_release_name() failed, either "
			  "'%s' is non-existent, or we are not the owners",
			  ecomp->service_name);
		break;
	default:
		if (dbus_error_is_set(&err)) {
			g_warning("dbus_bus_release_name() an error was set: "
				  "%s", err.message);
			dbus_error_free(&err);
		}
	}
	disconnect_sighandlers(ecomp);
	g_free(ecomp->service_name);
	g_free(ecomp->object_path);
	ecomp->object_path = NULL;
	g_free(ecomp->name);
	g_free(ecomp->uuid);
	g_free(ecomp);
	Exports = g_list_delete_link(Exports, node);
	extension_deregister(comp);
}
Exemple #13
0
/**
 * Destroy D-Bus connection.
 */
void
cdbus_destroy(session_t *ps) {
  if (ps->dbus_conn) {
    // Release DBus name firstly
    if (ps->dbus_service) {
      DBusError err = { };
      dbus_error_init(&err);

      dbus_bus_release_name(ps->dbus_conn, ps->dbus_service, &err);
      if (dbus_error_is_set(&err)) {
        printf_errf("(): Failed to release DBus name (%s).",
            err.message);
        dbus_error_free(&err);
      }
    }

    // Close and unref the connection
    dbus_connection_close(ps->dbus_conn);
    dbus_connection_unref(ps->dbus_conn);
  }
}
Exemple #14
0
void rd_release(
	rd_device *d) {

	if (!d)
		return;

	assert(d->ref > 0);

	if (--d->ref > 0)
		return;


	if (d->filtering)
		dbus_connection_remove_filter(
			d->connection,
			filter_handler,
			d);

	if (d->registered)
		dbus_connection_unregister_object_path(
			d->connection,
			d->object_path);

	if (d->owning)
		dbus_bus_release_name(
			d->connection,
			d->service_name,
			NULL);

	free(d->device_name);
	free(d->application_name);
	free(d->application_device_name);
	free(d->service_name);
	free(d->object_path);

	if (d->connection)
		dbus_connection_unref(d->connection);

	free(d);
}
Exemple #15
0
gboolean releaseName(gpointer my_data) {

	DBusError *error;
	int retval;

	error = NULL;
	
	/* Release the name we got earlier (That is, if we got one) */
	retval =  dbus_bus_release_name (con, "org.DBusTest.SignalTest", error);

	switch(retval) {
		case DBUS_RELEASE_NAME_REPLY_RELEASED:
			g_printerr("releaseName(): Name org.DBusTest.SignalTest was released successfully\n");
			break;
		case DBUS_RELEASE_NAME_REPLY_NOT_OWNER:
			g_printerr("releaseName(): Name org.DBusTest.SignalTest is not owned by this app!\n");
			break;
		case DBUS_RELEASE_NAME_REPLY_NON_EXISTENT:
			g_printerr("releaseName(): Name org.DBusTest.SignalTest does not exist!\n");
			break;
		default:
			g_printerr("releaseName(): Unknown exit status %d\n", retval);
	}

	if( retval == -1) {
		if( error == NULL ) {
			g_printerr("releaseName(): Something fishy. We got an exit status of -1 but error == NULL!\n");
		}
		else {
			g_printerr("Could not release name org.DBusTest.SignalTest: %s\n", error -> message);
			g_printerr("This program may not terminate...\n");
			dbus_error_free(error);
		}
		
	}

	/* Return false, so that releaseName() will not be called again by the main loop */
	return false;
}
static int do_service(void)
{
	int rc;

	rc = dbus_bus_request_name(connection, name,
				   DBUS_NAME_FLAG_REPLACE_EXISTING, &error);
	if (dbus_error_is_set(&error)) {
		fprintf(stderr, "FAIL: %s: %s\n", error.name, error.message);
		dbus_error_free(&error);
	}
	if (rc != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) {
		return 1;
	}

	if (unlock_fd())
		return 1;

	rc = 0;
	while (!terminate && !rc)
		rc = handle_messages();

	/* If we've received SIGTERM, try one last time to drain the incoming queue */
	if (terminate && !rc)
		rc = handle_messages();

	if (rc < 0)
		return 1;

	rc = dbus_bus_release_name(connection, name, &error);
	if (dbus_error_is_set(&error)) {
		fprintf(stderr, "FAIL: %s: %s\n", error.name, error.message);
		dbus_error_free(&error);
	}
	if (rc != DBUS_RELEASE_NAME_REPLY_RELEASED) {
		return 1;
	}

	return 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);
}
int
main (int argc, char *argv[])
{
  DBusConnection *conn[NUM_CONN];
  DBusConnection *monitor;
  DBusError error;
  int i;
  int test_data_len;

  test_data_len = sizeof (test_data) / sizeof (CommandAndResult);
  
  dbus_error_init (&error);

  conn[0] = dbus_bus_get_private (DBUS_BUS_SESSION, &error);
  if (dbus_error_is_set (&error))
    {
      fprintf (stderr, "*** Failed to open connection 0 to session bus: %s\n",
               error.message);
      dbus_error_free (&error);
      return 1;
    }
  
  if (!match_acquired_or_lost_signal (conn[0],
                                "NameAcquired",
                                dbus_bus_get_unique_name (conn[0])))
    return 1;
  
  conn[1] = dbus_bus_get_private (DBUS_BUS_SESSION, &error);
  if (dbus_error_is_set (&error))
    {
      fprintf (stderr, "*** Failed to open connection 1 to session bus: %s\n",
               error.message);
      dbus_error_free (&error);
      return 1;
    }

  if (!match_acquired_or_lost_signal (conn[1],
                                "NameAcquired",
                                dbus_bus_get_unique_name (conn[1])))
    return 1;


  conn[2] = dbus_bus_get_private (DBUS_BUS_SESSION, &error);
  if (dbus_error_is_set (&error))
    {
      fprintf (stderr, "*** Failed to open connection 2 to session bus: %s\n",
               error.message);
      dbus_error_free (&error);
      return 1;
    }

  if (!match_acquired_or_lost_signal (conn[2],
                                "NameAcquired",
                                dbus_bus_get_unique_name (conn[2])))
    return 1;


  conn[3] = dbus_bus_get_private (DBUS_BUS_SESSION, &error);
  if (dbus_error_is_set (&error))
    {
      fprintf (stderr, "*** Failed to open connection 3 to session bus: %s\n",
               error.message);
      dbus_error_free (&error);
      return 1;
    }

  if (!match_acquired_or_lost_signal (conn[3],
                                "NameAcquired",
                                dbus_bus_get_unique_name (conn[3])))
    return 1;


  monitor = dbus_bus_get (DBUS_BUS_SESSION, &error);
  if (dbus_error_is_set (&error))
    {
      fprintf (stderr, "*** Failed to open monitoring connection to session bus: %s\n",
               error.message);
      dbus_error_free (&error);
      return 1;
    }

  if (!match_acquired_or_lost_signal (monitor,
                                "NameAcquired",
                                dbus_bus_get_unique_name (monitor)))
    return 1;

  dbus_bus_add_match (monitor, "", &error);
  if (dbus_error_is_set (&error))
    {
      fprintf (stderr, "*** Failed to set filter on monitoring connection: %s\n",
               error.message);
      dbus_error_free (&error);
      return 1;
    }


  for (i = 0; i < NUM_CONN; i++) 
    dbus_connection_set_exit_on_disconnect (conn[i], FALSE);

  for (i = 0; i < test_data_len; i++)
    {
      dbus_uint32_t result;
      result = 0;

      if (test_data[i].command == ADD_CONNECTION)
        {
          result = dbus_bus_request_name (conn[test_data[i].connection_number], 
                                          TEST_NAME, 
                                          test_data[i].flags,
                                          &error);

          if (dbus_error_is_set (&error))
            {
              fprintf (stderr, "Error on addition in iteration %i: %s\n", i, error.message);
              dbus_error_free (&error);
              return 1;
            }
        } 
      else if (test_data[i].command == REMOVE_CONNECTION)
        {
          result = dbus_bus_release_name (conn[test_data[i].connection_number], 
                                          TEST_NAME, 
                                          &error);  
          if (dbus_error_is_set (&error))
            {
              fprintf (stderr, "*** Failed to remove connection %i in iteration %i: %s\n",
                       test_data[i].connection_number,
                       i,
                       error.message);
              dbus_error_free (&error);
              return 1;
            }
        }
      else
        {
          fprintf (stderr, "Command #%i not a valid command!\n", test_data[i].command);
          return 1;
        }


      if (result != test_data[i].expected_result)
        {
          fprintf (stderr, "Results recived (%i) are not the expected results (%i) in iteration %i\n",
                   result,
                   test_data[i].expected_result,
                   i);
          return 1;
        }

      if (!check_connection (monitor, i, conn))
        {
          fprintf (stderr, "Failed at iteration %i\n", i);
          return 1;
        }

      if (!check_signals (monitor, i, conn))
        {
          fprintf (stderr, "Failed at iteration %i\n", i);
          return 1;
        }
    }

    return 0;
}
Exemple #19
0
HippoDBusStacker*
hippo_dbus_stacker_try_to_acquire(const char  *stacker_server,
                                  gboolean     replace_existing,
                                  GError     **error)
{
    HippoDBusStacker *dbus;
    DBusGConnection *gconnection;
    DBusConnection *connection;
    char *stacker_bus_name;
    char *old_bus_name;
    DBusError derror;
    
    dbus_error_init(&derror);

    /* dbus_bus_get is a little hosed since you can't unref 
     * unless you know it's disconnected. I guess it turns
     * out we more or less want to do that anyway.
     */
    
    gconnection = dbus_g_bus_get(DBUS_BUS_SESSION, error);
    if (gconnection == NULL)
        return NULL;
    
    connection = dbus_g_connection_get_connection(gconnection);
    
    /* the purpose of this check is to be sure we will get a "Disconnected"
     * message in the future
     */
    if (!dbus_connection_get_is_connected(connection)) {
        dbus_connection_unref(connection);
        g_set_error(error, HIPPO_ERROR, HIPPO_ERROR_FAILED, 
            _("No active connection to the session's message bus"));
        return NULL;
    }

    stacker_bus_name = hippo_dbus_full_bus_name_com_dumbhippo_with_forward_hex(stacker_server);
    if (!acquire_bus_name(connection, stacker_server, replace_existing, stacker_bus_name, error)) {
        g_free(stacker_bus_name);
        /* FIXME leak bus connection since unref isn't allowed */
        return NULL;
    }

    /* We also acquire our old broken bus name for compatibility with old versions
     * of client apps, and so that when this version is run with --replace
     * old versions will exit. We *don't* exit if we lose ownership of this
     * name ourself, since we running the older version with --replace to replace
     * the new version isn't very interesting
     *
     * Since this is compat gunk, it only uses the stacker server.
     */
    
    old_bus_name = hippo_dbus_full_bus_name_com_dumbhippo_with_backward_hex(stacker_server);
    if (!acquire_bus_name(connection, stacker_server, replace_existing, old_bus_name, error)) {
        /* FIXME leak bus connection since unref isn't allowed */

        /* We need to give up the new bus name because we call ShowBrowser on
         * it in main.c if we fail to get both names, which deadlocks if
         * we own the new name
         */
        dbus_bus_release_name(connection, stacker_bus_name, NULL);
        
        g_free(old_bus_name);
        g_free(stacker_bus_name);
        
        return NULL;
    }

    g_free(stacker_bus_name);
    g_free(old_bus_name);

    {
    	DBusError tmp_derror;    
        dbus_uint32_t flags;
        
    	dbus_error_init(&tmp_derror);        
        
        /* We do want to be queued if we don't get this right away */
        flags = DBUS_NAME_FLAG_ALLOW_REPLACEMENT;
        if (replace_existing)
            flags |= DBUS_NAME_FLAG_REPLACE_EXISTING;
        
        /* we just ignore errors on this */
        dbus_bus_request_name(connection, HIPPO_DBUS_STACKER_BASE_BUS_NAME,
                              flags,
                              &tmp_derror);
        if (dbus_error_is_set(&tmp_derror))
        	g_debug("Failed to get bus name %s: %s", HIPPO_DBUS_STACKER_BASE_BUS_NAME, tmp_derror.message);
       	else
       		g_debug("Acquired bus name %s", HIPPO_DBUS_STACKER_BASE_BUS_NAME);                              
    }
    
    /* the connection is already set up with the main loop. 
     * We just need to create our object, filters, etc. 
     */
    g_debug("D-BUS connection established");

    dbus = g_object_new(HIPPO_TYPE_DBUS_STACKER, NULL);
    dbus->stacker_bus_name = stacker_bus_name;
    dbus->connection = connection;
    
    if (!dbus_connection_add_filter(connection, handle_message,
                                    dbus, NULL))
        g_error("no memory adding dbus connection filter");

    /* add an extra ref, which is owned by the "connected" state on 
     * the connection. We drop it in our filter func if we get 
     * the disconnected message or lose our bus name.
     */
    g_object_ref(dbus);

    /* we'll deal with this ourselves */
    dbus_connection_set_exit_on_disconnect(connection, FALSE);

    /* also returning a ref to the caller */    
    return dbus;
}