#include "module.h"
#include "network.h"
+#include <sys/un.h>
+
#ifndef INADDR_NONE
# define INADDR_NONE INADDR_BROADCAST
#endif
-union sockaddr_union {
+union irssi_sockaddr_union {
struct sockaddr sa;
struct sockaddr_in sin;
#ifdef HAVE_IPV6
#else
static
#endif
-void sin_set_ip(union sockaddr_union *so, const IPADDR *ip)
+void sin_set_ip(union irssi_sockaddr_union *so, const IPADDR *ip)
{
if (ip == NULL) {
#ifdef HAVE_IPV6
memcpy(&so->sin.sin_addr, &ip->ip, 4);
}
-void sin_get_ip(const union sockaddr_union *so, IPADDR *ip)
+void sin_get_ip(const union irssi_sockaddr_union *so, IPADDR *ip)
{
ip->family = so->sin.sin_family;
#else
static
#endif
-void sin_set_port(union sockaddr_union *so, int port)
+void sin_set_port(union irssi_sockaddr_union *so, int port)
{
#ifdef HAVE_IPV6
if (so->sin.sin_family == AF_INET6)
#else
static
#endif
-int sin_get_port(union sockaddr_union *so)
+int sin_get_port(union irssi_sockaddr_union *so)
{
#ifdef HAVE_IPV6
if (so->sin.sin_family == AF_INET6)
/* Connect to socket with ip address */
GIOChannel *net_connect_ip(IPADDR *ip, int port, IPADDR *my_ip)
{
- union sockaddr_union so;
+ union irssi_sockaddr_union so;
int handle, ret, opt = 1;
if (my_ip != NULL && ip->family != my_ip->family) {
if (ret < 0 && WSAGetLastError() != WSAEWOULDBLOCK)
#endif
{
+ int old_errno = errno;
+ close(handle);
+ errno = old_errno;
+ return NULL;
+ }
+
+ return g_io_channel_new(handle);
+}
+
+/* Connect to named UNIX socket */
+GIOChannel *net_connect_unix(const char *path)
+{
+ struct sockaddr_un sa;
+ int handle, ret;
+
+ /* create the socket */
+ handle = socket(PF_UNIX, SOCK_STREAM, 0);
+ if (handle == -1)
+ return NULL;
+
+ /* set socket options */
+#ifndef WIN32
+ fcntl(handle, F_SETFL, O_NONBLOCK);
+#endif
+
+ /* connect */
+ memset(&sa, 0, sizeof(sa));
+ sa.sun_family = AF_UNIX;
+ strncpy(sa.sun_path, path, sizeof(sa.sun_path)-1);
+ sa.sun_path[sizeof(sa.sun_path)-1] = '\0';
+
+ ret = connect(handle, (struct sockaddr *) &sa, sizeof(sa));
+ if (ret < 0 && errno != EINPROGRESS) {
+ int old_errno = errno;
close(handle);
+ errno = old_errno;
return NULL;
}
address. */
GIOChannel *net_listen(IPADDR *my_ip, int *port)
{
- union sockaddr_union so;
+ union irssi_sockaddr_union so;
int ret, handle, opt = 1;
socklen_t len;
/* Accept a connection on a socket */
GIOChannel *net_accept(GIOChannel *handle, IPADDR *addr, int *port)
{
- union sockaddr_union so;
+ union irssi_sockaddr_union so;
int ret;
socklen_t addrlen;
/* Get socket address/port */
int net_getsockname(GIOChannel *handle, IPADDR *addr, int *port)
{
- union sockaddr_union so;
+ union irssi_sockaddr_union so;
socklen_t addrlen;
g_return_val_if_fail(handle != NULL, -1);
int net_gethostbyname(const char *addr, IPADDR *ip4, IPADDR *ip6)
{
#ifdef HAVE_IPV6
- union sockaddr_union *so;
+ union irssi_sockaddr_union *so;
struct addrinfo hints, *ai, *ailist;
int ret, count;
#else
count = 0;
for (ai = ailist; ai != NULL && count < 2; ai = ai->ai_next) {
- so = (union sockaddr_union *) ai->ai_addr;
+ so = (union irssi_sockaddr_union *) ai->ai_addr;
if (ai->ai_family == AF_INET6 && ip6->family == 0) {
sin_get_ip(so, ip6);
#else
hp = gethostbyname(addr);
if (hp == NULL)
- return -1;
- //return h_errno;
+ return h_errno;
ip4->family = AF_INET;
memcpy(&ip4->ip, hp->h_addr, 4);
#ifdef HAVE_IPV6
struct addrinfo req, *ai;
int host_error;
+ char hostname[NI_MAXHOST];
+ char ipname[MAX_IP_LEN];
#else
struct hostent *hp;
#endif
- char ipname[MAX_IP_LEN];
g_return_val_if_fail(ip != NULL, -1);
g_return_val_if_fail(name != NULL, -1);
- net_ip2host(ip, ipname);
-
*name = NULL;
#ifdef HAVE_IPV6
+ net_ip2host(ip, ipname);
+
memset(&req, 0, sizeof(struct addrinfo));
req.ai_socktype = SOCK_STREAM;
req.ai_flags = AI_CANONNAME;
host_error = getaddrinfo(ipname, NULL, &req, &ai);
if (host_error != 0)
return host_error;
- *name = g_strdup(ai->ai_canonname);
+ host_error = getnameinfo(ai->ai_addr, ai->ai_addrlen,
+ hostname, NI_MAXHOST, NULL, 0, 0);
+ if (host_error != 0) {
+ freeaddrinfo(ai);
+ return host_error;
+ }
+
+ *name = g_strdup(hostname);
freeaddrinfo(ai);
#else
- hp = gethostbyaddr(ipname, strlen(ipname), AF_INET);
+ if (ip->family != AF_INET) return -1;
+ hp = gethostbyaddr(&ip->ip, 4, AF_INET);
if (hp == NULL) return -1;
*name = g_strdup(hp->h_name);
#else
unsigned long ip4;
- ip4 = ntohl(ip->ip.s_addr);
- g_snprintf(host, MAX_IP_LEN, "%lu.%lu.%lu.%lu",
- (ip4 & 0xff000000UL) >> 24,
- (ip4 & 0x00ff0000) >> 16,
- (ip4 & 0x0000ff00) >> 8,
- (ip4 & 0x000000ff));
+ if (ip->family != AF_INET) {
+ strcpy(host, "0.0.0.0");
+ } else {
+ ip4 = ntohl(ip->ip.s_addr);
+ g_snprintf(host, MAX_IP_LEN, "%lu.%lu.%lu.%lu",
+ (ip4 & 0xff000000UL) >> 24,
+ (ip4 & 0x00ff0000) >> 16,
+ (ip4 & 0x0000ff00) >> 8,
+ (ip4 & 0x000000ff));
+ }
#endif
return 0;
}
{
unsigned long addr;
-#ifdef HAVE_IPV6
if (strchr(host, ':') != NULL) {
/* IPv6 */
ip->family = AF_INET6;
+#ifdef HAVE_IPV6
if (inet_pton(AF_INET6, host, &ip->ip) == 0)
return -1;
- } else
+#else
+ ip->ip.s_addr = 0;
#endif
- {
+ } else {
/* IPv4 */
ip->family = AF_INET;
#ifdef HAVE_INET_ATON
int is_ipv6_address(const char *host)
{
while (*host != '\0') {
- if (*host != ':' && !isxdigit(*host))
+ if (*host != ':' && !i_isxdigit(*host))
return 0;
host++;
}