/** * Creates a new server listening on TCP. * If host is NULL, it will default to localhost. * If bind is NULL, it will default to the value for the host * parameter, and if that is NULL, then localhost * If bind is a hostname, it will be resolved and will listen * on all returned addresses. * If family is NULL, hostname resolution will try all address * families, otherwise it can be ipv4 or ipv6 to restrict the * addresses considered. * * @param host the hostname to report for the listen address * @param bind the hostname to listen on * @param port the port to listen on or 0 to let the OS choose * @param family * @param error location to store reason for failure. * @param use_nonce whether to use a nonce for low-level authentication (nonce-tcp transport) or not (tcp transport) * @returns the new server, or #NULL on failure. */ DBusServer* _dbus_server_new_for_tcp_socket (const char *host, const char *bind, const char *port, const char *family, DBusError *error, dbus_bool_t use_nonce) { DBusServer *server; int *listen_fds = NULL; int nlisten_fds = 0, i; DBusString address; DBusString host_str; DBusString port_str; DBusNonceFile *noncefile; _DBUS_ASSERT_ERROR_IS_CLEAR (error); noncefile = NULL; if (!_dbus_string_init (&address)) { dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); return NULL; } if (!_dbus_string_init (&port_str)) { dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); goto failed_0; } if (host == NULL) host = "localhost"; if (port == NULL) port = "0"; if (bind == NULL) bind = host; else if (strcmp (bind, "*") == 0) bind = NULL; nlisten_fds =_dbus_listen_tcp_socket (bind, port, family, &port_str, &listen_fds, error); if (nlisten_fds <= 0) { _DBUS_ASSERT_ERROR_IS_SET(error); goto failed_1; } _dbus_string_init_const (&host_str, host); if (!_dbus_string_append (&address, use_nonce ? "nonce-tcp:host=" : "tcp:host=") || !_dbus_address_append_escaped (&address, &host_str) || !_dbus_string_append (&address, ",port=") || !_dbus_string_append (&address, _dbus_string_get_const_data(&port_str))) { dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); goto failed_2; } if (family && (!_dbus_string_append (&address, ",family=") || !_dbus_string_append (&address, family))) { dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); goto failed_2; } if (use_nonce) { noncefile = dbus_new0 (DBusNonceFile, 1); if (noncefile == NULL) { dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); goto failed_2; } if (!_dbus_noncefile_create (noncefile, error)) goto failed_3; if (!_dbus_string_append (&address, ",noncefile=") || !_dbus_address_append_escaped (&address, _dbus_noncefile_get_path (noncefile))) { dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); goto failed_4; } } server = _dbus_server_new_for_socket (listen_fds, nlisten_fds, &address, noncefile); if (server == NULL) { dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); goto failed_4; } _dbus_string_free (&port_str); _dbus_string_free (&address); dbus_free(listen_fds); return server; failed_4: _dbus_noncefile_delete (noncefile, NULL); failed_3: dbus_free (noncefile); failed_2: for (i = 0 ; i < nlisten_fds ; i++) _dbus_close_socket (listen_fds[i], NULL); dbus_free(listen_fds); failed_1: _dbus_string_free (&port_str); failed_0: _dbus_string_free (&address); return NULL; }
/** * Creates a new server listening on the given Unix domain socket. * * @param path the path for the domain socket. * @param abstract #TRUE to use abstract socket namespace * @param error location to store reason for failure. * @returns the new server, or #NULL on failure. */ DBusServer* _dbus_server_new_for_domain_socket (const char *path, dbus_bool_t abstract, DBusError *error) { DBusServer *server; int listen_fd; DBusString address; char *path_copy; DBusString path_str; _DBUS_ASSERT_ERROR_IS_CLEAR (error); if (!_dbus_string_init (&address)) { dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); return NULL; } _dbus_string_init_const (&path_str, path); if ((abstract && !_dbus_string_append (&address, "unix:abstract=")) || (!abstract && !_dbus_string_append (&address, "unix:path=")) || !_dbus_address_append_escaped (&address, &path_str)) { dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); goto failed_0; } if (abstract) { path_copy = NULL; } else { path_copy = _dbus_strdup (path); if (path_copy == NULL) { dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); goto failed_0; } } listen_fd = _dbus_listen_unix_socket (path, abstract, error); if (listen_fd < 0) { _DBUS_ASSERT_ERROR_IS_SET (error); goto failed_1; } server = _dbus_server_new_for_socket (&listen_fd, 1, &address, 0); if (server == NULL) { dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); goto failed_2; } if (path_copy != NULL) _dbus_server_socket_own_filename(server, path_copy); _dbus_string_free (&address); return server; failed_2: _dbus_close_socket (listen_fd, NULL); failed_1: dbus_free (path_copy); failed_0: _dbus_string_free (&address); return NULL; }
/** * Creates a new debug server using an in-process pipe * * @param server_name the name of the server. * @param error address where an error can be returned. * @returns a new server, or #NULL on failure. */ DBusServer* _dbus_server_debug_pipe_new (const char *server_name, DBusError *error) { DBusServerDebugPipe *debug_server; DBusString address; DBusString name_str; _DBUS_ASSERT_ERROR_IS_CLEAR (error); if (!pipe_hash_ref ()) return NULL; if (_dbus_hash_table_lookup_string (server_pipe_hash, server_name) != NULL) { dbus_set_error (error, DBUS_ERROR_ADDRESS_IN_USE, NULL); pipe_hash_unref (); return NULL; } debug_server = dbus_new0 (DBusServerDebugPipe, 1); if (debug_server == NULL) goto nomem_0; if (!_dbus_string_init (&address)) goto nomem_1; _dbus_string_init_const (&name_str, server_name); if (!_dbus_string_append (&address, "debug-pipe:name=") || !_dbus_address_append_escaped (&address, &name_str)) goto nomem_2; debug_server->name = _dbus_strdup (server_name); if (debug_server->name == NULL) goto nomem_2; if (!_dbus_server_init_base (&debug_server->base, &debug_vtable, &address)) goto nomem_3; if (!_dbus_hash_table_insert_string (server_pipe_hash, debug_server->name, debug_server)) goto nomem_4; _dbus_string_free (&address); /* server keeps the pipe hash ref */ return (DBusServer *)debug_server; nomem_4: _dbus_server_finalize_base (&debug_server->base); nomem_3: dbus_free (debug_server->name); nomem_2: _dbus_string_free (&address); nomem_1: dbus_free (debug_server); nomem_0: pipe_hash_unref (); dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); return NULL; }