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 }