anope

- supernets anope source code & configuration
git clone git://git.acid.vegas/anope.git
Log | Files | Refs | Archive | README

socket.cpp (3213B)

      1 /* POSIX emulation layer for Windows.
      2  *
      3  * (C) 2008-2022 Anope Team
      4  * Contact us at team@anope.org
      5  *
      6  * Please read COPYING and README for further details.
      7  */
      8 
      9 #define WIN32_NO_OVERRIDE
     10 #include "services.h"
     11 
     12 inline static bool is_socket(int fd)
     13 {
     14 	int optval;
     15 	socklen_t optlen = sizeof(optval);
     16 	return getsockopt(fd, SOL_SOCKET, SO_TYPE, reinterpret_cast<char *>(&optval), &optlen) == 0;
     17 }
     18 
     19 int read(int fd, char *buf, size_t count)
     20 {
     21 	if (is_socket(fd))
     22 		return recv(fd, buf, count, 0);
     23 	else
     24 		return _read(fd, buf, count);
     25 }
     26 
     27 int write(int fd, const char *buf, size_t count)
     28 {
     29 	if (is_socket(fd))
     30 		return send(fd, buf, count, 0);
     31 	else
     32 		return _write(fd, buf, count);
     33 }
     34 
     35 int windows_close(int fd)
     36 {
     37 	if (is_socket(fd))
     38 		return closesocket(fd);
     39 	else
     40 		return close(fd);
     41 }
     42 
     43 int windows_accept(int fd, struct sockaddr *addr, int *addrlen)
     44 {
     45 	int i = accept(fd, addr, addrlen);
     46 	if (i == INVALID_SOCKET)
     47 		return -1;
     48 	return i;
     49 }
     50 
     51 /** This is inet_pton, but it works on Windows
     52  * @param af The protocol type, AF_INET or AF_INET6
     53  * @param src The address
     54  * @param dst Struct to put results in
     55  * @return 1 on success, -1 on error
     56  */
     57 int windows_inet_pton(int af, const char *src, void *dst)
     58 {
     59 	int address_length;
     60 	sockaddr_storage sa;
     61 	sockaddr_in *sin = reinterpret_cast<sockaddr_in *>(&sa);
     62 	sockaddr_in6 *sin6 = reinterpret_cast<sockaddr_in6 *>(&sa);
     63 
     64 	switch (af)
     65 	{
     66 		case AF_INET:
     67 			address_length = sizeof(sockaddr_in);
     68 			break;
     69 		case AF_INET6:
     70 			address_length = sizeof(sockaddr_in6);
     71 			break;
     72 		default:
     73 			return -1;
     74 	}
     75 
     76 	if (!WSAStringToAddress(static_cast<LPSTR>(const_cast<char *>(src)), af, NULL, reinterpret_cast<LPSOCKADDR>(&sa), &address_length))
     77 	{
     78 		switch (af)
     79 		{
     80 			case AF_INET:
     81 				memcpy(dst, &sin->sin_addr, sizeof(in_addr));
     82 				break;
     83 			case AF_INET6:
     84 				memcpy(dst, &sin6->sin6_addr, sizeof(in6_addr));
     85 				break;
     86 		}
     87 		return 1;
     88 	}
     89 
     90 	return 0;
     91 }
     92 
     93 /** This is inet_ntop, but it works on Windows
     94  * @param af The protocol type, AF_INET or AF_INET6
     95  * @param src Network address structure
     96  * @param dst After converting put it here
     97  * @param size sizeof the dest
     98  * @return dst
     99  */
    100 const char *windows_inet_ntop(int af, const void *src, char *dst, size_t size)
    101 {
    102 	int address_length;
    103 	DWORD string_length = size;
    104 	sockaddr_storage sa;
    105 	sockaddr_in *sin = reinterpret_cast<sockaddr_in *>(&sa);
    106 	sockaddr_in6 *sin6 = reinterpret_cast<sockaddr_in6 *>(&sa);
    107 
    108 	memset(&sa, 0, sizeof(sa));
    109 
    110 	switch (af)
    111 	{
    112 		case AF_INET:
    113 			address_length = sizeof(sockaddr_in);
    114 			sin->sin_family = af;
    115 			memcpy(&sin->sin_addr, src, sizeof(in_addr));
    116 			break;
    117 		case AF_INET6:
    118 			address_length = sizeof(sockaddr_in6);
    119 			sin6->sin6_family = af;
    120 			memcpy(&sin6->sin6_addr, src, sizeof(in6_addr));
    121 			break;
    122 		default:
    123 			return NULL;
    124 	}
    125 
    126 	if (!WSAAddressToString(reinterpret_cast<LPSOCKADDR>(&sa), address_length, NULL, dst, &string_length))
    127 		return dst;
    128 
    129 	return NULL;
    130 }
    131 
    132 int fcntl(int fd, int cmd, int arg)
    133 {
    134 	if (cmd == F_GETFL)
    135 	{
    136 		return 0;
    137 	}
    138 	else if (cmd == F_SETFL)
    139 	{
    140 		if (arg & O_NONBLOCK)
    141 		{
    142 			unsigned long opt = 1;
    143 			return ioctlsocket(fd, FIONBIO, &opt);
    144 		}
    145 		else
    146 		{
    147 			unsigned long opt = 0;
    148 			return ioctlsocket(fd, FIONBIO, &opt);
    149 		}
    150 	}
    151 
    152 	return -1;
    153 }