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

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

wrong socket

File size: 45.8 KB
Line 
1/* $Id: wsock32.cpp,v 1.48 2002-02-20 16:08: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 ULONG ulNotifyHandle, ulNotifyData;
379 int mode;
380 ULONG lEvent;
381
382 if(QueryAsyncEvent(s, &mode, &ulNotifyHandle, &ulNotifyData, &lEvent) == TRUE)
383 {
384 if(*argp != 0) {
385 //nothing to do; already non-blocking
386 return NO_ERROR;
387 }
388 else
389 if(lEvent != 0) {
390 dprintf(("Trying to set socket to blocking mode while async select active -> return error!"));
391 WSASetLastError(WSAEINVAL);
392 return SOCKET_ERROR;
393 }
394 }
395 }
396 ret = ioctl(s, cmd, (char *)argp, sizeof(int));
397
398 // Map EOPNOTSUPP to EINVAL
399 int sockerror = sock_errno();
400 if(sockerror && sockerror < SOCBASEERR) {
401 sockerror += SOCBASEERR;
402 }
403
404 if(ret == SOCKET_ERROR && sockerror == SOCEOPNOTSUPP)
405 WSASetLastError(WSAEINVAL);
406 else
407 if(ret == SOCKET_ERROR) {
408 WSASetLastError(wsaErrno());
409 }
410 else WSASetLastError(NO_ERROR);
411 return ret;
412}
413//******************************************************************************
414//******************************************************************************
415ODINFUNCTION3(int,OS2getpeername,
416 SOCKET, s,
417 struct sockaddr *,name,
418 int *, namelen)
419{
420 int ret;
421
422 if(!fWSAInitialized) {
423 WSASetLastError(WSANOTINITIALISED);
424 return SOCKET_ERROR;
425 }
426 else
427 if(WSAIsBlocking()) {
428 WSASetLastError(WSAEINPROGRESS);
429 return SOCKET_ERROR;
430 }
431 else
432 if (namelen == NULL || *namelen < (int)sizeof(struct sockaddr_in)) {
433 WSASetLastError(WSAEFAULT);
434 return SOCKET_ERROR;
435 }
436 ret = getsockname(s, name, namelen);
437 if(ret == SOCKET_ERROR) {
438 WSASetLastError(wsaErrno());
439 }
440 else WSASetLastError(NO_ERROR);
441 return ret;
442}
443//******************************************************************************
444//******************************************************************************
445ODINFUNCTION3(int,OS2getsockname,
446 SOCKET,s,
447 struct sockaddr *,name,
448 int *, namelen)
449{
450 int ret;
451
452 if(!fWSAInitialized) {
453 WSASetLastError(WSANOTINITIALISED);
454 return SOCKET_ERROR;
455 }
456 else
457 if(WSAIsBlocking()) {
458 WSASetLastError(WSAEINPROGRESS);
459 return SOCKET_ERROR;
460 }
461 else
462 if (namelen == NULL || *namelen < (int)sizeof(struct sockaddr_in)) {
463 WSASetLastError(WSAEFAULT);
464 return SOCKET_ERROR;
465 }
466 ret = getsockname(s, name, namelen);
467 if(ret == SOCKET_ERROR) {
468 WSASetLastError(wsaErrno());
469 }
470 else WSASetLastError(NO_ERROR);
471 return ret;
472}
473//******************************************************************************
474//******************************************************************************
475ODINFUNCTION1(u_long,OS2htonl,
476 u_long,hostlong)
477{
478 return(htonl(hostlong));
479}
480//******************************************************************************
481//******************************************************************************
482ODINFUNCTION1(u_short,OS2htons,
483 u_short,hostshort)
484{
485 return(htons(hostshort));
486}
487//******************************************************************************
488//******************************************************************************
489ODINFUNCTION1(u_long,OS2ntohl,
490 u_long,netlong)
491{
492 return(ntohl(netlong));
493}
494//******************************************************************************
495//******************************************************************************
496ODINFUNCTION1(u_short,OS2ntohs,
497 u_short,netshort)
498{
499 return(ntohs(netshort));
500}
501//******************************************************************************
502//******************************************************************************
503ODINFUNCTION1(unsigned long,OS2inet_addr,
504 const char *, cp)
505{
506 dprintf(("WSOCK32: OS2inet_addr(%s)\n",
507 cp));
508
509 return (inet_addr((char *)cp));
510}
511//******************************************************************************
512//******************************************************************************
513ODINFUNCTION1(char *,OS2inet_ntoa,
514 struct in_addr, in)
515{
516 return(inet_ntoa(in));
517}
518//******************************************************************************
519//******************************************************************************
520ODINFUNCTION3(SOCKET,OS2accept, SOCKET, s,
521 struct sockaddr *,addr,
522 int *, addrlen)
523{
524 int ret, mode;
525 ULONG lEvent, notifyData, notifyHandle;
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, &mode, &notifyHandle, &notifyData, &lEvent) == TRUE) {
552 if(WSAAsyncSelectWorker(ret, mode, notifyHandle, notifyData, 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 return SOCKET_ERROR;
660 }
661 else
662 if(ret == 0) {
663 int tmp, state;
664
665 state = ioctl(s, FIOBSTATUS, (char *)&tmp, sizeof(tmp));
666 if(state & SS_CANTRCVMORE) {
667 dprintf(("recv returned 0, socket is no longer connected -> return WSAENOTCONN"));
668 WSASetLastError(WSANO_DATA);
669 return 0; //graceful close
670 }
671 else
672 if(state & (SS_ISDISCONNECTING|SS_ISDISCONNECTED)) {
673 dprintf(("recv returned 0, socket is no longer connected -> return WSAENOTCONN"));
674 WSASetLastError(WSAENOTCONN);
675 return 0; //graceful close
676 }
677 else
678 if(state & SS_ISCONNECTED && flags != MSG_PEEK) {
679 dprintf(("recv returned 0, but socket is still connected -> return WSAWOULDBLOCK"));
680 WSASetLastError(WSAEWOULDBLOCK);
681 return SOCKET_ERROR;
682 }
683 }
684 else WSASetLastError(NO_ERROR);
685
686 //Reset FD_READ event flagfor WSAAsyncSelect thread if one was created for this socket
687 EnableAsyncEvent(s, FD_READ);
688 return ret;
689}
690//******************************************************************************
691//******************************************************************************
692ODINFUNCTION6(int,OS2recvfrom,
693 SOCKET,s,
694 char *,buf,
695 int,len,
696 int,flags,
697 struct sockaddr *,from,
698 int *,fromlen)
699{
700 int ret;
701
702 if(!fWSAInitialized) {
703 WSASetLastError(WSANOTINITIALISED);
704 return SOCKET_ERROR;
705 }
706 else
707 if(WSAIsBlocking()) {
708 WSASetLastError(WSAEINPROGRESS);
709 return SOCKET_ERROR;
710 }
711 else
712 if(fromlen == NULL || *fromlen < (int)sizeof(struct sockaddr_in)) {
713 WSASetLastError(WSAEFAULT);
714 return SOCKET_ERROR;
715 }
716 ret = recvfrom(s, buf, len, flags, from, fromlen);
717
718 if(ret == SOCKET_ERROR) {
719 WSASetLastError(wsaErrno());
720 }
721 else WSASetLastError(NO_ERROR);
722
723 //Reset FD_READ event flagfor WSAAsyncSelect thread if one was created for this socket
724 EnableAsyncEvent(s, FD_READ);
725 return ret;
726}
727//******************************************************************************
728//******************************************************************************
729ODINFUNCTION4(int,OS2send,
730 SOCKET,s,
731 const char *,buf,
732 int,len,
733 int,flags)
734{
735 int ret;
736
737 if(!fWSAInitialized) {
738 WSASetLastError(WSANOTINITIALISED);
739 return SOCKET_ERROR;
740 }
741 else
742 if(WSAIsBlocking()) {
743 WSASetLastError(WSAEINPROGRESS);
744 return SOCKET_ERROR;
745 }
746 ret = send(s, (char *)buf, len, flags);
747
748 if(ret == SOCKET_ERROR) {
749 WSASetLastError(wsaErrno());
750 }
751 else WSASetLastError(NO_ERROR);
752
753 //Reset FD_WRITE event flagfor WSAAsyncSelect thread if one was created for this socket
754 EnableAsyncEvent(s, FD_WRITE);
755 return ret;
756}
757//******************************************************************************
758//******************************************************************************
759ODINFUNCTION6(int,OS2sendto,
760 SOCKET,s,
761 const char *,buf,
762 int,len,
763 int,flags,
764 const struct sockaddr *,to,
765 int,tolen)
766{
767 int ret;
768 int optlen;
769 int option;
770
771 if(!fWSAInitialized) {
772 WSASetLastError(WSANOTINITIALISED);
773 return SOCKET_ERROR;
774 }
775 else
776 if(WSAIsBlocking()) {
777 WSASetLastError(WSAEINPROGRESS);
778 return SOCKET_ERROR;
779 }
780 else
781 if(tolen < (int)sizeof(struct sockaddr_in)) {
782 WSASetLastError(WSAEFAULT);
783 return SOCKET_ERROR;
784 }
785 // check if the socket is a raw socket and has the IP_HDRINCL switch
786 // if this is the case, we overwrite the IP header length field with
787 // the actual length because some apps tend to put in garbage in there
788 // and rely on Windows correcting this
789 optlen = sizeof(option);
790 option = 0;
791 ret = getsockopt(s, IPPROTO_IP, IP_HDRINCL_OS2, (char *)&option, &optlen);
792 if(ret == 0 && option != FALSE) {
793 *(u_short *)&buf[2] = len;
794 }
795 dprintf(("sending to %s", inet_ntoa(((sockaddr_in*)to)->sin_addr)));
796 ret = sendto(s, (char *)buf, len, flags, (struct sockaddr *)to, tolen);
797
798 if(ret == SOCKET_ERROR) {
799 WSASetLastError(wsaErrno());
800 }
801 else WSASetLastError(NO_ERROR);
802
803 //Reset FD_WRITE event flag for WSAAsyncSelect thread if one was created for this socket
804 EnableAsyncEvent(s, FD_WRITE);
805 return ret;
806}
807//******************************************************************************
808//******************************************************************************
809ODINFUNCTION5(int,OS2select,
810 int,nfds,
811 ws_fd_set *,readfds,
812 ws_fd_set *,writefds,
813 ws_fd_set *,exceptfds,
814 const struct timeval *,timeout)
815{
816 int ret, i, j;
817 int *sockets, *socktmp;
818 int nrread, nrwrite, nrexcept;
819 ULONG ttimeout;
820
821 WSASetLastError(NO_ERROR);
822
823 if(!fWSAInitialized) {
824 WSASetLastError(WSANOTINITIALISED);
825 return SOCKET_ERROR;
826 }
827 else
828 if(WSAIsBlocking()) {
829 WSASetLastError(WSAEINPROGRESS);
830 return SOCKET_ERROR;
831 }
832 else {
833 nrread = nrwrite = nrexcept = 0;
834 if(readfds) {
835 nrread += readfds->fd_count;
836 }
837 if(writefds) {
838 nrwrite += writefds->fd_count;
839 }
840 if(exceptfds) {
841 nrexcept += exceptfds->fd_count;
842 }
843#if 0
844 if(nrread + nrwrite + nrexcept == 0) {
845 dprintf(("ERROR: nrread + nrwrite + nrexcept == 0"));
846 WSASetLastError(WSAEINVAL);
847 return SOCKET_ERROR;
848 }
849#endif
850 if(timeout != NULL && (timeout->tv_sec < 0 || timeout->tv_usec < 0)) {
851 dprintf(("ERROR: timeout->tv_sec < 0 || timeout->tv_usec < 0"));
852 WSASetLastError(WSAEINVAL);
853 return SOCKET_ERROR;
854 }
855 if(timeout == NULL) {
856 ttimeout = -1L; // no timeout
857 }
858 else ttimeout = timeout->tv_sec * 1000 + timeout->tv_usec / 1000;
859
860 sockets = (int *)malloc(sizeof(int) * (nrread+nrwrite+nrexcept));
861 if(readfds) {
862 memcpy(&sockets[0], readfds->fd_array, nrread * sizeof(SOCKET));
863 }
864 if(writefds) {
865 memcpy(&sockets[nrread], writefds->fd_array, nrwrite * sizeof(SOCKET));
866 }
867 if(exceptfds) {
868 memcpy(&sockets[nrread+nrwrite], exceptfds->fd_array, nrexcept * sizeof(SOCKET));
869 }
870
871 ret = select(sockets, nrread, nrwrite, nrexcept, ttimeout);
872
873 if(ret == SOCKET_ERROR)
874 {
875 if(readfds != NULL)
876 readfds->fd_count = 0;
877
878 if(writefds != NULL)
879 writefds->fd_count = 0;
880
881 if(exceptfds != NULL)
882 exceptfds->fd_count = 0;
883
884 WSASetLastError(wsaErrno());
885 free(sockets);
886 return SOCKET_ERROR;
887 }
888
889 if(ret != 0) {
890 socktmp = sockets;
891 if(readfds != NULL) {
892 j = 0;
893 for(i=0;i<nrread;i++) {
894 if(socktmp[i] != -1) {
895 readfds->fd_array[i] = socktmp[i];
896 j++;
897 }
898 }
899 readfds->fd_count = j;
900 socktmp += nrread;
901 }
902
903 if(writefds != NULL) {
904 j = 0;
905 for(i=0;i<nrwrite;i++) {
906 if(socktmp[i] != -1) {
907 writefds->fd_array[i] = socktmp[i];
908 j++;
909 }
910 }
911 writefds->fd_count = j;
912 socktmp += nrwrite;
913 }
914 if(exceptfds != NULL) {
915 j = 0;
916 for(i=0;i<nrexcept;i++) {
917 if(socktmp[i] != -1) {
918 exceptfds->fd_array[i] = socktmp[i];
919 j++;
920 }
921 }
922 exceptfds->fd_count = j;
923 }
924 }
925 else {
926 if(readfds != NULL)
927 readfds->fd_count = 0;
928
929 if(writefds != NULL)
930 writefds->fd_count = 0;
931
932 if(exceptfds != NULL)
933 exceptfds->fd_count = 0;
934 }
935 free(sockets);
936 }
937 return ret;
938}
939//******************************************************************************
940//******************************************************************************
941ODINFUNCTION5(int,OS2setsockopt,
942 SOCKET,s,
943 int,level,
944 int,optname,
945 const char *,optval,
946 int,optlen)
947{
948 struct ws_linger *yy;
949 struct linger xx;
950 int ret, val;
951 ULONG size;
952 char *safeoptval;
953
954 if(!fWSAInitialized) {
955 dprintf(("WSA not initialized"));
956 WSASetLastError(WSANOTINITIALISED);
957 return SOCKET_ERROR;
958 }
959 else
960 if(WSAIsBlocking()) {
961 dprintf(("WSA is blocking"));
962 WSASetLastError(WSAEINPROGRESS);
963 return SOCKET_ERROR;
964 }
965 //SvL: The 16 bits TCP/IP stack doesn't like high addresses, so copy
966 // the option value(s) on the stack.
967 safeoptval = (char *)alloca(optlen);
968 if(safeoptval == NULL) {
969 DebugInt3();
970 WSASetLastError(WSAEFAULT);
971 return SOCKET_ERROR;
972 }
973 memcpy(safeoptval, optval, optlen);
974 optval = safeoptval;
975
976 if (level == SOL_SOCKET)
977 {
978 switch(optname)
979 {
980 case SO_DONTLINGER:
981 case SO_LINGER:
982 if(optlen < (int)sizeof(ws_linger))
983 {
984 dprintf(("SOL_SOCKET, SO_LINGER, optlen too small"));
985 WSASetLastError(WSAEFAULT);
986 return SOCKET_ERROR;
987 }
988 yy = (struct ws_linger *)optval;
989 dprintf(("%s: onoff %x linger %x", (optname == SO_DONTLINGER) ? "SO_DONTLINGER" : "SO_LINGER", (int)yy->l_onoff, (int)yy->l_linger));
990 xx.l_onoff = (optname == SO_DONTLINGER) ? !yy->l_onoff : yy->l_onoff;
991 xx.l_linger = yy->l_linger;
992
993 ret = setsockopt(s,level,optname,(char *)&xx, sizeof(xx));
994 break;
995 case SO_SNDBUF:
996 case SO_RCVBUF:
997 if(optlen < (int)sizeof(int))
998 {
999 dprintf(("SOL_SOCKET, SO_RCVBUF, optlen too small"));
1000 WSASetLastError(WSAEFAULT);
1001 return SOCKET_ERROR;
1002 }
1003
1004 size = *(ULONG *)optval;
1005tryagain:
1006 ret = setsockopt(s,level,optname, (char *)&size, sizeof(ULONG));
1007 if(ret == SOCKET_ERROR && wsaErrno() == WSAENOBUFS && size > 4096) {
1008 int newsize = (size > 65535) ? 63*1024 : (size-1024);
1009 dprintf(("setsockopt: change size from %d to %d", size, newsize));
1010 //SvL: Limit send & receive buffer length to 64k
1011 // (only happens with 16 bits tcpip stack?)
1012 size = newsize;
1013 goto tryagain;
1014 }
1015 break;
1016
1017 case SO_SNDTIMEO:
1018 case SO_RCVTIMEO:
1019 // convert "int" to "struct timeval"
1020 struct timeval tv;
1021 tv.tv_sec = *optval / 1000;
1022 tv.tv_usec = (*optval % 1000) * 1000;
1023 ret = setsockopt(s, level, optname, (char *)&tv, sizeof(tv) );
1024 break;
1025
1026 case SO_BROADCAST:
1027 case SO_DEBUG:
1028 case SO_KEEPALIVE:
1029 case SO_DONTROUTE:
1030 case SO_OOBINLINE:
1031 case SO_REUSEADDR:
1032 if(optlen < (int)sizeof(int)) {
1033 dprintf(("SOL_SOCKET, SO_REUSEADDR, optlen too small"));
1034 WSASetLastError(WSAEFAULT);
1035 return SOCKET_ERROR;
1036 }
1037 ret = setsockopt(s, level, optname, (char *)optval, optlen);
1038 break;
1039 default:
1040 dprintf(("setsockopt: SOL_SOCKET, unknown option %x", optname));
1041 WSASetLastError(WSAENOPROTOOPT);
1042 return SOCKET_ERROR;
1043 }
1044 }
1045 else
1046 if(level == IPPROTO_TCP)
1047 {
1048 if(optname == TCP_NODELAY) {
1049 if(optlen < (int)sizeof(int)) {
1050 dprintf(("IPPROTO_TCP, TCP_NODELAY, optlen too small"));
1051 WSASetLastError(WSAEFAULT);
1052 return SOCKET_ERROR;
1053 }
1054 ret = setsockopt(s, level, optname, (char *)optval, optlen);
1055 }
1056 else {
1057 dprintf(("setsockopt: IPPROTO_TCP, unknown option %x", optname));
1058 WSASetLastError(WSAENOPROTOOPT);
1059 return SOCKET_ERROR;
1060 }
1061 }
1062 else
1063 if (level == IPPROTO_IP)
1064 {
1065 switch (optname)
1066 {
1067 case IP_MULTICAST_IF:
1068 case WS2_IPPROTO_OPT(IP_MULTICAST_IF_WS2):
1069 {
1070 if (optlen < sizeof(in_addr))
1071 {
1072 dprintf(("IPPROTO_IP, IP_MULTICAST_IP, optlen too small"));
1073 WSASetLastError(WSAEFAULT);
1074 return SOCKET_ERROR;
1075 }
1076 //TODO convert common interface names!
1077 ret = setsockopt(s, IPPROTO_IP, IP_MULTICAST_IF_OS2, (char *)optval, optlen);
1078 break;
1079 }
1080
1081 case IP_ADD_MEMBERSHIP:
1082 case WS2_IPPROTO_OPT(IP_ADD_MEMBERSHIP_WS2):
1083 if (optlen < sizeof(struct ip_mreq))
1084 {
1085 dprintf(("IPPROTO_IP, IP_ADD_MEMBERSHIP, optlen too small"));
1086 WSASetLastError(WSAEFAULT);
1087 return SOCKET_ERROR;
1088 }
1089 ret = setsockopt(s, IPPROTO_IP, IP_ADD_MEMBERSHIP_OS2, (char *)optval, optlen);
1090 break;
1091
1092 case IP_DROP_MEMBERSHIP:
1093 case WS2_IPPROTO_OPT(IP_DROP_MEMBERSHIP_WS2):
1094 if (optlen < sizeof(struct ip_mreq))
1095 {
1096 dprintf(("IPPROTO_IP, IP_DROP_MEMBERSHIP, optlen too small"));
1097 WSASetLastError(WSAEFAULT);
1098 return SOCKET_ERROR;
1099 }
1100 ret = setsockopt(s, IPPROTO_IP, IP_DROP_MEMBERSHIP_OS2, (char *)optval, optlen);
1101 break;
1102
1103 case IP_MULTICAST_LOOP:
1104 case WS2_IPPROTO_OPT(IP_MULTICAST_LOOP_WS2):
1105 {
1106 u_int flLoop;
1107 if (optlen < sizeof(u_char))
1108 {
1109 dprintf(("IPPROTO_IP, IP_MULTICAST_LOOP/IP_MULTICAST_TTL, optlen too small"));
1110 WSASetLastError(WSAEFAULT);
1111 return SOCKET_ERROR;
1112 }
1113 flLoop = (*optval == 0) ? 0 : 1;
1114 dprintf(("IP_MULTICAST_LOOP %d", *optval));
1115 ret = setsockopt(s, IPPROTO_IP, IP_MULTICAST_LOOP_OS2, (char *)&flLoop, optlen);
1116 break;
1117 }
1118
1119 case IP_MULTICAST_TTL:
1120 case WS2_IPPROTO_OPT(IP_MULTICAST_TTL_WS2):
1121 if (optlen < sizeof(u_char))
1122 {
1123 dprintf(("IPPROTO_IP, IP_MULTICAST_TTL, optlen too small"));
1124 WSASetLastError(WSAEFAULT);
1125 return SOCKET_ERROR;
1126 }
1127 ret = setsockopt(s, IPPROTO_IP, IP_MULTICAST_TTL_OS2, (char *)optval, optlen);
1128 break;
1129
1130 case IP_TTL:
1131 case WS2_IPPROTO_OPT(IP_TTL_WS2):
1132 if (optlen < sizeof(u_int))
1133 {
1134 dprintf(("IPPROTO_IP, IP_TTL_WS2, optlen too small"));
1135 WSASetLastError(WSAEFAULT);
1136 return SOCKET_ERROR;
1137 }
1138 dprintf(("IPPROTO_IP, IP_TTL 0x%x", *optval));
1139 ret = setsockopt(s, IPPROTO_IP, IP_TTL_OS2, (char *)optval, optlen);
1140 break;
1141
1142 case IP_TOS:
1143 case WS2_IPPROTO_OPT(IP_TOS_WS2):
1144 if (optlen < sizeof(u_int))
1145 {
1146 dprintf(("IPPROTO_IP, IP_TOS_WS2, optlen too small"));
1147 WSASetLastError(WSAEFAULT);
1148 return SOCKET_ERROR;
1149 }
1150 dprintf(("IPPROTO_IP, IP_TOS 0x%x", *optval));
1151 ret = setsockopt(s, IPPROTO_IP, IP_TOS_OS2, (char *)optval, optlen);
1152 break;
1153
1154 case WS2_IPPROTO_OPT(IP_HDRINCL_WS2):
1155 if (optlen < sizeof(u_int))
1156 {
1157 dprintf(("IPPROTO_IP, IP_HDRINCL_WS2, optlen too small"));
1158 WSASetLastError(WSAEFAULT);
1159 return SOCKET_ERROR;
1160 }
1161 val = *optval;
1162 dprintf(("IPPROTO_IP, IP_HDRINCL 0x%x", val));
1163 ret = setsockopt(s, IPPROTO_IP, IP_HDRINCL_OS2, (char *)&val, optlen);
1164 break;
1165
1166 default:
1167 dprintf(("setsockopt: IPPROTO_IP, unknown option %x", optname));
1168 WSASetLastError(WSAENOPROTOOPT);
1169 return SOCKET_ERROR;
1170 }
1171 }
1172 else {
1173 dprintf(("unknown level code!"));
1174 WSASetLastError(WSAEINVAL);
1175 return SOCKET_ERROR;
1176 }
1177
1178 if(ret == SOCKET_ERROR) {
1179 WSASetLastError(wsaErrno());
1180 }
1181 else WSASetLastError(NO_ERROR);
1182 return ret;
1183}
1184//******************************************************************************
1185//******************************************************************************
1186ODINFUNCTION5(int,OS2getsockopt,
1187 SOCKET, s,
1188 int, level,
1189 int, optname,
1190 char *, optval,
1191 int *,optlen)
1192{
1193 struct ws_linger *yy;
1194 struct linger xx;
1195 int ret;
1196 int size, options;
1197
1198 if(!fWSAInitialized) {
1199 WSASetLastError(WSANOTINITIALISED);
1200 return SOCKET_ERROR;
1201 }
1202 else
1203 if(WSAIsBlocking()) {
1204 WSASetLastError(WSAEINPROGRESS);
1205 return SOCKET_ERROR;
1206 }
1207 if (level == SOL_SOCKET) {
1208 switch(optname) {
1209 case SO_DONTLINGER:
1210 case SO_LINGER:
1211 if(optlen == NULL || *optlen < sizeof(ws_linger)) {
1212 WSASetLastError(WSAEFAULT);
1213 return SOCKET_ERROR;
1214 }
1215 size = sizeof(xx);
1216 ret = getsockopt(s,level,optname,(char *)&xx, &size);
1217 yy = (struct ws_linger *)optval;
1218 yy->l_onoff = (optname == SO_DONTLINGER) ? !xx.l_onoff : xx.l_onoff;
1219 yy->l_linger = xx.l_linger;
1220 *optlen = size;
1221 break;
1222
1223 case SO_SNDBUF:
1224 case SO_RCVBUF:
1225 case SO_BROADCAST:
1226 case SO_DEBUG:
1227 case SO_KEEPALIVE:
1228 case SO_DONTROUTE:
1229 case SO_OOBINLINE:
1230 case SO_REUSEADDR:
1231 case SO_TYPE:
1232 if(optlen == NULL || *optlen < sizeof(int)) {
1233 WSASetLastError(WSAEFAULT);
1234 return SOCKET_ERROR;
1235 }
1236 ret = getsockopt(s, level, optname, (char *)optval, optlen);
1237 break;
1238 case SO_ACCEPTCONN:
1239 if(optlen == NULL || *optlen < sizeof(int)) {
1240 WSASetLastError(WSAEFAULT);
1241 return SOCKET_ERROR;
1242 }
1243 size = sizeof(options);
1244 ret = getsockopt(s, SOL_SOCKET, SO_OPTIONS, (char *)&options, &size);
1245 if(ret != SOCKET_ERROR) {
1246 *(BOOL *)optval = (options & SO_ACCEPTCONN) == SO_ACCEPTCONN;
1247 *optlen = sizeof(BOOL);
1248 }
1249 break;
1250 default:
1251 dprintf(("getsockopt: unknown option %x", optname));
1252 WSASetLastError(WSAENOPROTOOPT);
1253 return SOCKET_ERROR;
1254 }
1255 }
1256 else
1257 if(level == IPPROTO_TCP) {
1258 if(optname == TCP_NODELAY) {
1259 if(optlen == NULL || *optlen < sizeof(int)) {
1260 WSASetLastError(WSAEFAULT);
1261 return SOCKET_ERROR;
1262 }
1263 ret = getsockopt(s, level, optname, (char *)optval, optlen);
1264 }
1265 else {
1266 dprintf(("getsockopt: unknown option %x", optname));
1267 WSASetLastError(WSAENOPROTOOPT);
1268 return SOCKET_ERROR;
1269 }
1270 }
1271 else
1272 if(level == IPPROTO_IP) {
1273 switch (optname)
1274 {
1275 case IP_MULTICAST_IF:
1276 case WS2_IPPROTO_OPT(IP_MULTICAST_IF_WS2):
1277 {
1278 if (*optlen < sizeof(in_addr))
1279 {
1280 dprintf(("IPPROTO_IP, IP_MULTICAST_IP, optlen too small"));
1281 WSASetLastError(WSAEFAULT);
1282 return SOCKET_ERROR;
1283 }
1284 //TODO convert common interface names!
1285 ret = getsockopt(s, IPPROTO_IP, IP_MULTICAST_IF_OS2, (char *)optval, optlen);
1286 break;
1287 }
1288
1289 case IP_ADD_MEMBERSHIP:
1290 case WS2_IPPROTO_OPT(IP_ADD_MEMBERSHIP_WS2):
1291 if (*optlen < sizeof(struct ip_mreq))
1292 {
1293 dprintf(("IPPROTO_IP, IP_ADD_MEMBERSHIP, optlen too small"));
1294 WSASetLastError(WSAEFAULT);
1295 return SOCKET_ERROR;
1296 }
1297 ret = getsockopt(s, IPPROTO_IP, IP_ADD_MEMBERSHIP_OS2, (char *)optval, optlen);
1298 break;
1299
1300 case IP_DROP_MEMBERSHIP:
1301 case WS2_IPPROTO_OPT(IP_DROP_MEMBERSHIP_WS2):
1302 if (*optlen < sizeof(struct ip_mreq))
1303 {
1304 dprintf(("IPPROTO_IP, IP_DROP_MEMBERSHIP, optlen too small"));
1305 WSASetLastError(WSAEFAULT);
1306 return SOCKET_ERROR;
1307 }
1308 ret = getsockopt(s, IPPROTO_IP, IP_DROP_MEMBERSHIP_OS2, (char *)optval, optlen);
1309 break;
1310
1311 case IP_MULTICAST_LOOP:
1312 case WS2_IPPROTO_OPT(IP_MULTICAST_LOOP_WS2):
1313 {
1314 if (*optlen < sizeof(u_char))
1315 {
1316 dprintf(("IPPROTO_IP, IP_MULTICAST_LOOP/IP_MULTICAST_TTL, optlen too small"));
1317 WSASetLastError(WSAEFAULT);
1318 return SOCKET_ERROR;
1319 }
1320 ret = getsockopt(s, IPPROTO_IP, IP_MULTICAST_LOOP_OS2, (char *)optval, optlen);
1321 break;
1322 }
1323
1324 case IP_MULTICAST_TTL:
1325 case WS2_IPPROTO_OPT(IP_MULTICAST_TTL_WS2):
1326 if (*optlen < sizeof(u_char))
1327 {
1328 dprintf(("IPPROTO_IP, IP_MULTICAST_TTL, optlen too small"));
1329 WSASetLastError(WSAEFAULT);
1330 return SOCKET_ERROR;
1331 }
1332 ret = getsockopt(s, IPPROTO_IP, IP_MULTICAST_TTL_OS2, (char *)optval, optlen);
1333 break;
1334
1335 case IP_TTL:
1336 case WS2_IPPROTO_OPT(IP_TTL_WS2):
1337 if (*optlen < sizeof(u_int))
1338 {
1339 dprintf(("IPPROTO_IP, IP_TTL_WS2, optlen too small"));
1340 WSASetLastError(WSAEFAULT);
1341 return SOCKET_ERROR;
1342 }
1343 ret = getsockopt(s, IPPROTO_IP, IP_TTL_OS2, (char *)optval, optlen);
1344 break;
1345
1346 case IP_TOS:
1347 case WS2_IPPROTO_OPT(IP_TOS_WS2):
1348 if (*optlen < sizeof(u_int))
1349 {
1350 dprintf(("IPPROTO_IP, IP_TOS_WS2, optlen too small"));
1351 WSASetLastError(WSAEFAULT);
1352 return SOCKET_ERROR;
1353 }
1354 ret = getsockopt(s, IPPROTO_IP, IP_TOS_OS2, (char *)optval, optlen);
1355 break;
1356
1357 case WS2_IPPROTO_OPT(IP_HDRINCL_WS2):
1358 if (*optlen < sizeof(u_int))
1359 {
1360 dprintf(("IPPROTO_IP, IP_HDRINCL_WS2, optlen too small"));
1361 WSASetLastError(WSAEFAULT);
1362 return SOCKET_ERROR;
1363 }
1364 ret = getsockopt(s, IPPROTO_IP, IP_HDRINCL_OS2, (char *)optval, optlen);
1365 if(ret == 0) {
1366 ret = (ret != FALSE) ? TRUE : FALSE;
1367 }
1368 break;
1369
1370 default:
1371 dprintf(("getsockopt: IPPROTO_IP, unknown option %x", optname));
1372 WSASetLastError(WSAENOPROTOOPT);
1373 return SOCKET_ERROR;
1374 }
1375 }
1376 else {
1377 WSASetLastError(WSAEINVAL);
1378 return SOCKET_ERROR;
1379 }
1380
1381 if(ret == SOCKET_ERROR) {
1382 WSASetLastError(wsaErrno());
1383 }
1384 else WSASetLastError(NO_ERROR);
1385 return ret;
1386}
1387//******************************************************************************
1388//******************************************************************************
1389/* Database function prototypes */
1390//******************************************************************************
1391//******************************************************************************
1392ODINFUNCTION2(int,OS2gethostname,
1393 char *,name,
1394 int,namelen)
1395{
1396 int ret;
1397
1398 ret = gethostname(name, namelen);
1399 if(ret == NULL) {
1400 dprintf(("gethostname returned %s", name));
1401 WSASetLastError(NO_ERROR);
1402 return 0;
1403 }
1404 WSASetLastError((errno == EINVAL) ? WSAEFAULT : wsaErrno());
1405 return SOCKET_ERROR;
1406}
1407//******************************************************************************
1408//******************************************************************************
1409ODINFUNCTION3(ws_hostent *,OS2gethostbyaddr,
1410 const char *,addr,
1411 int,len,
1412 int,type)
1413{
1414 LPWSINFO pwsi = WINSOCK_GetIData();
1415
1416 if( pwsi )
1417 {
1418 struct hostent* host;
1419 if( (host = gethostbyaddr((char *)addr, len, type)) != NULL ) {
1420 if( WS_dup_he(pwsi, host) ) {
1421 WSASetLastError(NO_ERROR);
1422 return pwsi->he;
1423 }
1424 else WSASetLastError(WSAENOBUFS);
1425 }
1426 else WSASetLastError((h_errno < 0) ? wsaErrno() : wsaHerrno());
1427 }
1428 else WSASetLastError(WSANOTINITIALISED);
1429 return NULL;
1430}
1431//******************************************************************************
1432//NOTE: This function can possibly block for a very long time
1433// I.e. start ISDNPM without dialing in. gethostbyname will query
1434// each name server and retry several times (60+ seconds per name server)
1435//******************************************************************************
1436ODINFUNCTION1(ws_hostent *,OS2gethostbyname,
1437 const char *,name)
1438{
1439 LPWSINFO pwsi = WINSOCK_GetIData();
1440
1441 if( pwsi )
1442 {
1443 struct hostent* host;
1444
1445 dprintf(("gethostbyname %s", name));
1446
1447 host = gethostbyname( (char*) name);
1448
1449 if( host != NULL )
1450 {
1451 if( WS_dup_he(pwsi, host) )
1452 {
1453 WSASetLastError(NO_ERROR);
1454 return pwsi->he;
1455 }
1456 else
1457 WSASetLastError(WSAENOBUFS);
1458 }
1459 else
1460 WSASetLastError((h_errno < 0) ? wsaErrno() : wsaHerrno());
1461 }
1462 else
1463 WSASetLastError(WSANOTINITIALISED);
1464
1465 return NULL;
1466}
1467//******************************************************************************
1468//******************************************************************************
1469ODINFUNCTION2(struct ws_servent *,OS2getservbyport,
1470 int, port,
1471 const char *, proto)
1472{
1473 LPWSINFO pwsi = WINSOCK_GetIData();
1474
1475 if( pwsi )
1476 {
1477 struct servent* serv;
1478 if( (serv = getservbyport(port, (char *)proto)) != NULL ) {
1479 if( WS_dup_se(pwsi, serv) ) {
1480 WSASetLastError(NO_ERROR);
1481 return pwsi->se;
1482 }
1483 else WSASetLastError(WSAENOBUFS);
1484 }
1485 else WSASetLastError(WSANO_DATA);
1486 }
1487 else WSASetLastError(WSANOTINITIALISED);
1488 return NULL;
1489}
1490//******************************************************************************
1491//******************************************************************************
1492ODINFUNCTION2(struct ws_servent *,OS2getservbyname,
1493 const char *, name,
1494 const char *, proto)
1495{
1496 LPWSINFO pwsi = WINSOCK_GetIData();
1497
1498 if( pwsi )
1499 {
1500 struct servent *serv;
1501 if( (serv = getservbyname((char *)name, (char *)proto)) != NULL ) {
1502 if( WS_dup_se(pwsi, serv) ) {
1503 WSASetLastError(NO_ERROR);
1504 return pwsi->se;
1505 }
1506 else WSASetLastError(WSAENOBUFS);
1507 }
1508 else WSASetLastError(WSANO_DATA);
1509 }
1510 else WSASetLastError(WSANOTINITIALISED);
1511 return NULL;
1512}
1513//******************************************************************************
1514//******************************************************************************
1515ODINFUNCTION1(struct ws_protoent *,OS2getprotobynumber,
1516 int,number)
1517{
1518 LPWSINFO pwsi = WINSOCK_GetIData();
1519
1520 if( pwsi )
1521 {
1522 struct protoent* proto;
1523 if( (proto = getprotobynumber(number)) != NULL ) {
1524 if( WS_dup_pe(pwsi, proto) ) {
1525 WSASetLastError(NO_ERROR);
1526 return pwsi->pe;
1527 }
1528 else WSASetLastError(WSAENOBUFS);
1529 }
1530 else WSASetLastError(WSANO_DATA);
1531 }
1532 else WSASetLastError(WSANOTINITIALISED);
1533 return NULL;
1534}
1535//******************************************************************************
1536//******************************************************************************
1537ODINFUNCTION1(struct ws_protoent *,OS2getprotobyname,
1538 const char *,name)
1539{
1540 LPWSINFO pwsi = WINSOCK_GetIData();
1541
1542 if( pwsi )
1543 {
1544 struct protoent * proto;
1545 if( (proto = getprotobyname((char *)name)) != NULL ) {
1546 if(WS_dup_pe(pwsi, proto)) {
1547 WSASetLastError(NO_ERROR);
1548 return pwsi->pe;
1549 }
1550 else WSASetLastError(WSAENOBUFS);
1551 }
1552 else WSASetLastError((h_errno < 0) ? wsaErrno() : wsaHerrno());
1553 }
1554 else WSASetLastError(WSANOTINITIALISED);
1555 return NULL;
1556}
1557//******************************************************************************
1558//******************************************************************************
Note: See TracBrowser for help on using the repository browser.