Return to windows.c CVS log | Up to [ELWIX - Embedded LightWeight unIX -] / embedaddon / strongswan / src / libstrongswan / utils / compat |
1.1 misho 1: /* 2: * Copyright (C) 2013 Martin Willi 3: * Copyright (C) 2013 revosec AG 4: * 5: * This program is free software; you can redistribute it and/or modify it 6: * under the terms of the GNU General Public License as published by the 7: * Free Software Foundation; either version 2 of the License, or (at your 8: * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. 9: * 10: * This program is distributed in the hope that it will be useful, but 11: * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 12: * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13: * for more details. 14: */ 15: 16: /* WSAPoll() */ 17: #define _WIN32_WINNT 0x0600 18: 19: #include <utils/utils.h> 20: 21: #include <errno.h> 22: 23: /** 24: * See header 25: */ 26: void windows_init() 27: { 28: WSADATA wsad; 29: 30: /* initialize winsock2 */ 31: WSAStartup(MAKEWORD(2, 2), &wsad); 32: } 33: 34: /** 35: * See header 36: */ 37: void windows_deinit() 38: { 39: WSACleanup(); 40: } 41: 42: /** 43: * See header 44: */ 45: int usleep(useconds_t usec) 46: { 47: if (usec > 0 && usec < 1000) 48: { /* do not Sleep(0) for small values */ 49: usec = 1000; 50: } 51: SleepEx(usec / 1000, TRUE); 52: return 0; 53: } 54: 55: /** 56: * See header. 57: */ 58: char* strndup(const char *s, size_t n) 59: { 60: char *dst; 61: 62: n = min(strnlen(s, n), n); 63: dst = malloc(n + 1); 64: memcpy(dst, s, n); 65: dst[n] = '\0'; 66: 67: return dst; 68: } 69: 70: /* 71: * See header. 72: */ 73: void *dlopen(const char *filename, int flag) 74: { 75: return LoadLibrary(filename); 76: } 77: 78: /** 79: * Load a symbol from known default libs (monolithic build) 80: */ 81: static void* dlsym_default(const char *name) 82: { 83: const char *dlls[] = { 84: "libstrongswan-0.dll", 85: "libcharon-0.dll", 86: "libtnccs-0.dll", 87: NULL /* .exe */ 88: }; 89: HANDLE handle; 90: void *sym = NULL; 91: int i; 92: 93: for (i = 0; i < countof(dlls); i++) 94: { 95: handle = GetModuleHandle(dlls[i]); 96: if (handle) 97: { 98: sym = GetProcAddress(handle, name); 99: if (sym) 100: { 101: break; 102: } 103: } 104: } 105: return sym; 106: } 107: 108: /** 109: * Emulate RTLD_NEXT for some known symbols 110: */ 111: static void* dlsym_next(const char *name) 112: { 113: struct { 114: const char *dll; 115: const char *syms[4]; 116: } dlls[] = { 117: /* for leak detective */ 118: { "msvcrt", 119: { "malloc", "calloc", "realloc", "free" } 120: }, 121: }; 122: HANDLE handle = NULL; 123: int i, j; 124: 125: for (i = 0; i < countof(dlls); i++) 126: { 127: for (j = 0; j < countof(dlls[0].syms); j++) 128: { 129: if (dlls[i].syms[j] && streq(dlls[i].syms[j], name)) 130: { 131: handle = GetModuleHandle(dlls[i].dll); 132: break; 133: } 134: } 135: } 136: if (handle) 137: { 138: return GetProcAddress(handle, name); 139: } 140: return handle; 141: } 142: 143: /** 144: * See header. 145: */ 146: void* dlsym(void *handle, const char *symbol) 147: { 148: if (handle == RTLD_DEFAULT) 149: { 150: return dlsym_default(symbol); 151: } 152: if (handle == RTLD_NEXT) 153: { 154: return dlsym_next(symbol); 155: } 156: return GetProcAddress((HMODULE)handle, symbol); 157: } 158: 159: /** 160: * See header. 161: */ 162: char* dlerror(void) 163: { 164: static char buf[128]; 165: char *pos; 166: DWORD err; 167: 168: err = GetLastError(); 169: if (FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, 170: NULL, err, 0, buf, sizeof(buf), NULL) > 0) 171: { 172: pos = strchr(buf, '\n'); 173: if (pos) 174: { 175: *pos = '\0'; 176: } 177: } 178: else 179: { 180: snprintf(buf, sizeof(buf), "(%u)", err); 181: } 182: return buf; 183: } 184: 185: /** 186: * See header. 187: */ 188: int dlclose(void *handle) 189: { 190: return FreeLibrary((HMODULE)handle); 191: } 192: 193: /** 194: * See header 195: */ 196: int socketpair(int domain, int type, int protocol, int sv[2]) 197: { 198: struct sockaddr_in addr = { 199: .sin_family = AF_INET, 200: .sin_addr.s_addr = htonl(INADDR_LOOPBACK), 201: }; 202: socklen_t len = sizeof(addr); 203: int s, c, sc; 204: BOOL on; 205: 206: /* We don't check domain for AF_INET, as we use it as replacement for 207: * AF_UNIX. */ 208: if (type != SOCK_STREAM) 209: { 210: errno = EINVAL; 211: return -1; 212: } 213: if (protocol != 0 && protocol != IPPROTO_TCP) 214: { 215: errno = EINVAL; 216: return -1; 217: } 218: s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); 219: if (s == -1) 220: { 221: return -1; 222: } 223: c = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); 224: if (c == -1) 225: { 226: closesocket(s); 227: return -1; 228: } 229: if (bind(s, (struct sockaddr*)&addr, sizeof(addr)) == 0 && 230: getsockname(s,(struct sockaddr*)&addr, &len) == 0 && 231: listen(s, 0) == 0 && 232: connect(c, (struct sockaddr*)&addr, sizeof(addr)) == 0) 233: { 234: sc = accept(s, NULL, NULL); 235: if (sc >= 0) 236: { 237: closesocket(s); 238: s = sc; 239: if (setsockopt(s, IPPROTO_TCP, TCP_NODELAY, 240: (void*)&on, sizeof(on)) == 0 && 241: setsockopt(c, IPPROTO_TCP, TCP_NODELAY, 242: (void*)&on, sizeof(on)) == 0) 243: { 244: sv[0] = s; 245: sv[1] = c; 246: return 0; 247: } 248: } 249: } 250: closesocket(s); 251: closesocket(c); 252: return -1; 253: } 254: 255: /** 256: * See header 257: */ 258: char* getpass(const char *prompt) 259: { 260: static char buf[64] = ""; 261: char *pos; 262: HANDLE in, out; 263: DWORD mode, written = 0, total, done; 264: 265: out = GetStdHandle(STD_OUTPUT_HANDLE); 266: in = GetStdHandle(STD_INPUT_HANDLE); 267: 268: if (out == INVALID_HANDLE_VALUE || in == INVALID_HANDLE_VALUE || 269: !GetConsoleMode(out, &mode) || !GetConsoleMode(in, &mode)) 270: { 271: return NULL; 272: } 273: 274: total = strlen(prompt); 275: while (written < total) 276: { 277: if (!WriteConsole(out, prompt + written, total - written, &done, NULL)) 278: { 279: return NULL; 280: } 281: written += done; 282: } 283: 284: if (!SetConsoleMode(in, mode & ~ENABLE_ECHO_INPUT)) 285: { 286: return NULL; 287: } 288: 289: while (TRUE) 290: { 291: if (!ReadConsole(in, buf, sizeof(buf), &done, NULL)) 292: { 293: SetConsoleMode(in, mode); 294: return NULL; 295: } 296: buf[sizeof(buf)-1] = '\0'; 297: 298: if (done) 299: { 300: pos = strchr(buf, '\r'); 301: if (pos) 302: { 303: *pos = '\0'; 304: } 305: break; 306: } 307: } 308: SetConsoleMode(in, mode); 309: 310: /* append a newline, as we have no echo during input */ 311: WriteConsole(out, "\r\n", 2, &done, NULL); 312: 313: return buf; 314: } 315: 316: /** 317: * See header. 318: */ 319: #undef strerror_s 320: int strerror_s_extended(char *buf, size_t buflen, int errnum) 321: { 322: const char *errstr [] = { 323: /* EADDRINUSE */ "Address in use", 324: /* EADDRNOTAVAIL */ "Address not available", 325: /* EAFNOSUPPORT */ "Address family not supported", 326: /* EALREADY */ "Connection already in progress", 327: /* EBADMSG */ "Bad message", 328: /* ECANCELED */ "Operation canceled", 329: /* ECONNABORTED */ "Connection aborted", 330: /* ECONNREFUSED */ "Connection refused", 331: /* ECONNRESET */ "Connection reset", 332: /* EDESTADDRREQ */ "Destination address required", 333: /* EHOSTUNREACH */ "Host is unreachable", 334: /* EIDRM */ "Identifier removed", 335: /* EINPROGRESS */ "Operation in progress", 336: /* EISCONN */ "Socket is connected", 337: /* ELOOP */ "Too many levels of symbolic links", 338: /* EMSGSIZE */ "Message too large", 339: /* ENETDOWN */ "Network is down", 340: /* ENETRESET */ "Connection aborted by network", 341: /* ENETUNREACH */ "Network unreachable", 342: /* ENOBUFS */ "No buffer space available", 343: /* ENODATA */ "No message is available", 344: /* ENOLINK */ "No link", 345: /* ENOMSG */ "No message of the desired type", 346: /* ENOPROTOOPT */ "Protocol not available", 347: /* ENOSR */ "No stream resources", 348: /* ENOSTR */ "Not a stream", 349: /* ENOTCONN */ "The socket is not connected", 350: /* ENOTRECOVERABLE */ "State not recoverable", 351: /* ENOTSOCK */ "Not a socket", 352: /* ENOTSUP */ "Not supported", 353: /* EOPNOTSUPP */ "Operation not supported on socket", 354: /* EOTHER */ "Other error", 355: /* EOVERFLOW */ "Value too large to be stored in data type", 356: /* EOWNERDEAD */ "Previous owner died", 357: /* EPROTO */ "Protocol error", 358: /* EPROTONOSUPPORT */ "Protocol not supported", 359: /* EPROTOTYPE */ "Protocol wrong type for socket", 360: /* ETIME */ "Timeout", 361: /* ETIMEDOUT */ "Connection timed out", 362: /* ETXTBSY */ "Text file busy", 363: /* EWOULDBLOCK */ "Operation would block", 364: }; 365: int offset = EADDRINUSE; 366: 367: if (errnum < offset || errnum >= offset + countof(errstr)) 368: { 369: return strerror_s(buf, buflen, errnum); 370: } 371: strncpy(buf, errstr[errnum - offset], buflen); 372: buf[buflen - 1] = '\0'; 373: return 0; 374: } 375: 376: /** 377: * Set errno for a function setting WSA error on failure 378: */ 379: static int wserr(int retval) 380: { 381: if (retval < 0) 382: { 383: static const struct { 384: DWORD wsa; 385: int err; 386: } map[] = { 387: { WSANOTINITIALISED, EBADF }, 388: { WSAENETDOWN, ENETDOWN }, 389: { WSAENETRESET, ENETRESET }, 390: { WSAECONNABORTED, ECONNABORTED }, 391: { WSAESHUTDOWN, ECONNABORTED }, 392: { WSAEACCES, EACCES }, 393: { WSAEINTR, EINTR }, 394: { WSAEINPROGRESS, EINPROGRESS }, 395: { WSAEFAULT, EFAULT }, 396: { WSAENOBUFS, ENOBUFS }, 397: { WSAENOTSOCK, ENOTSOCK }, 398: { WSAEOPNOTSUPP, EOPNOTSUPP }, 399: { WSAEWOULDBLOCK, EWOULDBLOCK }, 400: { WSAEMSGSIZE, EMSGSIZE }, 401: { WSAEINVAL, EINVAL }, 402: { WSAENOTCONN, ENOTCONN }, 403: { WSAEHOSTUNREACH, EHOSTUNREACH }, 404: { WSAENETUNREACH, ENETUNREACH }, 405: { WSAECONNABORTED, ECONNABORTED }, 406: { WSAECONNRESET, ECONNRESET }, 407: { WSAETIMEDOUT, ETIMEDOUT }, 408: { WSAEMFILE, EMFILE }, 409: { WSAEALREADY, EALREADY }, 410: { WSAEDESTADDRREQ, EDESTADDRREQ }, 411: { WSAEISCONN, EISCONN }, 412: { WSAEOPNOTSUPP, EOPNOTSUPP }, 413: { WSAEPROTOTYPE, EPROTOTYPE }, 414: { WSAENOPROTOOPT, ENOPROTOOPT }, 415: { WSAEPROTONOSUPPORT, EPROTONOSUPPORT }, 416: { WSAEPFNOSUPPORT, EPROTONOSUPPORT }, 417: { WSAEAFNOSUPPORT, EAFNOSUPPORT }, 418: { WSAEADDRNOTAVAIL, EADDRNOTAVAIL }, 419: { WSAEADDRINUSE, EADDRINUSE }, 420: { WSAETIMEDOUT, ETIMEDOUT }, 421: { WSAECONNREFUSED, ECONNREFUSED }, 422: { WSAELOOP, ELOOP }, 423: { WSAENAMETOOLONG, ENAMETOOLONG }, 424: { WSAENOTEMPTY, ENOTEMPTY }, 425: { WSAEPROTOTYPE, EPROTOTYPE }, 426: { WSAVERNOTSUPPORTED, ENOTSUP }, 427: }; 428: DWORD wsa, i; 429: 430: wsa = WSAGetLastError(); 431: for (i = 0; i < countof(map); i++) 432: { 433: if (map[i].wsa == wsa) 434: { 435: errno = map[i].err; 436: return retval; 437: } 438: } 439: errno = ENOENT; 440: return retval; 441: } 442: errno = 0; 443: return retval; 444: } 445: 446: /** 447: * Check and clear the dontwait flag 448: */ 449: static bool check_dontwait(int *flags) 450: { 451: if (*flags & MSG_DONTWAIT) 452: { 453: *flags &= ~MSG_DONTWAIT; 454: return TRUE; 455: } 456: return FALSE; 457: } 458: 459: /** 460: * See header 461: */ 462: #undef shutdown 463: int windows_shutdown(int sockfd, int how) 464: { 465: return wserr(shutdown(sockfd, how)); 466: } 467: 468: /** 469: * See header 470: */ 471: #undef accept 472: int windows_accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen) 473: { 474: return wserr(accept(sockfd, addr, addrlen)); 475: } 476: 477: /** 478: * See header 479: */ 480: #undef bind 481: int windows_bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen) 482: { 483: return wserr(bind(sockfd, addr, addrlen)); 484: } 485: 486: /** 487: * See header 488: */ 489: #undef connect 490: int windows_connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen) 491: { 492: return wserr(connect(sockfd, addr, addrlen)); 493: } 494: 495: /** 496: * See header 497: */ 498: #undef getsockname 499: int windows_getsockname(int sockfd, struct sockaddr *addr, socklen_t *addrlen) 500: { 501: return wserr(getsockname(sockfd, addr, addrlen)); 502: } 503: 504: /** 505: * See header 506: */ 507: #undef getsockopt 508: int windows_getsockopt(int sockfd, int level, int optname, 509: void *optval, socklen_t *optlen) 510: { 511: return wserr(getsockopt(sockfd, level, optname, optval, optlen)); 512: } 513: 514: /** 515: * See header 516: */ 517: #undef setsockopt 518: int windows_setsockopt(int sockfd, int level, int optname, 519: const void *optval, socklen_t optlen) 520: { 521: return wserr(setsockopt(sockfd, level, optname, optval, optlen)); 522: } 523: 524: /** 525: * See header 526: */ 527: #undef socket 528: int windows_socket(int domain, int type, int protocol) 529: { 530: return wserr(socket(domain, type, protocol)); 531: } 532: 533: /** 534: * See header 535: */ 536: #undef select 537: int windows_select(int nfds, fd_set *readfds, fd_set *writefds, 538: fd_set *exceptfds, struct timeval *timeout) 539: { 540: return wserr(select(nfds, readfds, writefds, exceptfds, timeout)); 541: } 542: 543: /** 544: * See header 545: */ 546: #undef close 547: int windows_close(int fd) 548: { 549: int ret; 550: 551: ret = close(fd); 552: if (ret == -1 && errno == EBADF) 553: { /* Winsock socket? */ 554: ret = wserr(closesocket(fd)); 555: } 556: return ret; 557: } 558: 559: /** 560: * See header 561: */ 562: #undef recv 563: ssize_t windows_recv(int sockfd, void *buf, size_t len, int flags) 564: { 565: u_long on = 1, off = 0; 566: ssize_t outlen = -1; 567: 568: if (!check_dontwait(&flags)) 569: { 570: return wserr(recv(sockfd, buf, len, flags)); 571: } 572: if (wserr(ioctlsocket(sockfd, FIONBIO, &on) == 0)) 573: { 574: outlen = wserr(recv(sockfd, buf, len, flags)); 575: ioctlsocket(sockfd, FIONBIO, &off); 576: } 577: return outlen; 578: } 579: 580: /** 581: * See header 582: */ 583: #undef recvfrom 584: ssize_t windows_recvfrom(int sockfd, void *buf, size_t len, int flags, 585: struct sockaddr *src_addr, socklen_t *addrlen) 586: { 587: u_long on = 1, off = 0; 588: ssize_t outlen = -1; 589: 590: if (!check_dontwait(&flags)) 591: { 592: return wserr(recvfrom(sockfd, buf, len, flags, src_addr, addrlen)); 593: } 594: if (wserr(ioctlsocket(sockfd, FIONBIO, &on)) == 0) 595: { 596: outlen = wserr(recvfrom(sockfd, buf, len, flags, src_addr, addrlen)); 597: ioctlsocket(sockfd, FIONBIO, &off); 598: } 599: return outlen; 600: } 601: 602: /** 603: * See header 604: */ 605: #undef send 606: ssize_t windows_send(int sockfd, const void *buf, size_t len, int flags) 607: { 608: u_long on = 1, off = 0; 609: ssize_t outlen = -1; 610: 611: if (!check_dontwait(&flags)) 612: { 613: return wserr(send(sockfd, buf, len, flags)); 614: } 615: if (wserr(ioctlsocket(sockfd, FIONBIO, &on)) == 0) 616: { 617: outlen = wserr(send(sockfd, buf, len, flags)); 618: ioctlsocket(sockfd, FIONBIO, &off); 619: } 620: return outlen; 621: } 622: 623: /** 624: * See header 625: */ 626: #undef sendto 627: ssize_t windows_sendto(int sockfd, const void *buf, size_t len, int flags, 628: const struct sockaddr *dest_addr, socklen_t addrlen) 629: { 630: u_long on = 1, off = 0; 631: ssize_t outlen = -1; 632: 633: if (!check_dontwait(&flags)) 634: { 635: return wserr(sendto(sockfd, buf, len, flags, dest_addr, addrlen)); 636: } 637: if (wserr(ioctlsocket(sockfd, FIONBIO, &on)) == 0) 638: { 639: outlen = wserr(sendto(sockfd, buf, len, flags, dest_addr, addrlen)); 640: ioctlsocket(sockfd, FIONBIO, &off); 641: } 642: return outlen; 643: } 644: 645: /** 646: * See header 647: */ 648: #undef read 649: ssize_t windows_read(int fd, void *buf, size_t count) 650: { 651: ssize_t ret; 652: 653: ret = wserr(recv(fd, buf, count, 0)); 654: if (ret == -1 && errno == ENOTSOCK) 655: { 656: ret = read(fd, buf, count); 657: } 658: return ret; 659: } 660: 661: /** 662: * See header 663: */ 664: #undef write 665: ssize_t windows_write(int fd, void *buf, size_t count) 666: { 667: ssize_t ret; 668: 669: ret = wserr(send(fd, buf, count, 0)); 670: if (ret == -1 && errno == ENOTSOCK) 671: { 672: ret = write(fd, buf, count); 673: } 674: return ret; 675: } 676: 677: /** 678: * See header 679: */ 680: int poll(struct pollfd *fds, int nfds, int timeout) 681: { 682: return wserr(WSAPoll(fds, nfds, timeout)); 683: }