about summary refs log tree commit diff
path: root/src/base/system.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/base/system.c')
-rw-r--r--src/base/system.c202
1 files changed, 139 insertions, 63 deletions
diff --git a/src/base/system.c b/src/base/system.c
index 94481f21..466e3ca6 100644
--- a/src/base/system.c
+++ b/src/base/system.c
@@ -42,10 +42,6 @@
 	#include <fcntl.h>
 	#include <direct.h>
 	#include <errno.h>
-
-	#ifndef EWOULDBLOCK
-		#define EWOULDBLOCK WSAEWOULDBLOCK
-	#endif
 #else
 	#error NOT IMPLEMENTED
 #endif
@@ -316,9 +312,12 @@ int io_seek(IOHANDLE io, int offset, int origin)
 		break;
 	case IOSEEK_END:
 		real_origin = SEEK_END;
+		break;
+	default:
+		return -1;
 	}
 
-	return fseek((FILE*)io, offset, origin);
+	return fseek((FILE*)io, offset, real_origin);
 }
 
 long int io_tell(IOHANDLE io)
@@ -408,6 +407,17 @@ void thread_sleep(int milliseconds)
 #endif
 }
 
+void thread_detach(void *thread)
+{
+#if defined(CONF_FAMILY_UNIX)
+	pthread_detach((pthread_t)(thread));
+#elif defined(CONF_FAMILY_WINDOWS)
+	CloseHandle(thread);
+#else
+	#error not implemented
+#endif
+}
+
 
 
 
@@ -571,13 +581,23 @@ int net_addr_comp(const NETADDR *a, const NETADDR *b)
 void net_addr_str(const NETADDR *addr, char *string, int max_length)
 {
 	if(addr->type == NETTYPE_IPV4)
-		str_format(string, max_length, "%d.%d.%d.%d:%d", addr->ip[0], addr->ip[1], addr->ip[2], addr->ip[3], addr->port);
+	{
+		if(addr->port != 0)
+			str_format(string, max_length, "%d.%d.%d.%d:%d", addr->ip[0], addr->ip[1], addr->ip[2], addr->ip[3], addr->port);
+		else
+			str_format(string, max_length, "%d.%d.%d.%d", addr->ip[0], addr->ip[1], addr->ip[2], addr->ip[3]);
+	}
 	else if(addr->type == NETTYPE_IPV6)
 	{
-		str_format(string, max_length, "[%x:%x:%x:%x:%x:%x:%x:%x]:%d",
-			(addr->ip[0]<<8)|addr->ip[1], (addr->ip[2]<<8)|addr->ip[3], (addr->ip[4]<<8)|addr->ip[5], (addr->ip[6]<<8)|addr->ip[7],
-			(addr->ip[8]<<8)|addr->ip[9], (addr->ip[10]<<8)|addr->ip[11], (addr->ip[12]<<8)|addr->ip[13], (addr->ip[14]<<8)|addr->ip[15],
-			addr->port);
+		if(addr->port != 0)
+			str_format(string, max_length, "[%x:%x:%x:%x:%x:%x:%x:%x]:%d",
+				(addr->ip[0]<<8)|addr->ip[1], (addr->ip[2]<<8)|addr->ip[3], (addr->ip[4]<<8)|addr->ip[5], (addr->ip[6]<<8)|addr->ip[7],
+				(addr->ip[8]<<8)|addr->ip[9], (addr->ip[10]<<8)|addr->ip[11], (addr->ip[12]<<8)|addr->ip[13], (addr->ip[14]<<8)|addr->ip[15],
+				addr->port);
+		else
+			str_format(string, max_length, "[%x:%x:%x:%x:%x:%x:%x:%x]",
+				(addr->ip[0]<<8)|addr->ip[1], (addr->ip[2]<<8)|addr->ip[3], (addr->ip[4]<<8)|addr->ip[5], (addr->ip[6]<<8)|addr->ip[7],
+				(addr->ip[8]<<8)|addr->ip[9], (addr->ip[10]<<8)|addr->ip[11], (addr->ip[12]<<8)|addr->ip[13], (addr->ip[14]<<8)|addr->ip[15]);
 	}
 	else
 		str_format(string, max_length, "unknown type %d", addr->type);
@@ -799,8 +819,6 @@ static int priv_net_close_all_sockets(NETSOCKET sock)
 static int priv_net_create_socket(int domain, int type, struct sockaddr *addr, int sockaddrlen)
 {
 	int sock, e;
-	unsigned long mode = 1;
-	int broadcast = 1;
 
 	/* create socket */
 	sock = socket(domain, type, 0);
@@ -811,11 +829,13 @@ static int priv_net_create_socket(int domain, int type, struct sockaddr *addr, i
 	}
 
 	/* set to IPv6 only if thats what we are creating */
+#if defined(IPV6_V6ONLY)	/* windows sdk 6.1 and higher */
 	if(domain == AF_INET6)
 	{
 		int ipv6only = 1;
 		setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, (const char*)&ipv6only, sizeof(ipv6only));
 	}
+#endif
 
 	/* bind the socket */
 	e = bind(sock, addr, sockaddrlen);
@@ -826,16 +846,6 @@ static int priv_net_create_socket(int domain, int type, struct sockaddr *addr, i
 		return -1;
 	}
 
-	/* set non-blocking */
-#if defined(CONF_FAMILY_WINDOWS)
-	ioctlsocket(sock, FIONBIO, &mode);
-#else
-	ioctl(sock, FIONBIO, &mode);
-#endif
-
-	/* set boardcast */
-	setsockopt(sock, SOL_SOCKET, SO_BROADCAST, (const char*)&broadcast, sizeof(broadcast));
-
 	/* return the newly created socket */
 	return sock;
 }
