From 6180d6954c41a2412c166e5a9e8a2851cf39c6d1 Mon Sep 17 00:00:00 2001 From: Mikael Hallendal Date: Wed, 19 Feb 2003 08:13:31 +0000 Subject: 2003-02-19 Mikael Hallendal * dbus/dbus-server.c (dbus_server_listen): Support tcp: addresses. * dbus/dbus-transport-unix.c (_dbus_transport_new_for_tcp_socket): Added to create a transport connecting using a tcp/ip socket. * dbus/dbus-sysdeps.c (_dbus_connect_tcp_socket): Added to connect to a tcp socket at given host and port. (_dbus_listen_tcp_socket): added to listen on tcp socket for given hostname and port. * dbus/dbus-server.c (dbus_server_listen): Support tcp: addresses. * dbus/dbus-server-unix.c (_dbus_server_new_for_tcp_socket): Added to create a server listening on a TCP/IP socket. --- dbus/dbus-sysdeps.c | 157 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 157 insertions(+) (limited to 'dbus/dbus-sysdeps.c') diff --git a/dbus/dbus-sysdeps.c b/dbus/dbus-sysdeps.c index 316d278c..bf4793eb 100644 --- a/dbus/dbus-sysdeps.c +++ b/dbus/dbus-sysdeps.c @@ -40,6 +40,8 @@ #include #include #include +#include +#include #ifdef HAVE_WRITEV #include @@ -394,6 +396,161 @@ _dbus_listen_unix_socket (const char *path, return listen_fd; } +/** + * Creates a socket and connects to a socket at the given host + * and port. The connection fd is returned, and is set up as + * nonblocking. + * + * @param host the host name to connect to + * @param port the prot to connect to + * @param result return location for error code + * @returns connection file descriptor or -1 on error + */ +int +_dbus_connect_tcp_socket (const char *host, + dbus_uint32_t port, + DBusResultCode *result) +{ + int fd; + struct sockaddr_in addr; + struct hostent *he; + struct in_addr *haddr; + + fd = socket (AF_INET, SOCK_STREAM, 0); + + if (fd < 0) + { + dbus_set_result (result, + _dbus_result_from_errno (errno)); + + _dbus_verbose ("Failed to create socket: %s\n", + _dbus_strerror (errno)); + + return -1; + } + + if (host == NULL) + host = "localhost"; + + he = gethostbyname (host); + if (he == NULL) + { + dbus_set_result (result, + _dbus_result_from_errno (errno)); + _dbus_verbose ("Failed to lookup hostname: %s\n", + host); + return -1; + } + + haddr = ((struct in_addr *) (he->h_addr_list)[0]); + + _DBUS_ZERO (addr); + memcpy (&addr.sin_addr, haddr, sizeof(struct in_addr)); + addr.sin_family = AF_INET; + addr.sin_port = htons (port); + + if (connect (fd, (struct sockaddr*) &addr, sizeof (addr)) < 0) + { + dbus_set_result (result, + _dbus_result_from_errno (errno)); + + _dbus_verbose ("Failed to connect to socket %s: %s:%d\n", + host, port, _dbus_strerror (errno)); + + close (fd); + fd = -1; + + return -1; + } + + if (!_dbus_set_fd_nonblocking (fd, result)) + { + close (fd); + fd = -1; + + return -1; + } + + return fd; +} + +/** + * Creates a socket and binds it to the given path, + * then listens on the socket. The socket is + * set to be nonblocking. + * + * @param host the host name to listen on + * @param port the prot to listen on + * @param result return location for errors + * @returns the listening file descriptor or -1 on error + */ +int +_dbus_listen_tcp_socket (const char *host, + dbus_uint32_t port, + DBusResultCode *result) +{ + int listen_fd; + struct sockaddr_in addr; + struct hostent *he; + struct in_addr *haddr; + + listen_fd = socket (AF_INET, SOCK_STREAM, 0); + + if (listen_fd < 0) + { + dbus_set_result (result, _dbus_result_from_errno (errno)); + _dbus_verbose ("Failed to create socket \"%s:%d\": %s\n", + host, port, _dbus_strerror (errno)); + return -1; + } + + if (host == NULL) + host = "localhost"; + + he = gethostbyname (host); + if (he == NULL) + { + dbus_set_result (result, + _dbus_result_from_errno (errno)); + _dbus_verbose ("Failed to lookup hostname: %s\n", + host); + return -1; + } + + haddr = ((struct in_addr *) (he->h_addr_list)[0]); + + _DBUS_ZERO (addr); + memcpy (&addr.sin_addr, haddr, sizeof (struct in_addr)); + addr.sin_family = AF_INET; + addr.sin_port = htons (port); + + if (bind (listen_fd, (struct sockaddr*) &addr, sizeof (struct sockaddr))) + { + dbus_set_result (result, _dbus_result_from_errno (errno)); + _dbus_verbose ("Failed to bind socket \"%s:%d\": %s\n", + host, port, _dbus_strerror (errno)); + close (listen_fd); + return -1; + } + + if (listen (listen_fd, 30 /* backlog */) < 0) + { + dbus_set_result (result, _dbus_result_from_errno (errno)); + _dbus_verbose ("Failed to listen on socket \"%s:%d\": %s\n", + host, port, _dbus_strerror (errno)); + close (listen_fd); + return -1; + } + + if (!_dbus_set_fd_nonblocking (listen_fd, result)) + { + close (listen_fd); + return -1; + } + + return listen_fd; +} + /* try to read a single byte and return #TRUE if we read it * and it's equal to nul. */ -- cgit