1 /* win32sck.c 2 * 3 * (c) 1995 Microsoft Corporation. All rights reserved. 4 * Developed by hip communications inc. 5 * Portions (c) 1993 Intergraph Corporation. All rights reserved. 6 * 7 * You may distribute under the terms of either the GNU General Public 8 * License or the Artistic License, as specified in the README file. 9 */ 10 11 #define WIN32IO_IS_STDIO 12 #define WIN32SCK_IS_STDSCK 13 #define WIN32_LEAN_AND_MEAN 14 #define PERLIO_NOT_STDIO 0 15 #ifdef __GNUC__ 16 #define Win32_Winsock 17 #endif 18 #include <wchar.h> 19 #include <windows.h> 20 #include <ws2spi.h> 21 22 #include "EXTERN.h" 23 #include "perl.h" 24 25 #include "Win32iop.h" 26 #include <sys/socket.h> 27 #include <fcntl.h> 28 #include <sys/stat.h> 29 #include <assert.h> 30 #include <io.h> 31 32 /* thanks to Beverly Brown (beverly@datacube.com) */ 33 #define OPEN_SOCKET(x) win32_open_osfhandle(x,O_RDWR|O_BINARY) 34 #define TO_SOCKET(x) _get_osfhandle(x) 35 36 #define SOCKET_TEST(x, y) \ 37 STMT_START { \ 38 if((x) == (y)) \ 39 { \ 40 int wsaerr = WSAGetLastError(); \ 41 errno = convert_wsa_error_to_errno(wsaerr); \ 42 SetLastError(wsaerr); \ 43 } \ 44 } STMT_END 45 46 #define SOCKET_TEST_ERROR(x) SOCKET_TEST(x, SOCKET_ERROR) 47 48 static struct servent* win32_savecopyservent(struct servent*d, 49 struct servent*s, 50 const char *proto); 51 52 #ifdef WIN32_DYN_IOINFO_SIZE 53 EXTERN_C Size_t w32_ioinfo_size; 54 #endif 55 56 EXTERN_C void 57 EndSockets(void) 58 { 59 WSACleanup(); 60 } 61 62 /* Translate WSAExxx values to corresponding Exxx values where possible. Not all 63 * WSAExxx constants have corresponding Exxx constants in <errno.h> (even in 64 * VC++ 2010 and above, which have expanded <errno.h> with more values), but 65 * most missing constants are provided by win32/include/sys/errno2.h. The few 66 * that are not are returned unchanged. 67 * 68 * The list of possible WSAExxx values used here comes from the MSDN page 69 * titled "Windows Sockets Error Codes". 70 * 71 * (Note: Only the WSAExxx values are handled here; other WSAxxx values are 72 * returned unchanged. The return value normally ends up in errno/$! and at 73 * the Perl code level may be tested against the Exxx constants exported by 74 * the Errno and POSIX modules, which have never handled the other WSAxxx 75 * values themselves, apparently without any ill effect so far.) 76 */ 77 int 78 convert_wsa_error_to_errno(int wsaerr) 79 { 80 switch (wsaerr) { 81 case WSAEINTR: 82 return EINTR; 83 case WSAEBADF: 84 return EBADF; 85 case WSAEACCES: 86 return EACCES; 87 case WSAEFAULT: 88 return EFAULT; 89 case WSAEINVAL: 90 return EINVAL; 91 case WSAEMFILE: 92 return EMFILE; 93 case WSAEWOULDBLOCK: 94 return EWOULDBLOCK; 95 case WSAEINPROGRESS: 96 return EINPROGRESS; 97 case WSAEALREADY: 98 return EALREADY; 99 case WSAENOTSOCK: 100 return ENOTSOCK; 101 case WSAEDESTADDRREQ: 102 return EDESTADDRREQ; 103 case WSAEMSGSIZE: 104 return EMSGSIZE; 105 case WSAEPROTOTYPE: 106 return EPROTOTYPE; 107 case WSAENOPROTOOPT: 108 return ENOPROTOOPT; 109 case WSAEPROTONOSUPPORT: 110 return EPROTONOSUPPORT; 111 case WSAESOCKTNOSUPPORT: 112 return ESOCKTNOSUPPORT; 113 case WSAEOPNOTSUPP: 114 return EOPNOTSUPP; 115 case WSAEPFNOSUPPORT: 116 return EPFNOSUPPORT; 117 case WSAEAFNOSUPPORT: 118 return EAFNOSUPPORT; 119 case WSAEADDRINUSE: 120 return EADDRINUSE; 121 case WSAEADDRNOTAVAIL: 122 return EADDRNOTAVAIL; 123 case WSAENETDOWN: 124 return ENETDOWN; 125 case WSAENETUNREACH: 126 return ENETUNREACH; 127 case WSAENETRESET: 128 return ENETRESET; 129 case WSAECONNABORTED: 130 return ECONNABORTED; 131 case WSAECONNRESET: 132 return ECONNRESET; 133 case WSAENOBUFS: 134 return ENOBUFS; 135 case WSAEISCONN: 136 return EISCONN; 137 case WSAENOTCONN: 138 return ENOTCONN; 139 case WSAESHUTDOWN: 140 return ESHUTDOWN; 141 case WSAETOOMANYREFS: 142 return ETOOMANYREFS; 143 case WSAETIMEDOUT: 144 return ETIMEDOUT; 145 case WSAECONNREFUSED: 146 return ECONNREFUSED; 147 case WSAELOOP: 148 return ELOOP; 149 case WSAENAMETOOLONG: 150 return ENAMETOOLONG; 151 case WSAEHOSTDOWN: 152 return WSAEHOSTDOWN; /* EHOSTDOWN is not defined */ 153 case WSAEHOSTUNREACH: 154 return EHOSTUNREACH; 155 case WSAENOTEMPTY: 156 return ENOTEMPTY; 157 case WSAEPROCLIM: 158 return EPROCLIM; 159 case WSAEUSERS: 160 return EUSERS; 161 case WSAEDQUOT: 162 return EDQUOT; 163 case WSAESTALE: 164 return ESTALE; 165 case WSAEREMOTE: 166 return EREMOTE; 167 case WSAEDISCON: 168 return WSAEDISCON; /* EDISCON is not defined */ 169 case WSAENOMORE: 170 return WSAENOMORE; /* ENOMORE is not defined */ 171 #ifdef WSAECANCELLED 172 case WSAECANCELLED: /* New in WinSock2 */ 173 return ECANCELED; 174 #endif 175 case WSAEINVALIDPROCTABLE: 176 return WSAEINVALIDPROCTABLE; /* EINVALIDPROCTABLE is not defined */ 177 case WSAEINVALIDPROVIDER: 178 return WSAEINVALIDPROVIDER; /* EINVALIDPROVIDER is not defined */ 179 case WSAEPROVIDERFAILEDINIT: 180 return WSAEPROVIDERFAILEDINIT; /* EPROVIDERFAILEDINIT is not defined */ 181 case WSAEREFUSED: 182 return WSAEREFUSED; /* EREFUSED is not defined */ 183 } 184 185 return wsaerr; 186 } 187 188 #ifdef ERRNO_HAS_POSIX_SUPPLEMENT 189 /* Translate Exxx values in the POSIX supplement range defined in VC++ 2010 and 190 * above (EADDRINUSE <= err <= EWOULDBLOCK) to corresponding WSAExxx values. Not 191 * all such Exxx constants have corresponding WSAExxx constants in <winsock*.h>; 192 * we just use ERROR_INVALID_FUNCTION for those that are missing but do not 193 * really expect to encounter them anyway in the context in which this function 194 * is called. 195 * Some versions of MinGW/gcc-4.8 and above also define most, but not all, of 196 * these extra Exxx values. The missing ones are all cases for which there is no 197 * corresponding WSAExxx constant anyway, so we simply omit the cases for them 198 * here. 199 * Other Exxx values (err < sys_nerr) are returned unchanged. 200 */ 201 int 202 convert_errno_to_wsa_error(int err) 203 { 204 switch (err) { 205 case EADDRINUSE: 206 return WSAEADDRINUSE; 207 case EADDRNOTAVAIL: 208 return WSAEADDRNOTAVAIL; 209 case EAFNOSUPPORT: 210 return WSAEAFNOSUPPORT; 211 case EALREADY: 212 return WSAEALREADY; 213 #ifdef EBADMSG 214 case EBADMSG: /* Not defined in gcc-4.8.0 */ 215 return ERROR_INVALID_FUNCTION; 216 #endif 217 case ECANCELED: 218 #ifdef WSAECANCELLED 219 return WSAECANCELLED; /* New in WinSock2 */ 220 #else 221 return ERROR_INVALID_FUNCTION; 222 #endif 223 case ECONNABORTED: 224 return WSAECONNABORTED; 225 case ECONNREFUSED: 226 return WSAECONNREFUSED; 227 case ECONNRESET: 228 return WSAECONNRESET; 229 case EDESTADDRREQ: 230 return WSAEDESTADDRREQ; 231 case EHOSTUNREACH: 232 return WSAEHOSTUNREACH; 233 #ifdef EIDRM 234 case EIDRM: /* Not defined in gcc-4.8.0 */ 235 return ERROR_INVALID_FUNCTION; 236 #endif 237 case EINPROGRESS: 238 return WSAEINPROGRESS; 239 case EISCONN: 240 return WSAEISCONN; 241 case ELOOP: 242 return WSAELOOP; 243 case EMSGSIZE: 244 return WSAEMSGSIZE; 245 case ENETDOWN: 246 return WSAENETDOWN; 247 case ENETRESET: 248 return WSAENETRESET; 249 case ENETUNREACH: 250 return WSAENETUNREACH; 251 case ENOBUFS: 252 return WSAENOBUFS; 253 #ifdef ENODATA 254 case ENODATA: /* Not defined in gcc-4.8.0 */ 255 return ERROR_INVALID_FUNCTION; 256 #endif 257 #ifdef ENOLINK 258 case ENOLINK: /* Not defined in gcc-4.8.0 */ 259 return ERROR_INVALID_FUNCTION; 260 #endif 261 #ifdef ENOMSG 262 case ENOMSG: /* Not defined in gcc-4.8.0 */ 263 return ERROR_INVALID_FUNCTION; 264 #endif 265 case ENOPROTOOPT: 266 return WSAENOPROTOOPT; 267 #ifdef ENOSR 268 case ENOSR: /* Not defined in gcc-4.8.0 */ 269 return ERROR_INVALID_FUNCTION; 270 #endif 271 #ifdef ENOSTR 272 case ENOSTR: /* Not defined in gcc-4.8.0 */ 273 return ERROR_INVALID_FUNCTION; 274 #endif 275 case ENOTCONN: 276 return WSAENOTCONN; 277 #ifdef ENOTRECOVERABLE 278 case ENOTRECOVERABLE: /* Not defined in gcc-4.8.0 */ 279 return ERROR_INVALID_FUNCTION; 280 #endif 281 case ENOTSOCK: 282 return WSAENOTSOCK; 283 case ENOTSUP: 284 return ERROR_INVALID_FUNCTION; 285 case EOPNOTSUPP: 286 return WSAEOPNOTSUPP; 287 #ifdef EOTHER 288 case EOTHER: /* Not defined in gcc-4.8.0 */ 289 return ERROR_INVALID_FUNCTION; 290 #endif 291 case EOVERFLOW: 292 return ERROR_INVALID_FUNCTION; 293 case EOWNERDEAD: 294 return ERROR_INVALID_FUNCTION; 295 case EPROTO: 296 return ERROR_INVALID_FUNCTION; 297 case EPROTONOSUPPORT: 298 return WSAEPROTONOSUPPORT; 299 case EPROTOTYPE: 300 return WSAEPROTOTYPE; 301 #ifdef ETIME 302 case ETIME: /* Not defined in gcc-4.8.0 */ 303 return ERROR_INVALID_FUNCTION; 304 #endif 305 case ETIMEDOUT: 306 return WSAETIMEDOUT; 307 #ifdef ETXTBSY 308 case ETXTBSY: /* Not defined in gcc-4.8.0 */ 309 return ERROR_INVALID_FUNCTION; 310 #endif 311 case EWOULDBLOCK: 312 return WSAEWOULDBLOCK; 313 } 314 315 return err; 316 } 317 #endif /* ERRNO_HAS_POSIX_SUPPLEMENT */ 318 319 u_long 320 win32_htonl(u_long hostlong) 321 { 322 return htonl(hostlong); 323 } 324 325 u_short 326 win32_htons(u_short hostshort) 327 { 328 return htons(hostshort); 329 } 330 331 u_long 332 win32_ntohl(u_long netlong) 333 { 334 return ntohl(netlong); 335 } 336 337 u_short 338 win32_ntohs(u_short netshort) 339 { 340 return ntohs(netshort); 341 } 342 343 344 345 SOCKET 346 win32_accept(SOCKET s, struct sockaddr *addr, int *addrlen) 347 { 348 SOCKET r; 349 350 SOCKET_TEST((r = accept(TO_SOCKET(s), addr, addrlen)), INVALID_SOCKET); 351 return OPEN_SOCKET(r); 352 } 353 354 int 355 win32_bind(SOCKET s, const struct sockaddr *addr, int addrlen) 356 { 357 int r; 358 359 SOCKET_TEST_ERROR(r = bind(TO_SOCKET(s), addr, addrlen)); 360 return r; 361 } 362 363 int 364 win32_connect(SOCKET s, const struct sockaddr *addr, int addrlen) 365 { 366 int r; 367 368 SOCKET_TEST_ERROR(r = connect(TO_SOCKET(s), addr, addrlen)); 369 return r; 370 } 371 372 373 int 374 win32_getpeername(SOCKET s, struct sockaddr *addr, int *addrlen) 375 { 376 int r; 377 378 SOCKET_TEST_ERROR(r = getpeername(TO_SOCKET(s), addr, addrlen)); 379 return r; 380 } 381 382 int 383 win32_getsockname(SOCKET s, struct sockaddr *addr, int *addrlen) 384 { 385 int r; 386 387 SOCKET_TEST_ERROR(r = getsockname(TO_SOCKET(s), addr, addrlen)); 388 return r; 389 } 390 391 int 392 win32_getsockopt(SOCKET s, int level, int optname, char *optval, int *optlen) 393 { 394 int r; 395 396 SOCKET_TEST_ERROR(r = getsockopt(TO_SOCKET(s), level, optname, optval, optlen)); 397 return r; 398 } 399 400 int 401 win32_ioctlsocket(SOCKET s, long cmd, u_long *argp) 402 { 403 int r; 404 405 SOCKET_TEST_ERROR(r = ioctlsocket(TO_SOCKET(s), cmd, argp)); 406 return r; 407 } 408 409 int 410 win32_listen(SOCKET s, int backlog) 411 { 412 int r; 413 414 SOCKET_TEST_ERROR(r = listen(TO_SOCKET(s), backlog)); 415 return r; 416 } 417 418 int 419 win32_recv(SOCKET s, char *buf, int len, int flags) 420 { 421 int r; 422 423 SOCKET_TEST_ERROR(r = recv(TO_SOCKET(s), buf, len, flags)); 424 return r; 425 } 426 427 int 428 win32_recvfrom(SOCKET s, char *buf, int len, int flags, struct sockaddr *from, int *fromlen) 429 { 430 int r; 431 int frombufsize = *fromlen; 432 433 SOCKET_TEST_ERROR(r = recvfrom(TO_SOCKET(s), buf, len, flags, from, fromlen)); 434 /* Winsock's recvfrom() only returns a valid 'from' when the socket 435 * is connectionless. Perl expects a valid 'from' for all types 436 * of sockets, so go the extra mile. 437 */ 438 if (r != SOCKET_ERROR && frombufsize == *fromlen) 439 (void)win32_getpeername(s, from, fromlen); 440 return r; 441 } 442 443 /* select contributed by Vincent R. Slyngstad (vrs@ibeam.intel.com) */ 444 int 445 win32_select(int nfds, Perl_fd_set* rd, Perl_fd_set* wr, Perl_fd_set* ex, const struct timeval* timeout) 446 { 447 int r; 448 int i, fd, save_errno = errno; 449 FD_SET nrd, nwr, nex; 450 bool just_sleep = TRUE; 451 452 FD_ZERO(&nrd); 453 FD_ZERO(&nwr); 454 FD_ZERO(&nex); 455 for (i = 0; i < nfds; i++) { 456 if (rd && PERL_FD_ISSET(i,rd)) { 457 fd = TO_SOCKET(i); 458 FD_SET((unsigned)fd, &nrd); 459 just_sleep = FALSE; 460 } 461 if (wr && PERL_FD_ISSET(i,wr)) { 462 fd = TO_SOCKET(i); 463 FD_SET((unsigned)fd, &nwr); 464 just_sleep = FALSE; 465 } 466 if (ex && PERL_FD_ISSET(i,ex)) { 467 fd = TO_SOCKET(i); 468 FD_SET((unsigned)fd, &nex); 469 just_sleep = FALSE; 470 } 471 } 472 473 /* winsock seems incapable of dealing with all three fd_sets being empty, 474 * so do the (millisecond) sleep as a special case 475 */ 476 if (just_sleep) { 477 if (timeout) 478 Sleep(timeout->tv_sec * 1000 + 479 timeout->tv_usec / 1000); /* do the best we can */ 480 else 481 Sleep(UINT_MAX); 482 return 0; 483 } 484 485 errno = save_errno; 486 SOCKET_TEST_ERROR(r = select(nfds, &nrd, &nwr, &nex, (PTIMEVAL)timeout)); 487 save_errno = errno; 488 489 for (i = 0; i < nfds; i++) { 490 if (rd && PERL_FD_ISSET(i,rd)) { 491 fd = TO_SOCKET(i); 492 if (!FD_ISSET(fd, &nrd)) 493 PERL_FD_CLR(i,rd); 494 } 495 if (wr && PERL_FD_ISSET(i,wr)) { 496 fd = TO_SOCKET(i); 497 if (!FD_ISSET(fd, &nwr)) 498 PERL_FD_CLR(i,wr); 499 } 500 if (ex && PERL_FD_ISSET(i,ex)) { 501 fd = TO_SOCKET(i); 502 if (!FD_ISSET(fd, &nex)) 503 PERL_FD_CLR(i,ex); 504 } 505 } 506 errno = save_errno; 507 return r; 508 } 509 510 int 511 win32_send(SOCKET s, const char *buf, int len, int flags) 512 { 513 int r; 514 515 SOCKET_TEST_ERROR(r = send(TO_SOCKET(s), buf, len, flags)); 516 return r; 517 } 518 519 int 520 win32_sendto(SOCKET s, const char *buf, int len, int flags, 521 const struct sockaddr *to, int tolen) 522 { 523 int r; 524 525 SOCKET_TEST_ERROR(r = sendto(TO_SOCKET(s), buf, len, flags, to, tolen)); 526 return r; 527 } 528 529 int 530 win32_setsockopt(SOCKET s, int level, int optname, const char *optval, int optlen) 531 { 532 int r; 533 534 SOCKET_TEST_ERROR(r = setsockopt(TO_SOCKET(s), level, optname, optval, optlen)); 535 return r; 536 } 537 538 int 539 win32_shutdown(SOCKET s, int how) 540 { 541 int r; 542 543 SOCKET_TEST_ERROR(r = shutdown(TO_SOCKET(s), how)); 544 return r; 545 } 546 547 int 548 win32_closesocket(SOCKET s) 549 { 550 int r; 551 552 SOCKET_TEST_ERROR(r = closesocket(TO_SOCKET(s))); 553 return r; 554 } 555 556 void 557 convert_proto_info_w2a(WSAPROTOCOL_INFOW *in, WSAPROTOCOL_INFOA *out) 558 { 559 Copy(in, out, 1, WSAPROTOCOL_INFOA); 560 wcstombs(out->szProtocol, in->szProtocol, sizeof(out->szProtocol)); 561 } 562 563 SOCKET 564 open_ifs_socket(int af, int type, int protocol) 565 { 566 dTHX; 567 char *s; 568 unsigned long proto_buffers_len = 0; 569 int error_code, found = 0; 570 SOCKET out = INVALID_SOCKET; 571 572 if ((s = PerlEnv_getenv("PERL_ALLOW_NON_IFS_LSP")) && atoi(s)) 573 return WSASocket(af, type, protocol, NULL, 0, 0); 574 575 if (WSCEnumProtocols(NULL, NULL, &proto_buffers_len, &error_code) == SOCKET_ERROR 576 && error_code == WSAENOBUFS) 577 { 578 WSAPROTOCOL_INFOW *proto_buffers; 579 int protocols_available = 0; 580 581 Newx(proto_buffers, proto_buffers_len / sizeof(WSAPROTOCOL_INFOW), 582 WSAPROTOCOL_INFOW); 583 584 if ((protocols_available = WSCEnumProtocols(NULL, proto_buffers, 585 &proto_buffers_len, &error_code)) != SOCKET_ERROR) 586 { 587 int i; 588 for (i = 0; i < protocols_available; i++) 589 { 590 WSAPROTOCOL_INFOA proto_info; 591 592 if ((af != AF_UNSPEC && af != proto_buffers[i].iAddressFamily) 593 || (type != proto_buffers[i].iSocketType) 594 || (protocol != 0 && proto_buffers[i].iProtocol != 0 && 595 protocol != proto_buffers[i].iProtocol)) 596 continue; 597 598 if ((proto_buffers[i].dwServiceFlags1 & XP1_IFS_HANDLES) == 0) 599 continue; 600 601 found = 1; 602 convert_proto_info_w2a(&(proto_buffers[i]), &proto_info); 603 604 out = WSASocket(af, type, protocol, &proto_info, 0, 0); 605 break; 606 } 607 608 if (!found) 609 WSASetLastError(WSAEPROTONOSUPPORT); 610 } 611 612 Safefree(proto_buffers); 613 } 614 615 return out; 616 } 617 618 SOCKET 619 win32_socket(int af, int type, int protocol) 620 { 621 SOCKET s; 622 623 if((s = open_ifs_socket(af, type, protocol)) == INVALID_SOCKET) 624 { 625 int wsaerr = WSAGetLastError(); 626 errno = convert_wsa_error_to_errno(wsaerr); 627 SetLastError(wsaerr); 628 } 629 else 630 s = OPEN_SOCKET(s); 631 632 return s; 633 } 634 635 struct hostent * 636 win32_gethostbyaddr(const char *addr, int len, int type) 637 { 638 struct hostent *r; 639 640 SOCKET_TEST(r = gethostbyaddr(addr, len, type), NULL); 641 return r; 642 } 643 644 struct hostent * 645 win32_gethostbyname(const char *name) 646 { 647 struct hostent *r; 648 649 SOCKET_TEST(r = gethostbyname(name), NULL); 650 return r; 651 } 652 653 int 654 win32_gethostname(char *name, int len) 655 { 656 int r; 657 658 SOCKET_TEST_ERROR(r = gethostname(name, len)); 659 return r; 660 } 661 662 struct protoent * 663 win32_getprotobyname(const char *name) 664 { 665 struct protoent *r; 666 667 SOCKET_TEST(r = getprotobyname(name), NULL); 668 return r; 669 } 670 671 struct protoent * 672 win32_getprotobynumber(int num) 673 { 674 struct protoent *r; 675 676 SOCKET_TEST(r = getprotobynumber(num), NULL); 677 return r; 678 } 679 680 struct servent * 681 win32_getservbyname(const char *name, const char *proto) 682 { 683 dTHXa(NULL); 684 struct servent *r; 685 686 SOCKET_TEST(r = getservbyname(name, proto), NULL); 687 if (r) { 688 aTHXa(PERL_GET_THX); 689 r = win32_savecopyservent(&w32_servent, r, proto); 690 } 691 return r; 692 } 693 694 struct servent * 695 win32_getservbyport(int port, const char *proto) 696 { 697 dTHXa(NULL); 698 struct servent *r; 699 700 SOCKET_TEST(r = getservbyport(port, proto), NULL); 701 if (r) { 702 aTHXa(PERL_GET_THX); 703 r = win32_savecopyservent(&w32_servent, r, proto); 704 } 705 return r; 706 } 707 708 int 709 win32_ioctl(int i, unsigned int u, char *data) 710 { 711 u_long u_long_arg; 712 int retval; 713 714 /* mauke says using memcpy avoids alignment issues */ 715 memcpy(&u_long_arg, data, sizeof u_long_arg); 716 retval = ioctlsocket(TO_SOCKET(i), (long)u, &u_long_arg); 717 memcpy(data, &u_long_arg, sizeof u_long_arg); 718 719 if (retval == SOCKET_ERROR) { 720 int wsaerr = WSAGetLastError(); 721 int err = convert_wsa_error_to_errno(wsaerr); 722 if (err == ENOTSOCK) { 723 Perl_croak_nocontext("ioctl implemented only on sockets"); 724 /* NOTREACHED */ 725 } 726 errno = err; 727 SetLastError(wsaerr); 728 } 729 return retval; 730 } 731 732 char FAR * 733 win32_inet_ntoa(struct in_addr in) 734 { 735 return inet_ntoa(in); 736 } 737 738 unsigned long 739 win32_inet_addr(const char FAR *cp) 740 { 741 return inet_addr(cp); 742 } 743 744 /* 745 * Networking stubs 746 */ 747 748 void 749 win32_endhostent() 750 { 751 win32_croak_not_implemented("endhostent"); 752 } 753 754 void 755 win32_endnetent() 756 { 757 win32_croak_not_implemented("endnetent"); 758 } 759 760 void 761 win32_endprotoent() 762 { 763 win32_croak_not_implemented("endprotoent"); 764 } 765 766 void 767 win32_endservent() 768 { 769 win32_croak_not_implemented("endservent"); 770 } 771 772 773 struct netent * 774 win32_getnetent(void) 775 { 776 win32_croak_not_implemented("getnetent"); 777 return (struct netent *) NULL; 778 } 779 780 struct netent * 781 win32_getnetbyname(char *name) 782 { 783 win32_croak_not_implemented("getnetbyname"); 784 return (struct netent *)NULL; 785 } 786 787 struct netent * 788 win32_getnetbyaddr(long net, int type) 789 { 790 win32_croak_not_implemented("getnetbyaddr"); 791 return (struct netent *)NULL; 792 } 793 794 struct protoent * 795 win32_getprotoent(void) 796 { 797 win32_croak_not_implemented("getprotoent"); 798 return (struct protoent *) NULL; 799 } 800 801 struct servent * 802 win32_getservent(void) 803 { 804 win32_croak_not_implemented("getservent"); 805 return (struct servent *) NULL; 806 } 807 808 void 809 win32_sethostent(int stayopen) 810 { 811 win32_croak_not_implemented("sethostent"); 812 } 813 814 815 void 816 win32_setnetent(int stayopen) 817 { 818 win32_croak_not_implemented("setnetent"); 819 } 820 821 822 void 823 win32_setprotoent(int stayopen) 824 { 825 win32_croak_not_implemented("setprotoent"); 826 } 827 828 829 void 830 win32_setservent(int stayopen) 831 { 832 win32_croak_not_implemented("setservent"); 833 } 834 835 static char tcp_proto[] = "tcp"; 836 837 static struct servent* 838 win32_savecopyservent(struct servent*d, struct servent*s, const char *proto) 839 { 840 d->s_name = s->s_name; 841 d->s_aliases = s->s_aliases; 842 d->s_port = s->s_port; 843 if (s->s_proto && strlen(s->s_proto)) 844 d->s_proto = s->s_proto; 845 else 846 if (proto && strlen(proto)) 847 d->s_proto = (char *)proto; 848 else 849 d->s_proto = tcp_proto; 850 851 return d; 852 } 853 854 855