예제 #1
0
파일: server.c 프로젝트: herzi/p2p-dbus
guint16
my_dbus_server_get_port (DBusServer* server)
{
  DBusAddressEntry**entries;
  DBusError         error;
  guint16           port = 0;
  char            * address = dbus_server_get_address (server);
  int               n_entries;
  int               i;

  dbus_error_init (&error);
  if (!dbus_parse_address (address, &entries, &n_entries, &error))
    {
      g_warning ("error parsing server address: %s",
                 error.message);
      dbus_error_free (&error);
      free (address);
      exit (1);
      return 0;
    }

  for (i = 0; i < n_entries; i++)
    {
      if (!strcmp ("tcp", dbus_address_entry_get_method (entries[i])))
        {
          port = atoi (dbus_address_entry_get_value (entries[i], "port"));
          break;
        }
    }

  dbus_address_entries_free (entries);
  free (address);
  return port;
}
예제 #2
0
/**
 * Verifies if a given D-Bus address is a valid address
 * by attempting to connect to it. If it is, returns the
 * opened DBusTransport object. If it isn't, returns #NULL
 * and sets @p error.
 *
 * @param error address where an error can be returned.
 * @returns a new transport, or #NULL on failure.
 */
static DBusTransport*
check_address (const char *address, DBusError *error)
{
  DBusAddressEntry **entries;
  DBusTransport *transport = NULL;
  int len, i;

  _dbus_assert (address != NULL);
  _dbus_assert (*address != '\0');

  if (!dbus_parse_address (address, &entries, &len, error))
    return FALSE;              /* not a valid address */

  for (i = 0; i < len; i++)
    {
      transport = _dbus_transport_open (entries[i], error);
      if (transport != NULL)
        break;
    }

  dbus_address_entries_free (entries);
  return transport;
}
예제 #3
0
/**
 * Listens for new connections on the given address.  If there are
 * multiple semicolon-separated address entries in the address, tries
 * each one and listens on the first one that works.
 *
 * Returns #NULL and sets error if listening fails for any reason.
 * Otherwise returns a new #DBusServer.
 * dbus_server_set_new_connection_function(),
 * dbus_server_set_watch_functions(), and
 * dbus_server_set_timeout_functions() should be called immediately to
 * render the server fully functional.
 *
 * To free the server, applications must call first
 * dbus_server_disconnect() and then dbus_server_unref().
 *
 * @param address the address of this server.
 * @param error location to store reason for failure.
 * @returns a new #DBusServer, or #NULL on failure.
 *
 */
DBusServer*
dbus_server_listen (const char     *address,
                    DBusError      *error)
{
    DBusServer *server;
    DBusAddressEntry **entries;
    int len, i;
    DBusError first_connect_error = DBUS_ERROR_INIT;
    dbus_bool_t handled_once;

    _dbus_return_val_if_fail (address != NULL, NULL);
    _dbus_return_val_if_error_is_set (error, NULL);

    if (!dbus_parse_address (address, &entries, &len, error))
        return NULL;

    server = NULL;
    handled_once = FALSE;

    for (i = 0; i < len; i++)
    {
        int j;

        for (j = 0; j < (int) _DBUS_N_ELEMENTS (listen_funcs); ++j)
        {
            DBusServerListenResult result;
            DBusError tmp_error = DBUS_ERROR_INIT;

            result = (* listen_funcs[j].func) (entries[i],
                                               &server,
                                               &tmp_error);

            if (result == DBUS_SERVER_LISTEN_OK)
            {
                _dbus_assert (server != NULL);
                _DBUS_ASSERT_ERROR_IS_CLEAR (&tmp_error);
                handled_once = TRUE;
                goto out;
            }
            else if (result == DBUS_SERVER_LISTEN_ADDRESS_ALREADY_USED)
            {
                _dbus_assert (server == NULL);
                dbus_set_error (error,
                                DBUS_ERROR_ADDRESS_IN_USE,
                                "Address '%s' already used",
                                dbus_address_entry_get_method (entries[0]));
                handled_once = TRUE;
                goto out;
            }
            else if (result == DBUS_SERVER_LISTEN_BAD_ADDRESS)
            {
                _dbus_assert (server == NULL);
                _DBUS_ASSERT_ERROR_IS_SET (&tmp_error);
                dbus_move_error (&tmp_error, error);
                handled_once = TRUE;
                goto out;
            }
            else if (result == DBUS_SERVER_LISTEN_NOT_HANDLED)
            {
                _dbus_assert (server == NULL);
                _DBUS_ASSERT_ERROR_IS_CLEAR (&tmp_error);

                /* keep trying addresses */
            }
            else if (result == DBUS_SERVER_LISTEN_DID_NOT_CONNECT)
            {
                _dbus_assert (server == NULL);
                _DBUS_ASSERT_ERROR_IS_SET (&tmp_error);
                if (!dbus_error_is_set (&first_connect_error))
                    dbus_move_error (&tmp_error, &first_connect_error);
                else
                    dbus_error_free (&tmp_error);

                handled_once = TRUE;

                /* keep trying addresses */
            }
        }

        _dbus_assert (server == NULL);
        _DBUS_ASSERT_ERROR_IS_CLEAR (error);
    }

out:

    if (!handled_once)
    {
        _DBUS_ASSERT_ERROR_IS_CLEAR (error);
        if (len > 0)
            dbus_set_error (error,
                            DBUS_ERROR_BAD_ADDRESS,
                            "Unknown address type '%s'",
                            dbus_address_entry_get_method (entries[0]));
        else
            dbus_set_error (error,
                            DBUS_ERROR_BAD_ADDRESS,
                            "Empty address '%s'",
                            address);
    }

    dbus_address_entries_free (entries);

    if (server == NULL)
    {
        _dbus_assert (error == NULL || dbus_error_is_set (&first_connect_error) ||
                      dbus_error_is_set (error));

        if (error && dbus_error_is_set (error))
        {
            /* already set the error */
        }
        else
        {
            /* didn't set the error but either error should be
             * NULL or first_connect_error should be set.
             */
            _dbus_assert (error == NULL || dbus_error_is_set (&first_connect_error));
            dbus_move_error (&first_connect_error, error);
        }

        _DBUS_ASSERT_ERROR_IS_CLEAR (&first_connect_error); /* be sure we freed it */
        _DBUS_ASSERT_ERROR_IS_SET (error);

        return NULL;
    }
    else
    {
        _DBUS_ASSERT_ERROR_IS_CLEAR (error);
        return server;
    }
}