@@ -844,6 +854,7 @@ NETSOCKET net_udp_create(NETADDR bindaddr)
 {
 	NETSOCKET sock = invalid_socket;
 	NETADDR tmpbindaddr = bindaddr;
+	int broadcast = 1;
 
 	if(bindaddr.type&NETTYPE_IPV4)
 	{
@@ -859,6 +870,12 @@ NETSOCKET net_udp_create(NETADDR bindaddr)
 			sock.type |= NETTYPE_IPV4;
 			sock.ipv4sock = socket;
 		}
+
+		/* set non-blocking */
+		net_set_non_blocking(sock);
+
+		/* set boardcast */
+		setsockopt(socket, SOL_SOCKET, SO_BROADCAST, (const char*)&broadcast, sizeof(broadcast));
 	}
 
 	if(bindaddr.type&NETTYPE_IPV6)
@@ -875,6 +892,12 @@ NETSOCKET net_udp_create(NETADDR bindaddr)
 			sock.type |= NETTYPE_IPV6;
 			sock.ipv6sock = socket;
 		}
+
+		/* set non-blocking */
+		net_set_non_blocking(sock);
+
+		/* set boardcast */
+		setsockopt(socket, SOL_SOCKET, SO_BROADCAST, (const char*)&broadcast, sizeof(broadcast));
 	}
 
 	/* return */
@@ -984,32 +1007,48 @@ int net_udp_close(NETSOCKET sock)
 	return priv_net_close_all_sockets(sock);
 }
 
