source: trunk/src/wsock32/wsock32.cpp@ 7461

Last change on this file since 7461 was 7461, checked in by sandervl, 24 years ago

added more FS wrapper macros

File size: 45.1 KB
Line 
1/* $Id: wsock32.cpp,v 1.45 2001-11-27 11:13:03 sandervl Exp $ */
2
3/*
4 *
5 * Project Odin Software License can be found in LICENSE.TXT
6 *
7 * Win32 SOCK32 for OS/2
8 *
9 * Copyright (C) 1999 Patrick Haller <phaller@gmx.net>
10 * Copyright (C) 2000 Sander van Leeuwen (sandervl@xs4all.nl)
11 *
12 * Some parts based on Wine code: (dlls\winsock\socket.c)
13 * (C) 1993,1994,1996,1997 John Brezak, Erik Bos, Alex Korobka.
14 *
15 */
16
17/* Remark:
18 * 1999/11/21 experimental rewrite using IBM's PMWSock only
19 * -> some structural differences remain! (hostent)
20 * 1999/12/01 experimental rewrite works (TELNET)
21 * -> open issue: WSASetLastError / WSAGetLastError
22 * call SetLastError / GetLastError according to docs
23 *
24 * 2000/22/03 Complete rewrite -> got rid of pmwsock
25 *
26 * identical structures:
27 * - sockaddr_in
28 * - WSADATA
29 * - sockaddr
30 * - fd_set
31 * - timeval
32 *
33 * incompatible structures:
34 * - hostent
35 * - netent
36 * - servent
37 * - protent
38 * - linger
39 */
40
41
42/*****************************************************************************
43 * Includes *
44 *****************************************************************************/
45
46#define INCL_BASE
47#include <os2wrap.h> //Odin32 OS/2 api wrappers
48
49#include <string.h>
50#include <odinwrap.h>
51#include <os2sel.h>
52#include <stdlib.h>
53#include <win32api.h>
54#define NO_DCDATA
55#include <winuser32.h>
56#include <wprocess.h>
57#include <misc.h>
58
59#include "wsock32.h"
60#include <ws2tcpip.h>
61#include "wsastruct.h"
62#include "asyncthread.h"
63
64#define DBG_LOCALLOG DBG_wsock32
65#include "dbglocal.h"
66
67//kso: dirty fix to make this compile! not permanent!
68BOOL WINAPI QueryPerformanceCounter(LARGE_INTEGER *p);
69#define LowPart u.LowPart
70
71
72ODINDEBUGCHANNEL(WSOCK32-WSOCK32)
73
74
75/*****************************************************************************
76 * Local variables *
77 *****************************************************************************/
78
79static LPWSINFO lpFirstIData = NULL;
80
81
82//******************************************************************************
83//******************************************************************************
84
85// Note: for the TCP/IP 4.0 headers, SO_SNDTIMEO and SO_RCDTIMEO are
86// unfortunately not defined, so we do this here.
87#ifndef SO_SNDTIMEO
88#define SO_SNDTIMEO 0x1005
89#endif
90
91#ifndef SO_RCVTIMEO
92#define SO_RCVTIMEO 0x1006
93#endif
94
95
96//******************************************************************************
97//******************************************************************************
98LPWSINFO WINSOCK_GetIData(HANDLE tid)
99{
100 LPWSINFO iData;
101 BOOL fCurrentThread = FALSE;
102
103 if(tid == CURRENT_THREAD) {
104 tid = GetCurrentThread();
105 fCurrentThread = TRUE;
106 }
107tryagain:
108 for (iData = lpFirstIData; iData; iData = iData->lpNextIData) {
109 if (iData->dwThisThread == tid)
110 break;
111 }
112 if(iData == NULL && fCurrentThread) {
113 WINSOCK_CreateIData();
114 fCurrentThread = FALSE; //just to prevent infinite loops
115 goto tryagain;
116 }
117 if(iData == NULL) {
118 dprintf(("WINSOCK_GetIData: couldn't find struct for thread %x", tid));
119 DebugInt3();// should never happen!!!!!!!
120 }
121 return iData;
122}
123//******************************************************************************
124//******************************************************************************
125BOOL WINSOCK_CreateIData(void)
126{
127 LPWSINFO iData;
128
129 iData = (LPWSINFO)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(WSINFO));
130 if (!iData)
131 return FALSE;
132 iData->dwThisThread = GetCurrentThread();
133 iData->lpNextIData = lpFirstIData;
134 lpFirstIData = iData;
135 return TRUE;
136}
137//******************************************************************************
138//******************************************************************************
139void WINSOCK_DeleteIData(void)
140{
141 LPWSINFO iData = WINSOCK_GetIData();
142 LPWSINFO* ppid;
143 if (iData) {
144 for (ppid = &lpFirstIData; *ppid; ppid = &(*ppid)->lpNextIData) {
145 if (*ppid == iData) {
146 *ppid = iData->lpNextIData;
147 break;
148 }
149 }
150
151 if( iData->flags & WSI_BLOCKINGCALL )
152 dprintf(("\tinside blocking call!\n"));
153
154 /* delete scratch buffers */
155 if(iData->he) free(iData->he);
156 if(iData->se) free(iData->se);
157 if(iData->pe) free(iData->pe);
158
159 //// if( iData->buffer ) SEGPTR_FREE(iData->buffer);
160 //// if( iData->dbuffer ) SEGPTR_FREE(iData->dbuffer);
161
162 HeapFree(GetProcessHeap(), 0, iData);
163 }
164}
165//******************************************************************************
166//******************************************************************************
167void WIN32API WSASetLastError(int iError)
168{
169#ifdef DEBUG
170 char msg[20];
171#endif
172 // according to the docs, WSASetLastError() is just a call-through
173 // to SetLastError()
174 SetLastError(iError);
175#ifdef DEBUG
176 switch (iError)
177 {
178 case NO_ERROR:
179 strcpy(msg, "no error");
180 break;
181 case WSAEINTR:
182 strcpy(msg, "WSAEINTR");
183 break;
184 case WSAEBADF:
185 strcpy(msg, "WSAEBADF");
186 break;
187 case WSAEACCES:
188 strcpy(msg, "WSAEACCES");
189 break;
190 case WSAEFAULT:
191 strcpy(msg, "WSAEFAULT");
192 break;
193 case WSAEINVAL:
194 strcpy(msg, "WSAEINVAL");
195 break;
196 case WSAEMFILE:
197 strcpy(msg, "WSAEMFILE");
198 break;
199 case WSAEWOULDBLOCK:
200 strcpy(msg, "WSAEWOULDBLOCK");
201 break;
202 case WSAEINPROGRESS:
203 strcpy(msg, "WSAEINPROGRESS");
204 break;
205 case WSAEALREADY:
206 strcpy(msg, "WSAEALREADY");
207 break;
208 case WSAHOST_NOT_FOUND:
209 strcpy(msg, "WSAHOST_NOT_FOUND");
210 break;
211 default:
212 strcpy(msg, "unknown");
213 }
214 if (iError != 0)
215 {
216 dprintf(("WSASetLastError 0x%x - %s", iError, msg));
217 }
218#endif
219}
220//******************************************************************************
221//******************************************************************************
222int WIN32API WSAGetLastError()
223{
224 return GetLastError();
225}
226//******************************************************************************
227//******************************************************************************
228ODINFUNCTION2(int,OS2shutdown,
229 SOCKET,s,
230 int,how)
231{
232 int ret;
233
234 if(!fWSAInitialized) {
235 WSASetLastError(WSANOTINITIALISED);
236 return SOCKET_ERROR;
237 }
238 else
239 if(WSAIsBlocking()) {
240 WSASetLastError(WSAEINPROGRESS);
241 return SOCKET_ERROR;
242 }
243 ret = shutdown(s, how);
244
245 if(ret == SOCKET_ERROR) {
246 WSASetLastError(wsaErrno());
247 }
248 else WSASetLastError(NO_ERROR);
249 return ret;
250}
251//******************************************************************************
252//******************************************************************************
253ODINFUNCTION3(SOCKET,OS2socket,
254 int,af,
255 int,type,
256 int,protocol)
257{
258 SOCKET s;
259
260 if(!fWSAInitialized) {
261 WSASetLastError(WSANOTINITIALISED);
262 return SOCKET_ERROR;
263 }
264 else
265 if(WSAIsBlocking()) {
266 WSASetLastError(WSAEINPROGRESS);
267 return SOCKET_ERROR;
268 }
269 s = socket(af, type, protocol);
270
271 if(s == SOCKET_ERROR && sock_errno() == SOCEPFNOSUPPORT) {
272 //map SOCEPFNOSUPPORT to SOCEPFNOSUPPORT
273 WSASetLastError(SOCEPFNOSUPPORT);
274 }
275 else
276 if(s == SOCKET_ERROR) {
277 WSASetLastError(wsaErrno());
278 }
279 else WSASetLastError(NO_ERROR);
280 return s;
281}
282//******************************************************************************
283//******************************************************************************
284ODINFUNCTION1(int,OS2closesocket,SOCKET, s)
285{
286 int ret;
287
288 if(!fWSAInitialized) {
289 WSASetLastError(WSANOTINITIALISED);
290 return SOCKET_ERROR;
291 }
292 else
293 if(WSAIsBlocking()) {
294 WSASetLastError(WSAEINPROGRESS);
295 return SOCKET_ERROR;
296 }
297 //Close WSAAsyncSelect thread if one was created for this socket
298 FindAndSetAsyncEvent(s, WSA_SELECT_HWND, 0, 0, 0);
299
300 // wait thread termination
301 DosSleep(10);
302 ret = soclose(s);
303
304 if(ret == SOCKET_ERROR) {
305 WSASetLastError(wsaErrno());
306 }
307 else WSASetLastError(NO_ERROR);
308 return ret;
309}
310//******************************************************************************
311//******************************************************************************
312ODINFUNCTION3(int,OS2connect,
313 SOCKET, s,
314 const struct sockaddr *,name,
315 int, namelen)
316{
317 int ret;
318
319 if(!fWSAInitialized) {
320 WSASetLastError(WSANOTINITIALISED);
321 return SOCKET_ERROR;
322 }
323 else
324 if(WSAIsBlocking()) {
325 WSASetLastError(WSAEINPROGRESS);
326 return SOCKET_ERROR;
327 }
328 ret = connect(s, (sockaddr *)name, namelen);
329 // map BSD error codes
330 if(ret == SOCKET_ERROR) {
331 int sockerror = sock_errno();
332 if(sockerror && sockerror < SOCBASEERR) {
333 sockerror += SOCBASEERR;
334 }
335 if(sockerror == SOCEINPROGRESS) {
336 WSASetLastError(WSAEWOULDBLOCK);
337 }
338 else
339 if(sockerror == SOCEOPNOTSUPP) {
340 WSASetLastError(WSAEINVAL);
341 }
342 else WSASetLastError(wsaErrno());
343 }
344 else WSASetLastError(NO_ERROR);
345 return ret;
346}
347//******************************************************************************
348//******************************************************************************
349ODINFUNCTION3(int,OS2ioctlsocket,
350 SOCKET,s,
351 long, cmd,
352 u_long *,argp)
353{
354 int ret;
355
356 if(!fWSAInitialized) {
357 WSASetLastError(WSANOTINITIALISED);
358 return SOCKET_ERROR;
359 }
360 else
361 if(WSAIsBlocking()) {
362 WSASetLastError(WSAEINPROGRESS);
363 return SOCKET_ERROR;
364 }
365 // clear high word (not used in OS/2's tcpip stack)
366 cmd = LOUSHORT(cmd);
367
368 if(cmd != FIONBIO && cmd != FIONREAD && cmd != SIOCATMARK) {
369 WSASetLastError(WSAEINVAL);
370 return SOCKET_ERROR;
371 }
372
373 WSASetLastError(NO_ERROR);
374
375 //check if app want to set a socket, which has an outstanding async select,
376 //to blocking mode
377 if (cmd == FIONBIO) {
378 HWND hwnd;
379 int msg;
380 ULONG lEvent;
381
382 if(QueryAsyncEvent(s, &hwnd, &msg, &lEvent) == TRUE) {
383 if(*argp != 0) {
384 //nothing to do; already non-blocking
385 return NO_ERROR;
386 }
387 else
388 if(lEvent != 0) {
389 dprintf(("Trying to set socket to blocking mode while async select active -> return error!"));
390 WSASetLastError(WSAEINVAL);
391 return SOCKET_ERROR;
392 }
393 }
394 }
395 ret = ioctl(s, cmd, (char *)argp, sizeof(int));
396
397 // Map EOPNOTSUPP to EINVAL
398 int sockerror = sock_errno();
399 if(sockerror && sockerror < SOCBASEERR) {
400 sockerror += SOCBASEERR;
401 }
402
403 if(ret == SOCKET_ERROR && sockerror == SOCEOPNOTSUPP)
404 WSASetLastError(WSAEINVAL);
405 else
406 if(ret == SOCKET_ERROR) {
407 WSASetLastError(wsaErrno());
408 }
409 else WSASetLastError(NO_ERROR);
410 return ret;
411}
412//******************************************************************************
413//******************************************************************************
414ODINFUNCTION3(int,OS2getpeername,
415 SOCKET, s,
416 struct sockaddr *,name,
417 int *, namelen)
418{
419 int ret;
420
421 if(!fWSAInitialized) {
422 WSASetLastError(WSANOTINITIALISED);
423 return SOCKET_ERROR;
424 }
425 else
426 if(WSAIsBlocking()) {
427 WSASetLastError(WSAEINPROGRESS);
428 return SOCKET_ERROR;
429 }
430 else
431 if (namelen == NULL || *namelen < (int)sizeof(struct sockaddr_in)) {
432 WSASetLastError(WSAEFAULT);
433 return SOCKET_ERROR;
434 }
435 ret = getsockname(s, name, namelen);
436 if(ret == SOCKET_ERROR) {
437 WSASetLastError(wsaErrno());
438 }
439 else WSASetLastError(NO_ERROR);
440 return ret;
441}
442//******************************************************************************
443//******************************************************************************
444ODINFUNCTION3(int,OS2getsockname,
445 SOCKET,s,
446 struct sockaddr *,name,
447 int *, namelen)
448{
449 int ret;
450
451 if(!fWSAInitialized) {
452 WSASetLastError(WSANOTINITIALISED);
453 return SOCKET_ERROR;
454 }
455 else
456 if(WSAIsBlocking()) {
457 WSASetLastError(WSAEINPROGRESS);
458 return SOCKET_ERROR;
459 }
460 else
461 if (namelen == NULL || *namelen < (int)sizeof(struct sockaddr_in)) {
462 WSASetLastError(WSAEFAULT);
463 return SOCKET_ERROR;
464 }
465 ret = getsockname(s, name, namelen);
466 if(ret == SOCKET_ERROR) {
467 WSASetLastError(wsaErrno());
468 }
469 else WSASetLastError(NO_ERROR);
470 return ret;
471}
472//******************************************************************************
473//******************************************************************************
474ODINFUNCTION1(u_long,OS2htonl,
475 u_long,hostlong)
476{
477 return(htonl(hostlong));
478}
479//******************************************************************************
480//******************************************************************************
481ODINFUNCTION1(u_short,OS2htons,
482 u_short,hostshort)
483{
484 return(htons(hostshort));
485}
486//******************************************************************************
487//******************************************************************************
488ODINFUNCTION1(u_long,OS2ntohl,
489 u_long,netlong)
490{
491 return(ntohl(netlong));
492}
493//******************************************************************************
494//******************************************************************************
495ODINFUNCTION1(u_short,OS2ntohs,
496 u_short,netshort)
497{
498 return(ntohs(netshort));
499}
500//******************************************************************************
501//******************************************************************************
502ODINFUNCTION1(unsigned long,OS2inet_addr,
503 const char *, cp)
504{
505 dprintf(("WSOCK32: OS2inet_addr(%s)\n",
506 cp));
507
508 return (inet_addr((char *)cp));
509}
510//******************************************************************************
511//******************************************************************************
512ODINFUNCTION1(char *,OS2inet_ntoa,
513 struct in_addr, in)
514{
515 return(inet_ntoa(in));
516}
517//******************************************************************************
518//******************************************************************************
519ODINFUNCTION3(SOCKET,OS2accept, SOCKET, s,
520 struct sockaddr *,addr,
521 int *, addrlen)
522{
523 int ret, msg;
524 HWND hwnd;
525 ULONG lEvent;
526
527 if(!fWSAInitialized) {
528 WSASetLastError(WSANOTINITIALISED);
529 return SOCKET_ERROR;
530 }
531 else
532 if(WSAIsBlocking()) {
533 WSASetLastError(WSAEINPROGRESS);
534 return SOCKET_ERROR;
535 }
536 else
537 if ((addr != NULL) && (addrlen != NULL)) {
538 if (*addrlen < (int)sizeof(struct sockaddr_in)) {
539 WSASetLastError(WSAEFAULT);
540 return SOCKET_ERROR;
541 }
542 }
543 ret = accept(s, addr, addrlen);
544
545 if(ret != SOCKET_ERROR) {
546 //Enable FD_ACCEPT event flag if WSAAsyncSelect was called for this socket
547 EnableAsyncEvent(s, FD_ACCEPT);
548
549 //if this socket has an active async. select pending, then call WSAAsyncSelect
550 //with the same parameters for the new socket (see docs)
551 if(QueryAsyncEvent(s, &hwnd, &msg, &lEvent) == TRUE) {
552 if(WSAAsyncSelect(ret, hwnd, msg, lEvent) == SOCKET_ERROR) {
553 ret = SOCKET_ERROR;
554 }
555 }
556 }
557 if(ret == SOCKET_ERROR) {
558 WSASetLastError(wsaErrno());
559 }
560 else WSASetLastError(NO_ERROR);
561 return ret;
562}
563//******************************************************************************
564//******************************************************************************
565ODINFUNCTION3(int,OS2bind,
566 SOCKET ,s,
567 const struct sockaddr *,addr,
568 int, namelen)
569{
570 int ret;
571
572 if(!fWSAInitialized) {
573 WSASetLastError(WSANOTINITIALISED);
574 return SOCKET_ERROR;
575 }
576 else
577 if(WSAIsBlocking()) {
578 WSASetLastError(WSAEINPROGRESS);
579 return SOCKET_ERROR;
580 }
581 else
582 if(namelen < (int)sizeof(struct sockaddr_in)) {
583 WSASetLastError(WSAEFAULT);
584 return SOCKET_ERROR;
585 }
586 ret = bind(s, (struct sockaddr *)addr, namelen);
587
588 if(ret == SOCKET_ERROR) {
589 WSASetLastError(wsaErrno());
590 }
591 else WSASetLastError(NO_ERROR);
592 return ret;
593}
594//******************************************************************************
595//******************************************************************************
596ODINFUNCTION2(int,OS2listen,
597 SOCKET, s,
598 int, backlog)
599{
600 int ret, tmp, namelen;
601 struct sockaddr_in name;
602
603 if(!fWSAInitialized) {
604 WSASetLastError(WSANOTINITIALISED);
605 return SOCKET_ERROR;
606 }
607 else
608 if(WSAIsBlocking()) {
609 WSASetLastError(WSAEINPROGRESS);
610 return SOCKET_ERROR;
611 }
612 namelen = sizeof(name);
613 ret = getsockname(s, (struct sockaddr *)&name, &namelen);
614 if (ret == 0) {
615 if (name.sin_port == 0 && name.sin_addr.s_addr == 0) {
616 // Socket is not bound
617 WSASetLastError(WSAEINVAL);
618 return SOCKET_ERROR;
619 }
620 ret = ioctl(s, FIOBSTATUS, (char *)&tmp, sizeof(tmp)) &
621 (SS_ISCONNECTING | SS_ISCONNECTED | SS_ISDISCONNECTING);
622 if(ret) {
623 // Socket is already connected
624 WSASetLastError(WSAEISCONN);
625 return SOCKET_ERROR;
626 }
627 ret = listen(s, backlog);
628 //todo: reset FD_ACCEPT bit? (wine seems to do this, but it's not documented)
629 }
630 if(ret == SOCKET_ERROR) {
631 WSASetLastError(wsaErrno());
632 }
633 else WSASetLastError(NO_ERROR);
634 return ret;
635}
636//******************************************************************************
637//******************************************************************************
638ODINFUNCTION4(int,OS2recv,
639 SOCKET,s,
640 char *,buf,
641 int,len,
642 int,flags)
643{
644 int ret;
645
646 if(!fWSAInitialized) {
647 WSASetLastError(WSANOTINITIALISED);
648 return SOCKET_ERROR;
649 }
650 else
651 if(WSAIsBlocking()) {
652 WSASetLastError(WSAEINPROGRESS);
653 return SOCKET_ERROR;
654 }
655 ret = recv(s, buf, len, flags);
656
657 if(ret == SOCKET_ERROR) {
658 WSASetLastError(wsaErrno());
659 }
660 else
661 if(ret == 0) {
662 int tmp, state;
663
664 state = ioctl(s, FIOBSTATUS, (char *)&tmp, sizeof(tmp));
665 if(state & SS_ISCONNECTED && flags != MSG_PEEK) {
666 dprintf(("recv returned 0, but socket is still connected -> return WSAWOULDBLOCK"));
667 WSASetLastError(WSAEWOULDBLOCK);
668 ret = 0; //graceful close
669 }
670 }
671 else WSASetLastError(NO_ERROR);
672
673 //Reset FD_READ event flagfor WSAAsyncSelect thread if one was created for this socket
674 EnableAsyncEvent(s, FD_READ);
675 return ret;
676}
677//******************************************************************************
678//******************************************************************************
679ODINFUNCTION6(int,OS2recvfrom,
680 SOCKET,s,
681 char *,buf,
682 int,len,
683 int,flags,
684 struct sockaddr *,from,
685 int *,fromlen)
686{
687 int ret;
688
689 if(!fWSAInitialized) {
690 WSASetLastError(WSANOTINITIALISED);
691 return SOCKET_ERROR;
692 }
693 else
694 if(WSAIsBlocking()) {
695 WSASetLastError(WSAEINPROGRESS);
696 return SOCKET_ERROR;
697 }
698 else
699 if(fromlen == NULL || *fromlen < (int)sizeof(struct sockaddr_in)) {
700 WSASetLastError(WSAEFAULT);
701 return SOCKET_ERROR;
702 }
703 ret = recvfrom(s, buf, len, flags, from, fromlen);
704
705 if(ret == SOCKET_ERROR) {
706 WSASetLastError(wsaErrno());
707 }
708 else WSASetLastError(NO_ERROR);
709
710 //Reset FD_READ event flagfor WSAAsyncSelect thread if one was created for this socket
711 EnableAsyncEvent(s, FD_READ);
712 return ret;
713}
714//******************************************************************************
715//******************************************************************************
716ODINFUNCTION4(int,OS2send,
717 SOCKET,s,
718 const char *,buf,
719 int,len,
720 int,flags)
721{
722 int ret;
723
724 if(!fWSAInitialized) {
725 WSASetLastError(WSANOTINITIALISED);
726 return SOCKET_ERROR;
727 }
728 else
729 if(WSAIsBlocking()) {
730 WSASetLastError(WSAEINPROGRESS);
731 return SOCKET_ERROR;
732 }
733 ret = send(s, (char *)buf, len, flags);
734
735 if(ret == SOCKET_ERROR) {
736 WSASetLastError(wsaErrno());
737 }
738 else WSASetLastError(NO_ERROR);
739
740 //Reset FD_WRITE event flagfor WSAAsyncSelect thread if one was created for this socket
741 EnableAsyncEvent(s, FD_WRITE);
742 return ret;
743}
744//******************************************************************************
745//******************************************************************************
746ODINFUNCTION6(int,OS2sendto,
747 SOCKET,s,
748 const char *,buf,
749 int,len,
750 int,flags,
751 const struct sockaddr *,to,
752 int,tolen)
753{
754 int ret;
755 int optlen;
756 int option;
757
758 if(!fWSAInitialized) {
759 WSASetLastError(WSANOTINITIALISED);
760 return SOCKET_ERROR;
761 }
762 else
763 if(WSAIsBlocking()) {
764 WSASetLastError(WSAEINPROGRESS);
765 return SOCKET_ERROR;
766 }
767 else
768 if(tolen < (int)sizeof(struct sockaddr_in)) {
769 WSASetLastError(WSAEFAULT);
770 return SOCKET_ERROR;
771 }
772 // check if the socket is a raw socket and has the IP_HDRINCL switch
773 // if this is the case, we overwrite the IP header length field with
774 // the actual length because some apps tend to put in garbage in there
775 // and rely on Windows correcting this
776 optlen = sizeof(option);
777 option = 0;
778 ret = getsockopt(s, IPPROTO_IP, IP_HDRINCL_OS2, (char *)&option, &optlen);
779 if(ret == 0 && option != FALSE) {
780 *(u_short *)&buf[2] = len;
781 }
782 dprintf(("sending to %s", inet_ntoa(((sockaddr_in*)to)->sin_addr)));
783 ret = sendto(s, (char *)buf, len, flags, (struct sockaddr *)to, tolen);
784
785 if(ret == SOCKET_ERROR) {
786 WSASetLastError(wsaErrno());
787 }
788 else WSASetLastError(NO_ERROR);
789
790 //Reset FD_WRITE event flag for WSAAsyncSelect thread if one was created for this socket
791 EnableAsyncEvent(s, FD_WRITE);
792 return ret;
793}
794//******************************************************************************
795//******************************************************************************
796ODINFUNCTION5(int,OS2select,
797 int,nfds,
798 ws_fd_set *,readfds,
799 ws_fd_set *,writefds,
800 ws_fd_set *,exceptfds,
801 const struct timeval *,timeout)
802{
803 int ret, i, j;
804 int *sockets, *socktmp;
805 int nrread, nrwrite, nrexcept;
806 ULONG ttimeout;
807
808 WSASetLastError(NO_ERROR);
809
810 if(!fWSAInitialized) {
811 WSASetLastError(WSANOTINITIALISED);
812 return SOCKET_ERROR;
813 }
814 else
815 if(WSAIsBlocking()) {
816 WSASetLastError(WSAEINPROGRESS);
817 return SOCKET_ERROR;
818 }
819 else {
820 nrread = nrwrite = nrexcept = 0;
821 if(readfds) {
822 nrread += readfds->fd_count;
823 }
824 if(writefds) {
825 nrwrite += writefds->fd_count;
826 }
827 if(exceptfds) {
828 nrexcept += exceptfds->fd_count;
829 }
830#if 0
831 if(nrread + nrwrite + nrexcept == 0) {
832 dprintf(("ERROR: nrread + nrwrite + nrexcept == 0"));
833 WSASetLastError(WSAEINVAL);
834 return SOCKET_ERROR;
835 }
836#endif
837 if(timeout != NULL && (timeout->tv_sec < 0 || timeout->tv_usec < 0)) {
838 dprintf(("ERROR: timeout->tv_sec < 0 || timeout->tv_usec < 0"));
839 WSASetLastError(WSAEINVAL);
840 return SOCKET_ERROR;
841 }
842 if(timeout == NULL) {
843 ttimeout = -1L; // no timeout
844 }
845 else ttimeout = timeout->tv_sec * 1000 + timeout->tv_usec / 1000;
846
847 sockets = (int *)malloc(sizeof(int) * (nrread+nrwrite+nrexcept));
848 if(readfds) {
849 memcpy(&sockets[0], readfds->fd_array, nrread * sizeof(SOCKET));
850 }
851 if(writefds) {
852 memcpy(&sockets[nrread], writefds->fd_array, nrwrite * sizeof(SOCKET));
853 }
854 if(exceptfds) {
855 memcpy(&sockets[nrread+nrwrite], exceptfds->fd_array, nrexcept * sizeof(SOCKET));
856 }
857
858 ret = select(sockets, nrread, nrwrite, nrexcept, ttimeout);
859
860 if(ret == SOCKET_ERROR)
861 {
862 if(readfds != NULL)
863 readfds->fd_count = 0;
864
865 if(writefds != NULL)
866 writefds->fd_count = 0;
867
868 if(exceptfds != NULL)
869 exceptfds->fd_count = 0;
870
871 WSASetLastError(wsaErrno());
872 free(sockets);
873 return SOCKET_ERROR;
874 }
875
876 if(ret != 0) {
877 socktmp = sockets;
878 if(readfds != NULL) {
879 j = 0;
880 for(i=0;i<nrread;i++) {
881 if(socktmp[i] != -1) {
882 readfds->fd_array[i] = socktmp[i];
883 j++;
884 }
885 }
886 readfds->fd_count = j;
887 socktmp += nrread;
888 }
889
890 if(writefds != NULL) {
891 j = 0;
892 for(i=0;i<nrwrite;i++) {
893 if(socktmp[i] != -1) {
894 writefds->fd_array[i] = socktmp[i];
895 j++;
896 }
897 }
898 writefds->fd_count = j;
899 socktmp += nrwrite;
900 }
901 if(exceptfds != NULL) {
902 j = 0;
903 for(i=0;i<nrexcept;i++) {
904 if(socktmp[i] != -1) {
905 exceptfds->fd_array[i] = socktmp[i];
906 j++;
907 }
908 }
909 exceptfds->fd_count = j;
910 }
911 }
912 else {
913 if(readfds != NULL)
914 readfds->fd_count = 0;
915
916 if(writefds != NULL)
917 writefds->fd_count = 0;
918
919 if(exceptfds != NULL)
920 exceptfds->fd_count = 0;
921 }
922 free(sockets);
923 }
924 return ret;
925}
926//******************************************************************************
927//******************************************************************************
928ODINFUNCTION5(int,OS2setsockopt,
929 SOCKET,s,
930 int,level,
931 int,optname,
932 const char *,optval,
933 int,optlen)
934{
935 struct ws_linger *yy;
936 struct linger xx;
937 int ret;
938 ULONG size;
939 char *safeoptval;
940
941 if(!fWSAInitialized) {
942 dprintf(("WSA not initialized"));
943 WSASetLastError(WSANOTINITIALISED);
944 return SOCKET_ERROR;
945 }
946 else
947 if(WSAIsBlocking()) {
948 dprintf(("WSA is blocking"));
949 WSASetLastError(WSAEINPROGRESS);
950 return SOCKET_ERROR;
951 }
952 //SvL: The 16 bits TCP/IP stack doesn't like high addresses, so copy
953 // the option value(s) on the stack.
954 safeoptval = (char *)alloca(optlen);
955 if(safeoptval == NULL) {
956 DebugInt3();
957 WSASetLastError(WSAEFAULT);
958 return SOCKET_ERROR;
959 }
960 memcpy(safeoptval, optval, optlen);
961 optval = safeoptval;
962
963 if (level == SOL_SOCKET)
964 {
965 switch(optname)
966 {
967 case SO_DONTLINGER:
968 case SO_LINGER:
969 if(optlen < (int)sizeof(ws_linger))
970 {
971 dprintf(("SOL_SOCKET, SO_LINGER, optlen too small"));
972 WSASetLastError(WSAEFAULT);
973 return SOCKET_ERROR;
974 }
975 yy = (struct ws_linger *)optval;
976 xx.l_onoff = (optname == SO_DONTLINGER) ? !yy->l_onoff : yy->l_onoff;
977 xx.l_linger = yy->l_linger;
978
979 ret = setsockopt(s,level,optname,(char *)&xx, sizeof(xx));
980 break;
981 case SO_SNDBUF:
982 case SO_RCVBUF:
983 if(optlen < (int)sizeof(int))
984 {
985 dprintf(("SOL_SOCKET, SO_RCVBUF, optlen too small"));
986 WSASetLastError(WSAEFAULT);
987 return SOCKET_ERROR;
988 }
989
990 size = *(ULONG *)optval;
991tryagain:
992 ret = setsockopt(s,level,optname, (char *)&size, sizeof(ULONG));
993 if(ret == SOCKET_ERROR && wsaErrno() == WSAENOBUFS && size > 4096) {
994 int newsize = (size > 65535) ? 63*1024 : (size-1024);
995 dprintf(("setsockopt: change size from %d to %d", size, newsize));
996 //SvL: Limit send & receive buffer length to 64k
997 // (only happens with 16 bits tcpip stack?)
998 size = newsize;
999 goto tryagain;
1000 }
1001 break;
1002
1003 case SO_SNDTIMEO:
1004 case SO_RCVTIMEO:
1005 // convert "int" to "struct timeval"
1006 struct timeval tv;
1007 tv.tv_sec = *optval / 1000;
1008 tv.tv_usec = (*optval % 1000) * 1000;
1009 ret = setsockopt(s, level, optname, (char *)&tv, sizeof(tv) );
1010 break;
1011
1012 case SO_BROADCAST:
1013 case SO_DEBUG:
1014 case SO_KEEPALIVE:
1015 case SO_DONTROUTE:
1016 case SO_OOBINLINE:
1017 case SO_REUSEADDR:
1018 if(optlen < (int)sizeof(int)) {
1019 dprintf(("SOL_SOCKET, SO_REUSEADDR, optlen too small"));
1020 WSASetLastError(WSAEFAULT);
1021 return SOCKET_ERROR;
1022 }
1023 ret = setsockopt(s, level, optname, (char *)optval, optlen);
1024 break;
1025 default:
1026 dprintf(("setsockopt: SOL_SOCKET, unknown option %x", optname));
1027 WSASetLastError(WSAENOPROTOOPT);
1028 return SOCKET_ERROR;
1029 }
1030 }
1031 else
1032 if(level == IPPROTO_TCP)
1033 {
1034 if(optname == TCP_NODELAY) {
1035 if(optlen < (int)sizeof(int)) {
1036 dprintf(("IPPROTO_TCP, TCP_NODELAY, optlen too small"));
1037 WSASetLastError(WSAEFAULT);
1038 return SOCKET_ERROR;
1039 }
1040 ret = setsockopt(s, level, optname, (char *)optval, optlen);
1041 }
1042 else {
1043 dprintf(("setsockopt: IPPROTO_TCP, unknown option %x", optname));
1044 WSASetLastError(WSAENOPROTOOPT);
1045 return SOCKET_ERROR;
1046 }
1047 }
1048 else
1049 if (level == IPPROTO_IP)
1050 {
1051 switch (optname)
1052 {
1053 case IP_MULTICAST_IF:
1054 case WS2_IPPROTO_OPT(IP_MULTICAST_IF_WS2):
1055 {
1056 if (optlen < sizeof(in_addr))
1057 {
1058 dprintf(("IPPROTO_IP, IP_MULTICAST_IP, optlen too small"));
1059 WSASetLastError(WSAEFAULT);
1060 return SOCKET_ERROR;
1061 }
1062 //TODO convert common interface names!
1063 ret = setsockopt(s, IPPROTO_IP, IP_MULTICAST_IF_OS2, (char *)optval, optlen);
1064 break;
1065 }
1066
1067 case IP_ADD_MEMBERSHIP:
1068 case WS2_IPPROTO_OPT(IP_ADD_MEMBERSHIP_WS2):
1069 if (optlen < sizeof(struct ip_mreq))
1070 {
1071 dprintf(("IPPROTO_IP, IP_ADD_MEMBERSHIP, optlen too small"));
1072 WSASetLastError(WSAEFAULT);
1073 return SOCKET_ERROR;
1074 }
1075 ret = setsockopt(s, IPPROTO_IP, IP_ADD_MEMBERSHIP_OS2, (char *)optval, optlen);
1076 break;
1077
1078 case IP_DROP_MEMBERSHIP:
1079 case WS2_IPPROTO_OPT(IP_DROP_MEMBERSHIP_WS2):
1080 if (optlen < sizeof(struct ip_mreq))
1081 {
1082 dprintf(("IPPROTO_IP, IP_DROP_MEMBERSHIP, optlen too small"));
1083 WSASetLastError(WSAEFAULT);
1084 return SOCKET_ERROR;
1085 }
1086 ret = setsockopt(s, IPPROTO_IP, IP_DROP_MEMBERSHIP_OS2, (char *)optval, optlen);
1087 break;
1088
1089 case IP_MULTICAST_LOOP:
1090 case WS2_IPPROTO_OPT(IP_MULTICAST_LOOP_WS2):
1091 {
1092 u_int flLoop;
1093 if (optlen < sizeof(u_char))
1094 {
1095 dprintf(("IPPROTO_IP, IP_MULTICAST_LOOP/IP_MULTICAST_TTL, optlen too small"));
1096 WSASetLastError(WSAEFAULT);
1097 return SOCKET_ERROR;
1098 }
1099 flLoop = (*optval == 0) ? 0 : 1;
1100 dprintf(("IP_MULTICAST_LOOP %d", *optval));
1101 ret = setsockopt(s, IPPROTO_IP, IP_MULTICAST_LOOP_OS2, (char *)&flLoop, optlen);
1102 break;
1103 }
1104
1105 case IP_MULTICAST_TTL:
1106 case WS2_IPPROTO_OPT(IP_MULTICAST_TTL_WS2):
1107 if (optlen < sizeof(u_char))
1108 {
1109 dprintf(("IPPROTO_IP, IP_MULTICAST_TTL, optlen too small"));
1110 WSASetLastError(WSAEFAULT);
1111 return SOCKET_ERROR;
1112 }
1113 ret = setsockopt(s, IPPROTO_IP, IP_MULTICAST_TTL_OS2, (char *)optval, optlen);
1114 break;
1115
1116 case IP_TTL:
1117 case WS2_IPPROTO_OPT(IP_TTL_WS2):
1118 if (optlen < sizeof(u_int))
1119 {
1120 dprintf(("IPPROTO_IP, IP_TTL_WS2, optlen too small"));
1121 WSASetLastError(WSAEFAULT);
1122 return SOCKET_ERROR;
1123 }
1124 dprintf(("IPPROTO_IP, IP_TTL 0x%x", *optval));
1125 ret = setsockopt(s, IPPROTO_IP, IP_TTL_OS2, (char *)optval, optlen);
1126 break;
1127
1128 case IP_TOS:
1129 case WS2_IPPROTO_OPT(IP_TOS_WS2):
1130 if (optlen < sizeof(u_int))
1131 {
1132 dprintf(("IPPROTO_IP, IP_TOS_WS2, optlen too small"));
1133 WSASetLastError(WSAEFAULT);
1134 return SOCKET_ERROR;
1135 }
1136 dprintf(("IPPROTO_IP, IP_TOS 0x%x", *optval));
1137 ret = setsockopt(s, IPPROTO_IP, IP_TOS_OS2, (char *)optval, optlen);
1138 break;
1139
1140 case WS2_IPPROTO_OPT(IP_HDRINCL_WS2):
1141 if (optlen < sizeof(u_int))
1142 {
1143 dprintf(("IPPROTO_IP, IP_HDRINCL_WS2, optlen too small"));
1144 WSASetLastError(WSAEFAULT);
1145 return SOCKET_ERROR;
1146 }
1147 dprintf(("IPPROTO_IP, IP_HDRINCL 0x%x", *optval));
1148 ret = setsockopt(s, IPPROTO_IP, IP_HDRINCL_OS2, (char *)optval, optlen);
1149 break;
1150
1151 default:
1152 dprintf(("setsockopt: IPPROTO_IP, unknown option %x", optname));
1153 WSASetLastError(WSAENOPROTOOPT);
1154 return SOCKET_ERROR;
1155 }
1156 }
1157 else {
1158 dprintf(("unknown level code!"));
1159 WSASetLastError(WSAEINVAL);
1160 return SOCKET_ERROR;
1161 }
1162
1163 if(ret == SOCKET_ERROR) {
1164 WSASetLastError(wsaErrno());
1165 }
1166 else WSASetLastError(NO_ERROR);
1167 return ret;
1168}
1169//******************************************************************************
1170//******************************************************************************
1171ODINFUNCTION5(int,OS2getsockopt,
1172 SOCKET, s,
1173 int, level,
1174 int, optname,
1175 char *, optval,
1176 int *,optlen)
1177{
1178 struct ws_linger *yy;
1179 struct linger xx;
1180 int ret;
1181 int size, options;
1182
1183 if(!fWSAInitialized) {
1184 WSASetLastError(WSANOTINITIALISED);
1185 return SOCKET_ERROR;
1186 }
1187 else
1188 if(WSAIsBlocking()) {
1189 WSASetLastError(WSAEINPROGRESS);
1190 return SOCKET_ERROR;
1191 }
1192 if (level == SOL_SOCKET) {
1193 switch(optname) {
1194 case SO_DONTLINGER:
1195 case SO_LINGER:
1196 if(optlen == NULL || *optlen < sizeof(ws_linger)) {
1197 WSASetLastError(WSAEFAULT);
1198 return SOCKET_ERROR;
1199 }
1200 size = sizeof(xx);
1201 ret = getsockopt(s,level,optname,(char *)&xx, &size);
1202 yy = (struct ws_linger *)optval;
1203 yy->l_onoff = (optname == SO_DONTLINGER) ? !xx.l_onoff : xx.l_onoff;
1204 yy->l_linger = xx.l_linger;
1205 *optlen = size;
1206 break;
1207
1208 case SO_SNDBUF:
1209 case SO_RCVBUF:
1210 case SO_BROADCAST:
1211 case SO_DEBUG:
1212 case SO_KEEPALIVE:
1213 case SO_DONTROUTE:
1214 case SO_OOBINLINE:
1215 case SO_REUSEADDR:
1216 case SO_TYPE:
1217 if(optlen == NULL || *optlen < sizeof(int)) {
1218 WSASetLastError(WSAEFAULT);
1219 return SOCKET_ERROR;
1220 }
1221 ret = getsockopt(s, level, optname, (char *)optval, optlen);
1222 break;
1223 case SO_ACCEPTCONN:
1224 if(optlen == NULL || *optlen < sizeof(int)) {
1225 WSASetLastError(WSAEFAULT);
1226 return SOCKET_ERROR;
1227 }
1228 size = sizeof(options);
1229 ret = getsockopt(s, SOL_SOCKET, SO_OPTIONS, (char *)&options, &size);
1230 if(ret != SOCKET_ERROR) {
1231 *(BOOL *)optval = (options & SO_ACCEPTCONN) == SO_ACCEPTCONN;
1232 *optlen = sizeof(BOOL);
1233 }
1234 break;
1235 default:
1236 dprintf(("getsockopt: unknown option %x", optname));
1237 WSASetLastError(WSAENOPROTOOPT);
1238 return SOCKET_ERROR;
1239 }
1240 }
1241 else
1242 if(level == IPPROTO_TCP) {
1243 if(optname == TCP_NODELAY) {
1244 if(optlen == NULL || *optlen < sizeof(int)) {
1245 WSASetLastError(WSAEFAULT);
1246 return SOCKET_ERROR;
1247 }
1248 ret = getsockopt(s, level, optname, (char *)optval, optlen);
1249 }
1250 else {
1251 dprintf(("getsockopt: unknown option %x", optname));
1252 WSASetLastError(WSAENOPROTOOPT);
1253 return SOCKET_ERROR;
1254 }
1255 }
1256 else
1257 if(level == IPPROTO_IP) {
1258 switch (optname)
1259 {
1260 case IP_MULTICAST_IF:
1261 case WS2_IPPROTO_OPT(IP_MULTICAST_IF_WS2):
1262 {
1263 if (*optlen < sizeof(in_addr))
1264 {
1265 dprintf(("IPPROTO_IP, IP_MULTICAST_IP, optlen too small"));
1266 WSASetLastError(WSAEFAULT);
1267 return SOCKET_ERROR;
1268 }
1269 //TODO convert common interface names!
1270 ret = getsockopt(s, IPPROTO_IP, IP_MULTICAST_IF_OS2, (char *)optval, optlen);
1271 break;
1272 }
1273
1274 case IP_ADD_MEMBERSHIP:
1275 case WS2_IPPROTO_OPT(IP_ADD_MEMBERSHIP_WS2):
1276 if (*optlen < sizeof(struct ip_mreq))
1277 {
1278 dprintf(("IPPROTO_IP, IP_ADD_MEMBERSHIP, optlen too small"));
1279 WSASetLastError(WSAEFAULT);
1280 return SOCKET_ERROR;
1281 }
1282 ret = getsockopt(s, IPPROTO_IP, IP_ADD_MEMBERSHIP_OS2, (char *)optval, optlen);
1283 break;
1284
1285 case IP_DROP_MEMBERSHIP:
1286 case WS2_IPPROTO_OPT(IP_DROP_MEMBERSHIP_WS2):
1287 if (*optlen < sizeof(struct ip_mreq))
1288 {
1289 dprintf(("IPPROTO_IP, IP_DROP_MEMBERSHIP, optlen too small"));
1290 WSASetLastError(WSAEFAULT);
1291 return SOCKET_ERROR;
1292 }
1293 ret = getsockopt(s, IPPROTO_IP, IP_DROP_MEMBERSHIP_OS2, (char *)optval, optlen);
1294 break;
1295
1296 case IP_MULTICAST_LOOP:
1297 case WS2_IPPROTO_OPT(IP_MULTICAST_LOOP_WS2):
1298 {
1299 if (*optlen < sizeof(u_char))
1300 {
1301 dprintf(("IPPROTO_IP, IP_MULTICAST_LOOP/IP_MULTICAST_TTL, optlen too small"));
1302 WSASetLastError(WSAEFAULT);
1303 return SOCKET_ERROR;
1304 }
1305 ret = getsockopt(s, IPPROTO_IP, IP_MULTICAST_LOOP_OS2, (char *)optval, optlen);
1306 break;
1307 }
1308
1309 case IP_MULTICAST_TTL:
1310 case WS2_IPPROTO_OPT(IP_MULTICAST_TTL_WS2):
1311 if (*optlen < sizeof(u_char))
1312 {
1313 dprintf(("IPPROTO_IP, IP_MULTICAST_TTL, optlen too small"));
1314 WSASetLastError(WSAEFAULT);
1315 return SOCKET_ERROR;
1316 }
1317 ret = getsockopt(s, IPPROTO_IP, IP_MULTICAST_TTL_OS2, (char *)optval, optlen);
1318 break;
1319
1320 case IP_TTL:
1321 case WS2_IPPROTO_OPT(IP_TTL_WS2):
1322 if (*optlen < sizeof(u_int))
1323 {
1324 dprintf(("IPPROTO_IP, IP_TTL_WS2, optlen too small"));
1325 WSASetLastError(WSAEFAULT);
1326 return SOCKET_ERROR;
1327 }
1328 ret = getsockopt(s, IPPROTO_IP, IP_TTL_OS2, (char *)optval, optlen);
1329 break;
1330
1331 case IP_TOS:
1332 case WS2_IPPROTO_OPT(IP_TOS_WS2):
1333 if (*optlen < sizeof(u_int))
1334 {
1335 dprintf(("IPPROTO_IP, IP_TOS_WS2, optlen too small"));
1336 WSASetLastError(WSAEFAULT);
1337 return SOCKET_ERROR;
1338 }
1339 ret = getsockopt(s, IPPROTO_IP, IP_TOS_OS2, (char *)optval, optlen);
1340 break;
1341
1342 case WS2_IPPROTO_OPT(IP_HDRINCL_WS2):
1343 if (*optlen < sizeof(u_int))
1344 {
1345 dprintf(("IPPROTO_IP, IP_HDRINCL_WS2, optlen too small"));
1346 WSASetLastError(WSAEFAULT);
1347 return SOCKET_ERROR;
1348 }
1349 ret = getsockopt(s, IPPROTO_IP, IP_HDRINCL_OS2, (char *)optval, optlen);
1350 if(ret == 0) {
1351 ret = (ret != FALSE) ? TRUE : FALSE;
1352 }
1353 break;
1354
1355 default:
1356 dprintf(("getsockopt: IPPROTO_IP, unknown option %x", optname));
1357 WSASetLastError(WSAENOPROTOOPT);
1358 return SOCKET_ERROR;
1359 }
1360 }
1361 else {
1362 WSASetLastError(WSAEINVAL);
1363 return SOCKET_ERROR;
1364 }
1365
1366 if(ret == SOCKET_ERROR) {
1367 WSASetLastError(wsaErrno());
1368 }
1369 else WSASetLastError(NO_ERROR);
1370 return ret;
1371}
1372//******************************************************************************
1373//******************************************************************************
1374/* Database function prototypes */
1375//******************************************************************************
1376//******************************************************************************
1377ODINFUNCTION2(int,OS2gethostname,
1378 char *,name,
1379 int,namelen)
1380{
1381 int ret;
1382
1383 ret = gethostname(name, namelen);
1384 if(ret == NULL) {
1385 dprintf(("gethostname returned %s", name));
1386 WSASetLastError(NO_ERROR);
1387 return 0;
1388 }
1389 WSASetLastError((errno == EINVAL) ? WSAEFAULT : wsaErrno());
1390 return SOCKET_ERROR;
1391}
1392//******************************************************************************
1393//******************************************************************************
1394ODINFUNCTION3(ws_hostent *,OS2gethostbyaddr,
1395 const char *,addr,
1396 int,len,
1397 int,type)
1398{
1399 LPWSINFO pwsi = WINSOCK_GetIData();
1400
1401 if( pwsi )
1402 {
1403 struct hostent* host;
1404 if( (host = gethostbyaddr((char *)addr, len, type)) != NULL ) {
1405 if( WS_dup_he(pwsi, host) ) {
1406 WSASetLastError(NO_ERROR);
1407 return pwsi->he;
1408 }
1409 else WSASetLastError(WSAENOBUFS);
1410 }
1411 else WSASetLastError((h_errno < 0) ? wsaErrno() : wsaHerrno());
1412 }
1413 else WSASetLastError(WSANOTINITIALISED);
1414 return NULL;
1415}
1416//******************************************************************************
1417//NOTE: This function can possibly block for a very long time
1418// I.e. start ISDNPM without dialing in. gethostbyname will query
1419// each name server and retry several times (60+ seconds per name server)
1420//******************************************************************************
1421ODINFUNCTION1(ws_hostent *,OS2gethostbyname,
1422 const char *,name)
1423{
1424 LPWSINFO pwsi = WINSOCK_GetIData();
1425
1426 if( pwsi )
1427 {
1428 struct hostent* host;
1429
1430 dprintf(("gethostbyname %s", name));
1431
1432 host = gethostbyname( (char*) name);
1433
1434 if( host != NULL )
1435 {
1436 if( WS_dup_he(pwsi, host) )
1437 {
1438 WSASetLastError(NO_ERROR);
1439 return pwsi->he;
1440 }
1441 else
1442 WSASetLastError(WSAENOBUFS);
1443 }
1444 else
1445 WSASetLastError((h_errno < 0) ? wsaErrno() : wsaHerrno());
1446 }
1447 else
1448 WSASetLastError(WSANOTINITIALISED);
1449
1450 return NULL;
1451}
1452//******************************************************************************
1453//******************************************************************************
1454ODINFUNCTION2(struct ws_servent *,OS2getservbyport,
1455 int, port,
1456 const char *, proto)
1457{
1458 LPWSINFO pwsi = WINSOCK_GetIData();
1459
1460 if( pwsi )
1461 {
1462 struct servent* serv;
1463 if( (serv = getservbyport(port, (char *)proto)) != NULL ) {
1464 if( WS_dup_se(pwsi, serv) ) {
1465 WSASetLastError(NO_ERROR);
1466 return pwsi->se;
1467 }
1468 else WSASetLastError(WSAENOBUFS);
1469 }
1470 else WSASetLastError(WSANO_DATA);
1471 }
1472 else WSASetLastError(WSANOTINITIALISED);
1473 return NULL;
1474}
1475//******************************************************************************
1476//******************************************************************************
1477ODINFUNCTION2(struct ws_servent *,OS2getservbyname,
1478 const char *, name,
1479 const char *, proto)
1480{
1481 LPWSINFO pwsi = WINSOCK_GetIData();
1482
1483 if( pwsi )
1484 {
1485 struct servent *serv;
1486 if( (serv = getservbyname((char *)name, (char *)proto)) != NULL ) {
1487 if( WS_dup_se(pwsi, serv) ) {
1488 WSASetLastError(NO_ERROR);
1489 return pwsi->se;
1490 }
1491 else WSASetLastError(WSAENOBUFS);
1492 }
1493 else WSASetLastError(WSANO_DATA);
1494 }
1495 else WSASetLastError(WSANOTINITIALISED);
1496 return NULL;
1497}
1498//******************************************************************************
1499//******************************************************************************
1500ODINFUNCTION1(struct ws_protoent *,OS2getprotobynumber,
1501 int,number)
1502{
1503 LPWSINFO pwsi = WINSOCK_GetIData();
1504
1505 if( pwsi )
1506 {
1507 struct protoent* proto;
1508 if( (proto = getprotobynumber(number)) != NULL ) {
1509 if( WS_dup_pe(pwsi, proto) ) {
1510 WSASetLastError(NO_ERROR);
1511 return pwsi->pe;
1512 }
1513 else WSASetLastError(WSAENOBUFS);
1514 }
1515 else WSASetLastError(WSANO_DATA);
1516 }
1517 else WSASetLastError(WSANOTINITIALISED);
1518 return NULL;
1519}
1520//******************************************************************************
1521//******************************************************************************
1522ODINFUNCTION1(struct ws_protoent *,OS2getprotobyname,
1523 const char *,name)
1524{
1525 LPWSINFO pwsi = WINSOCK_GetIData();
1526
1527 if( pwsi )
1528 {
1529 struct protoent * proto;
1530 if( (proto = getprotobyname((char *)name)) != NULL ) {
1531 if(WS_dup_pe(pwsi, proto)) {
1532 WSASetLastError(NO_ERROR);
1533 return pwsi->pe;
1534 }
1535 else WSASetLastError(WSAENOBUFS);
1536 }
1537 else WSASetLastError((h_errno < 0) ? wsaErrno() : wsaHerrno());
1538 }
1539 else WSASetLastError(WSANOTINITIALISED);
1540 return NULL;
1541}
1542//******************************************************************************
1543//******************************************************************************
Note: See TracBrowser for help on using the repository browser.