libhydra: Remove empty unused library
[strongswan.git] / src / libstrongswan / utils / compat / windows.c
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 }