1 /* win32sck.c
2 *
3 * (c) 1995 Microsoft Corporation. All rights reserved.
4 * Developed by hip communications inc., http://info.hip.com/info/
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 <windows.h>
19 #include <ws2spi.h>
20
21 #include "EXTERN.h"
22 #include "perl.h"
23
24 #include "Win32iop.h"
25 #include <sys/socket.h>
26 #include <fcntl.h>
27 #include <sys/stat.h>
28 #include <assert.h>
29 #include <io.h>
30
31 /* thanks to Beverly Brown (beverly@datacube.com) */
32 #ifdef USE_SOCKETS_AS_HANDLES
33 # define OPEN_SOCKET(x) win32_open_osfhandle(x,O_RDWR|O_BINARY)
34 # define TO_SOCKET(x) _get_osfhandle(x)
35 #else
36 # define OPEN_SOCKET(x) (x)
37 # define TO_SOCKET(x) (x)
38 #endif /* USE_SOCKETS_AS_HANDLES */
39
40 #if defined(USE_5005THREADS) || defined(USE_ITHREADS)
41 #define StartSockets() \
42 STMT_START { \
43 if (!wsock_started) \
44 start_sockets(); \
45 set_socktype(); \
46 } STMT_END
47 #else
48 #define StartSockets() \
49 STMT_START { \
50 if (!wsock_started) { \
51 start_sockets(); \
52 set_socktype(); \
53 } \
54 } STMT_END
55 #endif
56
57 #define SOCKET_TEST(x, y) \
58 STMT_START { \
59 StartSockets(); \
60 if((x) == (y)) \
61 errno = WSAGetLastError(); \
62 } STMT_END
63
64 #define SOCKET_TEST_ERROR(x) SOCKET_TEST(x, SOCKET_ERROR)
65
66 static struct servent* win32_savecopyservent(struct servent*d,
67 struct servent*s,
68 const char *proto);
69
70 static int wsock_started = 0;
71
72 EXTERN_C void
EndSockets(void)73 EndSockets(void)
74 {
75 if (wsock_started)
76 WSACleanup();
77 }
78
79 void
start_sockets(void)80 start_sockets(void)
81 {
82 dTHX;
83 unsigned short version;
84 WSADATA retdata;
85 int ret;
86
87 /*
88 * initalize the winsock interface and insure that it is
89 * cleaned up at exit.
90 */
91 version = 0x2;
92 if(ret = WSAStartup(version, &retdata))
93 Perl_croak_nocontext("Unable to locate winsock library!\n");
94 if(retdata.wVersion != version)
95 Perl_croak_nocontext("Could not find version 2.0 of winsock dll\n");
96
97 /* atexit((void (*)(void)) EndSockets); */
98 wsock_started = 1;
99 }
100
101 void
set_socktype(void)102 set_socktype(void)
103 {
104 #ifdef USE_SOCKETS_AS_HANDLES
105 #if defined(USE_5005THREADS) || defined(USE_ITHREADS)
106 dTHX;
107 if (!w32_init_socktype) {
108 w32_init_socktype = 1;
109 }
110 #endif
111 #endif /* USE_SOCKETS_AS_HANDLES */
112 }
113
114
115 #ifndef USE_SOCKETS_AS_HANDLES
116 #undef fdopen
117 FILE *
my_fdopen(int fd,char * mode)118 my_fdopen(int fd, char *mode)
119 {
120 FILE *fp;
121 char sockbuf[256];
122 int optlen = sizeof(sockbuf);
123 int retval;
124
125 if (!wsock_started)
126 return(fdopen(fd, mode));
127
128 retval = getsockopt((SOCKET)fd, SOL_SOCKET, SO_TYPE, sockbuf, &optlen);
129 if(retval == SOCKET_ERROR && WSAGetLastError() == WSAENOTSOCK) {
130 return(fdopen(fd, mode));
131 }
132
133 /*
134 * If we get here, then fd is actually a socket.
135 */
136 Newxz(fp, 1, FILE); /* XXX leak, good thing this code isn't used */
137 if(fp == NULL) {
138 errno = ENOMEM;
139 return NULL;
140 }
141
142 fp->_file = fd;
143 if(*mode == 'r')
144 fp->_flag = _IOREAD;
145 else
146 fp->_flag = _IOWRT;
147
148 return fp;
149 }
150 #endif /* USE_SOCKETS_AS_HANDLES */
151
152
153 u_long
win32_htonl(u_long hostlong)154 win32_htonl(u_long hostlong)
155 {
156 StartSockets();
157 return htonl(hostlong);
158 }
159
160 u_short
win32_htons(u_short hostshort)161 win32_htons(u_short hostshort)
162 {
163 StartSockets();
164 return htons(hostshort);
165 }
166
167 u_long
win32_ntohl(u_long netlong)168 win32_ntohl(u_long netlong)
169 {
170 StartSockets();
171 return ntohl(netlong);
172 }
173
174 u_short
win32_ntohs(u_short netshort)175 win32_ntohs(u_short netshort)
176 {
177 StartSockets();
178 return ntohs(netshort);
179 }
180
181
182
183 SOCKET
win32_accept(SOCKET s,struct sockaddr * addr,int * addrlen)184 win32_accept(SOCKET s, struct sockaddr *addr, int *addrlen)
185 {
186 SOCKET r;
187
188 SOCKET_TEST((r = accept(TO_SOCKET(s), addr, addrlen)), INVALID_SOCKET);
189 return OPEN_SOCKET(r);
190 }
191
192 int
win32_bind(SOCKET s,const struct sockaddr * addr,int addrlen)193 win32_bind(SOCKET s, const struct sockaddr *addr, int addrlen)
194 {
195 int r;
196
197 SOCKET_TEST_ERROR(r = bind(TO_SOCKET(s), addr, addrlen));
198 return r;
199 }
200
201 int
win32_connect(SOCKET s,const struct sockaddr * addr,int addrlen)202 win32_connect(SOCKET s, const struct sockaddr *addr, int addrlen)
203 {
204 int r;
205
206 SOCKET_TEST_ERROR(r = connect(TO_SOCKET(s), addr, addrlen));
207 return r;
208 }
209
210
211 int
win32_getpeername(SOCKET s,struct sockaddr * addr,int * addrlen)212 win32_getpeername(SOCKET s, struct sockaddr *addr, int *addrlen)
213 {
214 int r;
215
216 SOCKET_TEST_ERROR(r = getpeername(TO_SOCKET(s), addr, addrlen));
217 return r;
218 }
219
220 int
win32_getsockname(SOCKET s,struct sockaddr * addr,int * addrlen)221 win32_getsockname(SOCKET s, struct sockaddr *addr, int *addrlen)
222 {
223 int r;
224
225 SOCKET_TEST_ERROR(r = getsockname(TO_SOCKET(s), addr, addrlen));
226 return r;
227 }
228
229 int
win32_getsockopt(SOCKET s,int level,int optname,char * optval,int * optlen)230 win32_getsockopt(SOCKET s, int level, int optname, char *optval, int *optlen)
231 {
232 int r;
233
234 SOCKET_TEST_ERROR(r = getsockopt(TO_SOCKET(s), level, optname, optval, optlen));
235 return r;
236 }
237
238 int
win32_ioctlsocket(SOCKET s,long cmd,u_long * argp)239 win32_ioctlsocket(SOCKET s, long cmd, u_long *argp)
240 {
241 int r;
242
243 SOCKET_TEST_ERROR(r = ioctlsocket(TO_SOCKET(s), cmd, argp));
244 return r;
245 }
246
247 int
win32_listen(SOCKET s,int backlog)248 win32_listen(SOCKET s, int backlog)
249 {
250 int r;
251
252 SOCKET_TEST_ERROR(r = listen(TO_SOCKET(s), backlog));
253 return r;
254 }
255
256 int
win32_recv(SOCKET s,char * buf,int len,int flags)257 win32_recv(SOCKET s, char *buf, int len, int flags)
258 {
259 int r;
260
261 SOCKET_TEST_ERROR(r = recv(TO_SOCKET(s), buf, len, flags));
262 return r;
263 }
264
265 int
win32_recvfrom(SOCKET s,char * buf,int len,int flags,struct sockaddr * from,int * fromlen)266 win32_recvfrom(SOCKET s, char *buf, int len, int flags, struct sockaddr *from, int *fromlen)
267 {
268 int r;
269 int frombufsize = *fromlen;
270
271 SOCKET_TEST_ERROR(r = recvfrom(TO_SOCKET(s), buf, len, flags, from, fromlen));
272 /* Winsock's recvfrom() only returns a valid 'from' when the socket
273 * is connectionless. Perl expects a valid 'from' for all types
274 * of sockets, so go the extra mile.
275 */
276 if (r != SOCKET_ERROR && frombufsize == *fromlen)
277 (void)win32_getpeername(s, from, fromlen);
278 return r;
279 }
280
281 /* select contributed by Vincent R. Slyngstad (vrs@ibeam.intel.com) */
282 int
win32_select(int nfds,Perl_fd_set * rd,Perl_fd_set * wr,Perl_fd_set * ex,const struct timeval * timeout)283 win32_select(int nfds, Perl_fd_set* rd, Perl_fd_set* wr, Perl_fd_set* ex, const struct timeval* timeout)
284 {
285 int r;
286 #ifdef USE_SOCKETS_AS_HANDLES
287 Perl_fd_set dummy;
288 int i, fd, save_errno = errno;
289 FD_SET nrd, nwr, nex, *prd, *pwr, *pex;
290
291 /* winsock seems incapable of dealing with all three null fd_sets,
292 * so do the (millisecond) sleep as a special case
293 */
294 if (!(rd || wr || ex)) {
295 if (timeout)
296 Sleep(timeout->tv_sec * 1000 +
297 timeout->tv_usec / 1000); /* do the best we can */
298 else
299 Sleep(UINT_MAX);
300 return 0;
301 }
302 StartSockets();
303 PERL_FD_ZERO(&dummy);
304 if (!rd)
305 rd = &dummy, prd = NULL;
306 else
307 prd = &nrd;
308 if (!wr)
309 wr = &dummy, pwr = NULL;
310 else
311 pwr = &nwr;
312 if (!ex)
313 ex = &dummy, pex = NULL;
314 else
315 pex = &nex;
316
317 FD_ZERO(&nrd);
318 FD_ZERO(&nwr);
319 FD_ZERO(&nex);
320 for (i = 0; i < nfds; i++) {
321 fd = TO_SOCKET(i);
322 if (PERL_FD_ISSET(i,rd))
323 FD_SET((unsigned)fd, &nrd);
324 if (PERL_FD_ISSET(i,wr))
325 FD_SET((unsigned)fd, &nwr);
326 if (PERL_FD_ISSET(i,ex))
327 FD_SET((unsigned)fd, &nex);
328 }
329
330 errno = save_errno;
331 SOCKET_TEST_ERROR(r = select(nfds, prd, pwr, pex, timeout));
332 save_errno = errno;
333
334 for (i = 0; i < nfds; i++) {
335 fd = TO_SOCKET(i);
336 if (PERL_FD_ISSET(i,rd) && !FD_ISSET(fd, &nrd))
337 PERL_FD_CLR(i,rd);
338 if (PERL_FD_ISSET(i,wr) && !FD_ISSET(fd, &nwr))
339 PERL_FD_CLR(i,wr);
340 if (PERL_FD_ISSET(i,ex) && !FD_ISSET(fd, &nex))
341 PERL_FD_CLR(i,ex);
342 }
343 errno = save_errno;
344 #else
345 SOCKET_TEST_ERROR(r = select(nfds, rd, wr, ex, timeout));
346 #endif
347 return r;
348 }
349
350 int
win32_send(SOCKET s,const char * buf,int len,int flags)351 win32_send(SOCKET s, const char *buf, int len, int flags)
352 {
353 int r;
354
355 SOCKET_TEST_ERROR(r = send(TO_SOCKET(s), buf, len, flags));
356 return r;
357 }
358
359 int
win32_sendto(SOCKET s,const char * buf,int len,int flags,const struct sockaddr * to,int tolen)360 win32_sendto(SOCKET s, const char *buf, int len, int flags,
361 const struct sockaddr *to, int tolen)
362 {
363 int r;
364
365 SOCKET_TEST_ERROR(r = sendto(TO_SOCKET(s), buf, len, flags, to, tolen));
366 return r;
367 }
368
369 int
win32_setsockopt(SOCKET s,int level,int optname,const char * optval,int optlen)370 win32_setsockopt(SOCKET s, int level, int optname, const char *optval, int optlen)
371 {
372 int r;
373
374 SOCKET_TEST_ERROR(r = setsockopt(TO_SOCKET(s), level, optname, optval, optlen));
375 return r;
376 }
377
378 int
win32_shutdown(SOCKET s,int how)379 win32_shutdown(SOCKET s, int how)
380 {
381 int r;
382
383 SOCKET_TEST_ERROR(r = shutdown(TO_SOCKET(s), how));
384 return r;
385 }
386
387 int
win32_closesocket(SOCKET s)388 win32_closesocket(SOCKET s)
389 {
390 int r;
391
392 SOCKET_TEST_ERROR(r = closesocket(TO_SOCKET(s)));
393 return r;
394 }
395
396 #ifdef USE_SOCKETS_AS_HANDLES
397 #define WIN32_OPEN_SOCKET(af, type, protocol) open_ifs_socket(af, type, protocol)
398
399 void
convert_proto_info_w2a(WSAPROTOCOL_INFOW * in,WSAPROTOCOL_INFOA * out)400 convert_proto_info_w2a(WSAPROTOCOL_INFOW *in, WSAPROTOCOL_INFOA *out)
401 {
402 Copy(in, out, 1, WSAPROTOCOL_INFOA);
403 wcstombs(out->szProtocol, in->szProtocol, sizeof(out->szProtocol));
404 }
405
406 SOCKET
open_ifs_socket(int af,int type,int protocol)407 open_ifs_socket(int af, int type, int protocol)
408 {
409 dTHX;
410 char *s;
411 unsigned long proto_buffers_len = 0;
412 int error_code;
413 SOCKET out = INVALID_SOCKET;
414
415 if ((s = PerlEnv_getenv("PERL_ALLOW_NON_IFS_LSP")) && atoi(s))
416 return WSASocket(af, type, protocol, NULL, 0, 0);
417
418 if (WSCEnumProtocols(NULL, NULL, &proto_buffers_len, &error_code) == SOCKET_ERROR
419 && error_code == WSAENOBUFS)
420 {
421 WSAPROTOCOL_INFOW *proto_buffers;
422 int protocols_available = 0;
423
424 Newx(proto_buffers, proto_buffers_len / sizeof(WSAPROTOCOL_INFOW),
425 WSAPROTOCOL_INFOW);
426
427 if ((protocols_available = WSCEnumProtocols(NULL, proto_buffers,
428 &proto_buffers_len, &error_code)) != SOCKET_ERROR)
429 {
430 int i;
431 for (i = 0; i < protocols_available; i++)
432 {
433 WSAPROTOCOL_INFOA proto_info;
434
435 if ((af != AF_UNSPEC && af != proto_buffers[i].iAddressFamily)
436 || (type != proto_buffers[i].iSocketType)
437 || (protocol != 0 && proto_buffers[i].iProtocol != 0 &&
438 protocol != proto_buffers[i].iProtocol))
439 continue;
440
441 if ((proto_buffers[i].dwServiceFlags1 & XP1_IFS_HANDLES) == 0)
442 continue;
443
444 convert_proto_info_w2a(&(proto_buffers[i]), &proto_info);
445
446 out = WSASocket(af, type, protocol, &proto_info, 0, 0);
447 break;
448 }
449 }
450
451 Safefree(proto_buffers);
452 }
453
454 return out;
455 }
456
457 #else
458 #define WIN32_OPEN_SOCKET(af, type, protocol) socket(af, type, protocol)
459 #endif
460
461 SOCKET
win32_socket(int af,int type,int protocol)462 win32_socket(int af, int type, int protocol)
463 {
464 SOCKET s;
465
466 #ifndef USE_SOCKETS_AS_HANDLES
467 SOCKET_TEST(s = socket(af, type, protocol), INVALID_SOCKET);
468 #else
469 StartSockets();
470
471 if((s = WIN32_OPEN_SOCKET(af, type, protocol)) == INVALID_SOCKET)
472 errno = WSAGetLastError();
473 else
474 s = OPEN_SOCKET(s);
475 #endif /* USE_SOCKETS_AS_HANDLES */
476
477 return s;
478 }
479
480 /*
481 * close RTL fd while respecting sockets
482 * added as temporary measure until PerlIO has real
483 * Win32 native layer
484 * -- BKS, 11-11-2000
485 */
486
my_close(int fd)487 int my_close(int fd)
488 {
489 int osf;
490 if (!wsock_started) /* No WinSock? */
491 return(close(fd)); /* Then not a socket. */
492 osf = TO_SOCKET(fd);/* Get it now before it's gone! */
493 if (osf != -1) {
494 int err;
495 err = closesocket(osf);
496 if (err == 0) {
497 #if defined(USE_FIXED_OSFHANDLE) || defined(PERL_MSVCRT_READFIX)
498 _set_osfhnd(fd, INVALID_HANDLE_VALUE);
499 #endif
500 (void)close(fd); /* handle already closed, ignore error */
501 return 0;
502 }
503 else if (err == SOCKET_ERROR) {
504 err = WSAGetLastError();
505 if (err != WSAENOTSOCK) {
506 (void)close(fd);
507 errno = err;
508 return EOF;
509 }
510 }
511 }
512 return close(fd);
513 }
514
515 #undef fclose
516 int
my_fclose(FILE * pf)517 my_fclose (FILE *pf)
518 {
519 int osf;
520 if (!wsock_started) /* No WinSock? */
521 return(fclose(pf)); /* Then not a socket. */
522 osf = TO_SOCKET(win32_fileno(pf));/* Get it now before it's gone! */
523 if (osf != -1) {
524 int err;
525 win32_fflush(pf);
526 err = closesocket(osf);
527 if (err == 0) {
528 #if defined(USE_FIXED_OSFHANDLE) || defined(PERL_MSVCRT_READFIX)
529 _set_osfhnd(win32_fileno(pf), INVALID_HANDLE_VALUE);
530 #endif
531 (void)fclose(pf); /* handle already closed, ignore error */
532 return 0;
533 }
534 else if (err == SOCKET_ERROR) {
535 err = WSAGetLastError();
536 if (err != WSAENOTSOCK) {
537 (void)fclose(pf);
538 errno = err;
539 return EOF;
540 }
541 }
542 }
543 return fclose(pf);
544 }
545
546 #undef fstat
547 int
my_fstat(int fd,Stat_t * sbufptr)548 my_fstat(int fd, Stat_t *sbufptr)
549 {
550 /* This fixes a bug in fstat() on Windows 9x. fstat() uses the
551 * GetFileType() win32 syscall, which will fail on Windows 9x.
552 * So if we recognize a socket on Windows 9x, we return the
553 * same results as on Windows NT/2000.
554 * XXX this should be extended further to set S_IFSOCK on
555 * sbufptr->st_mode.
556 */
557 int osf;
558 if (!wsock_started || IsWinNT()) {
559 #if defined(WIN64) || defined(USE_LARGE_FILES)
560 #if defined(__BORLANDC__) /* buk */
561 return win32_fstat(fd, sbufptr );
562 #else
563 return _fstati64(fd, sbufptr);
564 #endif
565 #else
566 return fstat(fd, sbufptr);
567 #endif
568 }
569
570 osf = TO_SOCKET(fd);
571 if (osf != -1) {
572 char sockbuf[256];
573 int optlen = sizeof(sockbuf);
574 int retval;
575
576 retval = getsockopt((SOCKET)osf, SOL_SOCKET, SO_TYPE, sockbuf, &optlen);
577 if (retval != SOCKET_ERROR || WSAGetLastError() != WSAENOTSOCK) {
578 #if defined(__BORLANDC__)&&(__BORLANDC__<=0x520)
579 sbufptr->st_mode = S_IFIFO;
580 #else
581 sbufptr->st_mode = _S_IFIFO;
582 #endif
583 sbufptr->st_rdev = sbufptr->st_dev = (dev_t)fd;
584 sbufptr->st_nlink = 1;
585 sbufptr->st_uid = sbufptr->st_gid = sbufptr->st_ino = 0;
586 sbufptr->st_atime = sbufptr->st_mtime = sbufptr->st_ctime = 0;
587 sbufptr->st_size = (Off_t)0;
588 return 0;
589 }
590 }
591 #if defined(WIN64) || defined(USE_LARGE_FILES)
592 #if defined(__BORLANDC__) /* buk */
593 return win32_fstat(fd, sbufptr );
594 #else
595 return _fstati64(fd, sbufptr);
596 #endif
597 #else
598 return fstat(fd, sbufptr);
599 #endif
600 }
601
602 struct hostent *
win32_gethostbyaddr(const char * addr,int len,int type)603 win32_gethostbyaddr(const char *addr, int len, int type)
604 {
605 struct hostent *r;
606
607 SOCKET_TEST(r = gethostbyaddr(addr, len, type), NULL);
608 return r;
609 }
610
611 struct hostent *
win32_gethostbyname(const char * name)612 win32_gethostbyname(const char *name)
613 {
614 struct hostent *r;
615
616 SOCKET_TEST(r = gethostbyname(name), NULL);
617 return r;
618 }
619
620 int
win32_gethostname(char * name,int len)621 win32_gethostname(char *name, int len)
622 {
623 int r;
624
625 SOCKET_TEST_ERROR(r = gethostname(name, len));
626 return r;
627 }
628
629 struct protoent *
win32_getprotobyname(const char * name)630 win32_getprotobyname(const char *name)
631 {
632 struct protoent *r;
633
634 SOCKET_TEST(r = getprotobyname(name), NULL);
635 return r;
636 }
637
638 struct protoent *
win32_getprotobynumber(int num)639 win32_getprotobynumber(int num)
640 {
641 struct protoent *r;
642
643 SOCKET_TEST(r = getprotobynumber(num), NULL);
644 return r;
645 }
646
647 struct servent *
win32_getservbyname(const char * name,const char * proto)648 win32_getservbyname(const char *name, const char *proto)
649 {
650 dTHX;
651 struct servent *r;
652
653 SOCKET_TEST(r = getservbyname(name, proto), NULL);
654 if (r) {
655 r = win32_savecopyservent(&w32_servent, r, proto);
656 }
657 return r;
658 }
659
660 struct servent *
win32_getservbyport(int port,const char * proto)661 win32_getservbyport(int port, const char *proto)
662 {
663 dTHX;
664 struct servent *r;
665
666 SOCKET_TEST(r = getservbyport(port, proto), NULL);
667 if (r) {
668 r = win32_savecopyservent(&w32_servent, r, proto);
669 }
670 return r;
671 }
672
673 int
win32_ioctl(int i,unsigned int u,char * data)674 win32_ioctl(int i, unsigned int u, char *data)
675 {
676 dTHX;
677 u_long argp = (u_long)data;
678 int retval;
679
680 if (!wsock_started) {
681 Perl_croak_nocontext("ioctl implemented only on sockets");
682 /* NOTREACHED */
683 }
684
685 retval = ioctlsocket(TO_SOCKET(i), (long)u, &argp);
686 if (retval == SOCKET_ERROR) {
687 if (WSAGetLastError() == WSAENOTSOCK) {
688 Perl_croak_nocontext("ioctl implemented only on sockets");
689 /* NOTREACHED */
690 }
691 errno = WSAGetLastError();
692 }
693 return retval;
694 }
695
696 char FAR *
win32_inet_ntoa(struct in_addr in)697 win32_inet_ntoa(struct in_addr in)
698 {
699 StartSockets();
700 return inet_ntoa(in);
701 }
702
703 unsigned long
win32_inet_addr(const char FAR * cp)704 win32_inet_addr(const char FAR *cp)
705 {
706 StartSockets();
707 return inet_addr(cp);
708 }
709
710 /*
711 * Networking stubs
712 */
713
714 void
win32_endhostent()715 win32_endhostent()
716 {
717 dTHX;
718 Perl_croak_nocontext("endhostent not implemented!\n");
719 }
720
721 void
win32_endnetent()722 win32_endnetent()
723 {
724 dTHX;
725 Perl_croak_nocontext("endnetent not implemented!\n");
726 }
727
728 void
win32_endprotoent()729 win32_endprotoent()
730 {
731 dTHX;
732 Perl_croak_nocontext("endprotoent not implemented!\n");
733 }
734
735 void
win32_endservent()736 win32_endservent()
737 {
738 dTHX;
739 Perl_croak_nocontext("endservent not implemented!\n");
740 }
741
742
743 struct netent *
win32_getnetent(void)744 win32_getnetent(void)
745 {
746 dTHX;
747 Perl_croak_nocontext("getnetent not implemented!\n");
748 return (struct netent *) NULL;
749 }
750
751 struct netent *
win32_getnetbyname(char * name)752 win32_getnetbyname(char *name)
753 {
754 dTHX;
755 Perl_croak_nocontext("getnetbyname not implemented!\n");
756 return (struct netent *)NULL;
757 }
758
759 struct netent *
win32_getnetbyaddr(long net,int type)760 win32_getnetbyaddr(long net, int type)
761 {
762 dTHX;
763 Perl_croak_nocontext("getnetbyaddr not implemented!\n");
764 return (struct netent *)NULL;
765 }
766
767 struct protoent *
win32_getprotoent(void)768 win32_getprotoent(void)
769 {
770 dTHX;
771 Perl_croak_nocontext("getprotoent not implemented!\n");
772 return (struct protoent *) NULL;
773 }
774
775 struct servent *
win32_getservent(void)776 win32_getservent(void)
777 {
778 dTHX;
779 Perl_croak_nocontext("getservent not implemented!\n");
780 return (struct servent *) NULL;
781 }
782
783 void
win32_sethostent(int stayopen)784 win32_sethostent(int stayopen)
785 {
786 dTHX;
787 Perl_croak_nocontext("sethostent not implemented!\n");
788 }
789
790
791 void
win32_setnetent(int stayopen)792 win32_setnetent(int stayopen)
793 {
794 dTHX;
795 Perl_croak_nocontext("setnetent not implemented!\n");
796 }
797
798
799 void
win32_setprotoent(int stayopen)800 win32_setprotoent(int stayopen)
801 {
802 dTHX;
803 Perl_croak_nocontext("setprotoent not implemented!\n");
804 }
805
806
807 void
win32_setservent(int stayopen)808 win32_setservent(int stayopen)
809 {
810 dTHX;
811 Perl_croak_nocontext("setservent not implemented!\n");
812 }
813
814 static struct servent*
win32_savecopyservent(struct servent * d,struct servent * s,const char * proto)815 win32_savecopyservent(struct servent*d, struct servent*s, const char *proto)
816 {
817 d->s_name = s->s_name;
818 d->s_aliases = s->s_aliases;
819 d->s_port = s->s_port;
820 #ifndef __BORLANDC__ /* Buggy on Win95 and WinNT-with-Borland-WSOCK */
821 if (!IsWin95() && s->s_proto && strlen(s->s_proto))
822 d->s_proto = s->s_proto;
823 else
824 #endif
825 if (proto && strlen(proto))
826 d->s_proto = (char *)proto;
827 else
828 d->s_proto = "tcp";
829
830 return d;
831 }
832
833
834