-// TODO: make TCP stuff work again
-NETSOCKET net_tcp_create(const NETADDR *a)
+NETSOCKET net_tcp_create(NETADDR bindaddr)
 {
-	/* TODO: IPv6 support */
 	NETSOCKET sock = invalid_socket;
+	NETADDR tmpbindaddr = bindaddr;
 
-	if(a->type&NETTYPE_IPV4)
+	if(bindaddr.type&NETTYPE_IPV4)
 	{
 		struct sockaddr_in addr;
+		int socket = -1;
+
+		/* bind, we should check for error */
+		tmpbindaddr.type = NETTYPE_IPV4;
+		netaddr_to_sockaddr_in(&tmpbindaddr, &addr);
+		socket = priv_net_create_socket(AF_INET, SOCK_STREAM, (struct sockaddr *)&addr, sizeof(addr));
+		if(socket >= 0)
+		{
+			sock.type |= NETTYPE_IPV4;
+			sock.ipv4sock = socket;
+		}
+	}
 
-		/* create socket */
-		sock.type |= NETTYPE_IPV4;
-		sock.ipv4sock = socket(AF_INET, SOCK_STREAM, 0);
-		if(sock.ipv4sock < 0)
-			return invalid_socket;
+	if(bindaddr.type&NETTYPE_IPV6)
+	{
+		struct sockaddr_in6 addr;
+		int socket = -1;
 
 		/* bind, we should check for error */
-		netaddr_to_sockaddr_in(a, &addr);
-		bind(sock.ipv4sock, (struct sockaddr *)&addr, sizeof(addr));
+		tmpbindaddr.type = NETTYPE_IPV6;
+		netaddr_to_sockaddr_in6(&tmpbindaddr, &addr);
+		socket = priv_net_create_socket(AF_INET6, SOCK_STREAM, (struct sockaddr *)&addr, sizeof(addr));
+		if(socket >= 0)
+		{
+			sock.type |= NETTYPE_IPV6;
+			sock.ipv6sock = socket;
+		}
 	}
 
 	/* return */
 	return sock;
 }
 
-int net_tcp_set_non_blocking(NETSOCKET sock)
+int net_set_non_blocking(NETSOCKET sock)
 {
 	unsigned long mode = 1;
 	if(sock.ipv4sock >= 0)
@@ -1033,7 +1072,7 @@ int net_tcp_set_non_blocking(NETSOCKET sock)
 	return 0;
 }
 
-int net_tcp_set_blocking(NETSOCKET sock)
+int net_set_blocking(NETSOCKET sock)
 {
 	unsigned long mode = 0;
 	if(sock.ipv4sock >= 0)
@@ -1059,30 +1098,31 @@ int net_tcp_set_blocking(NETSOCKET sock)
 
 int net_tcp_listen(NETSOCKET sock, int backlog)
 {
+	int err = -1;
 	if(sock.ipv4sock >= 0)
-		listen(sock.ipv4sock, backlog);
+		err = listen(sock.ipv4sock, backlog);
 	if(sock.ipv6sock >= 0)
-		listen(sock.ipv6sock, backlog);
-	return 0;
+		err = listen(sock.ipv6sock, backlog);
+	return err;
 }
 
 int net_tcp_accept(NETSOCKET sock, NETSOCKET *new_sock, NETADDR *a)
 {
 	int s;
 	socklen_t sockaddr_len;
-	struct sockaddr addr;
 
 	*new_sock = invalid_socket;
 
-	sockaddr_len = sizeof(addr);
-
 	if(sock.ipv4sock >= 0)
 	{
-		s = accept(sock.ipv4sock, &addr, &sockaddr_len);
+		struct sockaddr_in addr;
+		sockaddr_len = sizeof(addr);
 
+		s = accept(sock.ipv4sock, (struct sockaddr *)&addr, &sockaddr_len);
+		
 		if (s != -1)
 		{
-			sockaddr_to_netaddr(&addr, a);
+			sockaddr_to_netaddr((const struct sockaddr *)&addr, a);
 			new_sock->type = NETTYPE_IPV4;
 			new_sock->ipv4sock = s;
 			return s;
@@ -1091,55 +1131,74 @@ int net_tcp_accept(NETSOCKET sock, NETSOCKET *new_sock, NETADDR *a)
 
 	if(sock.ipv6sock >= 0)
 	{
-		s = accept(sock.ipv6sock, &addr, &sockaddr_len);
+		struct sockaddr_in6 addr;
+		sockaddr_len = sizeof(addr);
 
+		s = accept(sock.ipv6sock, (struct sockaddr *)&addr, &sockaddr_len);
+		
 		if (s != -1)
 		{
-			sockaddr_to_netaddr(&addr, a);
+			sockaddr_to_netaddr((const struct sockaddr *)&addr, a);
 			new_sock->type = NETTYPE_IPV6;
 			new_sock->ipv6sock = s;
 			return s;
 		}
 	}
 
-	return 0;
+	return -1;
 }
 
 int net_tcp_connect(NETSOCKET sock, const NETADDR *a)
 {
-	/*struct sockaddr addr;
-	netaddr_to_sockaddr(a, &addr);
-	return connect(sock, &addr, sizeof(addr));
-	*/
-	return 0;
+	if(a->type&NETTYPE_IPV4)
+	{
+		struct sockaddr_in addr;
+		netaddr_to_sockaddr_in(a, &addr);
+		return connect(sock.ipv4sock, (struct sockaddr *)&addr, sizeof(addr));
+	}
+
+	if(a->type&NETTYPE_IPV6)
+	{
+		struct sockaddr_in6 addr;
+		netaddr_to_sockaddr_in6(a, &addr);
+		return connect(sock.ipv6sock, (struct sockaddr *)&addr, sizeof(addr));
+	}
+
+	return -1;
 }
 
-int net_tcp_connect_non_blocking(NETSOCKET sock, const NETADDR *a)
+int net_tcp_connect_non_blocking(NETSOCKET sock, NETADDR bindaddr)
 {
-	/* struct sockaddr addr; */
 	int res = 0;
 
-	/*
-	netaddr_to_sockaddr(a, &addr);
-	net_tcp_set_non_blocking(sock);
-	res = connect(sock, &addr, sizeof(addr));
-	net_tcp_set_blocking(sock);
-	*/
+	net_set_non_blocking(sock);
+	res = net_tcp_connect(sock, &bindaddr);
+	net_set_blocking(sock);
 
 	return res;
 }
 
 int net_tcp_send(NETSOCKET sock, const void *data, int size)
 {
-	int bytes = 0;
-	/* bytes = send((int)sock, (const char*)data, size, 0); */
+	int bytes = -1;
+
+	if(sock.ipv4sock >= 0)
+		bytes = send((int)sock.ipv4sock, (const char*)data, size, 0);
+	if(sock.ipv6sock >= 0)
+		bytes = send((int)sock.ipv6sock, (const char*)data, size, 0);
+		
 	return bytes;
 }
 
 int net_tcp_recv(NETSOCKET sock, void *data, int maxsize)
 {
-	int bytes = 0;
-	/* bytes = recv((int)sock, (char*)data, maxsize, 0); */
+	int bytes = -1;
+
+	if(sock.ipv4sock >= 0)
+		bytes = recv((int)sock.ipv4sock, (char*)data, maxsize, 0);
+	if(sock.ipv6sock >= 0)
+		bytes = recv((int)sock.ipv6sock, (char*)data, maxsize, 0);
+		
 	return bytes;
 }
 
@@ -1150,12 +1209,20 @@ int net_tcp_close(NETSOCKET sock)
 
 int net_errno()
 {
+#if defined(CONF_FAMILY_WINDOWS)
+	return WSAGetLastError();
+#else
 	return errno;
+#endif
 }
 
 int net_would_block()
 {
+#if defined(CONF_FAMILY_WINDOWS)
+	return net_errno() == WSAEWOULDBLOCK;
+#else
 	return net_errno() == EWOULDBLOCK;
+#endif
 }
 
 int net_init()
@@ -1522,6 +1589,15 @@ int str_comp_nocase(const char *a, const char *b)
 #endif
 }
 
+int str_comp_nocase_num(const char *a, const char *b, const int num)
+{
+#if defined(CONF_FAMILY_WINDOWS)
+	return _strnicmp(a, b, num);
+#else
+	return strncasecmp(a, b, num);
+#endif
+}
+
 int str_comp(const char *a, const char *b)
 {
 	return strcmp(a, b);