xref: /minix3/crypto/external/bsd/openssl/dist/MacOS/GetHTTPS.src/MacSocket.cpp (revision ebfedea0ce5bbe81e252ddf32d732e40fb633fae)
1*ebfedea0SLionel Sambuc /*
2*ebfedea0SLionel Sambuc  *	A simple socket-like package.
3*ebfedea0SLionel Sambuc  *	This could undoubtedly be improved, since it does polling and busy-waiting.
4*ebfedea0SLionel Sambuc  *	At least it uses asynch I/O and implements timeouts!
5*ebfedea0SLionel Sambuc  *
6*ebfedea0SLionel Sambuc  *	Other funkiness includes the use of my own (possibly brain-damaged) error-handling infrastructure.
7*ebfedea0SLionel Sambuc  *
8*ebfedea0SLionel Sambuc  *	-Roy Wood (roy@centricsystems.ca)
9*ebfedea0SLionel Sambuc  *
10*ebfedea0SLionel Sambuc  */
11*ebfedea0SLionel Sambuc 
12*ebfedea0SLionel Sambuc 
13*ebfedea0SLionel Sambuc /* ====================================================================
14*ebfedea0SLionel Sambuc  * Copyright (c) 1998-1999 The OpenSSL Project.  All rights reserved.
15*ebfedea0SLionel Sambuc  *
16*ebfedea0SLionel Sambuc  * Redistribution and use in source and binary forms, with or without
17*ebfedea0SLionel Sambuc  * modification, are permitted provided that the following conditions
18*ebfedea0SLionel Sambuc  * are met:
19*ebfedea0SLionel Sambuc  *
20*ebfedea0SLionel Sambuc  * 1. Redistributions of source code must retain the above copyright
21*ebfedea0SLionel Sambuc  *    notice, this list of conditions and the following disclaimer.
22*ebfedea0SLionel Sambuc  *
23*ebfedea0SLionel Sambuc  * 2. Redistributions in binary form must reproduce the above copyright
24*ebfedea0SLionel Sambuc  *    notice, this list of conditions and the following disclaimer in
25*ebfedea0SLionel Sambuc  *    the documentation and/or other materials provided with the
26*ebfedea0SLionel Sambuc  *    distribution.
27*ebfedea0SLionel Sambuc  *
28*ebfedea0SLionel Sambuc  * 3. All advertising materials mentioning features or use of this
29*ebfedea0SLionel Sambuc  *    software must display the following acknowledgment:
30*ebfedea0SLionel Sambuc  *    "This product includes software developed by the OpenSSL Project
31*ebfedea0SLionel Sambuc  *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
32*ebfedea0SLionel Sambuc  *
33*ebfedea0SLionel Sambuc  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
34*ebfedea0SLionel Sambuc  *    endorse or promote products derived from this software without
35*ebfedea0SLionel Sambuc  *    prior written permission. For written permission, please contact
36*ebfedea0SLionel Sambuc  *    openssl-core@openssl.org.
37*ebfedea0SLionel Sambuc  *
38*ebfedea0SLionel Sambuc  * 5. Products derived from this software may not be called "OpenSSL"
39*ebfedea0SLionel Sambuc  *    nor may "OpenSSL" appear in their names without prior written
40*ebfedea0SLionel Sambuc  *    permission of the OpenSSL Project.
41*ebfedea0SLionel Sambuc  *
42*ebfedea0SLionel Sambuc  * 6. Redistributions of any form whatsoever must retain the following
43*ebfedea0SLionel Sambuc  *    acknowledgment:
44*ebfedea0SLionel Sambuc  *    "This product includes software developed by the OpenSSL Project
45*ebfedea0SLionel Sambuc  *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
46*ebfedea0SLionel Sambuc  *
47*ebfedea0SLionel Sambuc  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
48*ebfedea0SLionel Sambuc  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
49*ebfedea0SLionel Sambuc  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
50*ebfedea0SLionel Sambuc  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
51*ebfedea0SLionel Sambuc  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
52*ebfedea0SLionel Sambuc  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
53*ebfedea0SLionel Sambuc  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
54*ebfedea0SLionel Sambuc  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
55*ebfedea0SLionel Sambuc  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
56*ebfedea0SLionel Sambuc  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
57*ebfedea0SLionel Sambuc  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
58*ebfedea0SLionel Sambuc  * OF THE POSSIBILITY OF SUCH DAMAGE.
59*ebfedea0SLionel Sambuc  * ====================================================================
60*ebfedea0SLionel Sambuc  *
61*ebfedea0SLionel Sambuc  * This product includes cryptographic software written by Eric Young
62*ebfedea0SLionel Sambuc  * (eay@cryptsoft.com).  This product includes software written by Tim
63*ebfedea0SLionel Sambuc  * Hudson (tjh@cryptsoft.com).
64*ebfedea0SLionel Sambuc  *
65*ebfedea0SLionel Sambuc  */
66*ebfedea0SLionel Sambuc 
67*ebfedea0SLionel Sambuc 
68*ebfedea0SLionel Sambuc 
69*ebfedea0SLionel Sambuc 
70*ebfedea0SLionel Sambuc 
71*ebfedea0SLionel Sambuc #include "MacSocket.h"
72*ebfedea0SLionel Sambuc 
73*ebfedea0SLionel Sambuc #include <Threads.h>
74*ebfedea0SLionel Sambuc 
75*ebfedea0SLionel Sambuc #include <OpenTransport.h>
76*ebfedea0SLionel Sambuc #include <OpenTpTInternet.h>
77*ebfedea0SLionel Sambuc #include <OpenTptClient.h>
78*ebfedea0SLionel Sambuc 
79*ebfedea0SLionel Sambuc 
80*ebfedea0SLionel Sambuc 
81*ebfedea0SLionel Sambuc #include "CPStringUtils.hpp"
82*ebfedea0SLionel Sambuc #include "ErrorHandling.hpp"
83*ebfedea0SLionel Sambuc 
84*ebfedea0SLionel Sambuc 
85*ebfedea0SLionel Sambuc //	#define MACSOCKET_DEBUG		1
86*ebfedea0SLionel Sambuc 
87*ebfedea0SLionel Sambuc #ifdef MACSOCKET_DEBUG
88*ebfedea0SLionel Sambuc 	#include <stdio.h>
89*ebfedea0SLionel Sambuc #endif
90*ebfedea0SLionel Sambuc 
91*ebfedea0SLionel Sambuc 
92*ebfedea0SLionel Sambuc 
93*ebfedea0SLionel Sambuc extern int errno;
94*ebfedea0SLionel Sambuc 
95*ebfedea0SLionel Sambuc 
96*ebfedea0SLionel Sambuc #define kMaxNumSockets			4
97*ebfedea0SLionel Sambuc 
98*ebfedea0SLionel Sambuc 
99*ebfedea0SLionel Sambuc struct SocketStruct
100*ebfedea0SLionel Sambuc {
101*ebfedea0SLionel Sambuc 	Boolean						mIsInUse;
102*ebfedea0SLionel Sambuc 
103*ebfedea0SLionel Sambuc 	Boolean						mEndpointIsBound;
104*ebfedea0SLionel Sambuc 
105*ebfedea0SLionel Sambuc 	Boolean						mLocalEndIsConnected;
106*ebfedea0SLionel Sambuc 	Boolean						mRemoteEndIsConnected;
107*ebfedea0SLionel Sambuc 
108*ebfedea0SLionel Sambuc 	Boolean						mReceivedTOpenComplete;
109*ebfedea0SLionel Sambuc 	Boolean						mReceivedTBindComplete;
110*ebfedea0SLionel Sambuc 	Boolean						mReceivedTConnect;
111*ebfedea0SLionel Sambuc 	Boolean						mReceivedTListen;
112*ebfedea0SLionel Sambuc 	Boolean						mReceivedTPassCon;
113*ebfedea0SLionel Sambuc 	Boolean						mReceivedTDisconnect;
114*ebfedea0SLionel Sambuc 	Boolean						mReceivedTOrdRel;
115*ebfedea0SLionel Sambuc 	Boolean						mReceivedTDisconnectComplete;
116*ebfedea0SLionel Sambuc 
117*ebfedea0SLionel Sambuc 	long						mTimeoutTicks;
118*ebfedea0SLionel Sambuc 	long						mOperationStartTicks;
119*ebfedea0SLionel Sambuc 
120*ebfedea0SLionel Sambuc 	MacSocket_IdleWaitCallback	mIdleWaitCallback;
121*ebfedea0SLionel Sambuc 	void						*mUserRefPtr;
122*ebfedea0SLionel Sambuc 
123*ebfedea0SLionel Sambuc 	OTEventCode					mExpectedCode;
124*ebfedea0SLionel Sambuc 	OTResult					mAsyncOperationResult;
125*ebfedea0SLionel Sambuc 
126*ebfedea0SLionel Sambuc 	EndpointRef		 			mEndPointRef;
127*ebfedea0SLionel Sambuc 	TBind						*mBindRequestedAddrInfo;
128*ebfedea0SLionel Sambuc 	TBind						*mAssignedAddrInfo;
129*ebfedea0SLionel Sambuc 	TCall						*mRemoteAddrInfo;
130*ebfedea0SLionel Sambuc 
131*ebfedea0SLionel Sambuc 	Boolean						mReadyToReadData;
132*ebfedea0SLionel Sambuc 	Boolean						mReadyToWriteData;
133*ebfedea0SLionel Sambuc 
134*ebfedea0SLionel Sambuc 	Ptr							mReadBuffer;
135*ebfedea0SLionel Sambuc 	Ptr							mWriteBuffer;
136*ebfedea0SLionel Sambuc 
137*ebfedea0SLionel Sambuc 	int							mLastError;
138*ebfedea0SLionel Sambuc 	char						mErrMessage[256];
139*ebfedea0SLionel Sambuc };
140*ebfedea0SLionel Sambuc 
141*ebfedea0SLionel Sambuc typedef struct SocketStruct	SocketStruct;
142*ebfedea0SLionel Sambuc 
143*ebfedea0SLionel Sambuc 
144*ebfedea0SLionel Sambuc static SocketStruct			sSockets[kMaxNumSockets];
145*ebfedea0SLionel Sambuc static Boolean				sSocketsSetup = false;
146*ebfedea0SLionel Sambuc 
147*ebfedea0SLionel Sambuc 
148*ebfedea0SLionel Sambuc 
149*ebfedea0SLionel Sambuc 
150*ebfedea0SLionel Sambuc static OSErr MyBusyWait(SocketStruct *ioSocket,Boolean returnImmediatelyOnError,OTResult *outOTResult,Boolean *inAsyncOperationCompleteFlag);
151*ebfedea0SLionel Sambuc 
152*ebfedea0SLionel Sambuc static pascal void OTNonYieldingNotifier(void *contextPtr,OTEventCode code,OTResult result,void *cookie);
153*ebfedea0SLionel Sambuc 
154*ebfedea0SLionel Sambuc static Boolean	SocketIndexIsValid(const int inSocketNum);
155*ebfedea0SLionel Sambuc 
156*ebfedea0SLionel Sambuc static void InitSocket(SocketStruct *ioSocket);
157*ebfedea0SLionel Sambuc 
158*ebfedea0SLionel Sambuc static void PrepareForAsyncOperation(SocketStruct *ioSocket,const OTEventCode inExpectedCode);
159*ebfedea0SLionel Sambuc 
160*ebfedea0SLionel Sambuc static Boolean TimeoutElapsed(const SocketStruct *inSocket);
161*ebfedea0SLionel Sambuc 
162*ebfedea0SLionel Sambuc static OSStatus NegotiateIPReuseAddrOption(EndpointRef inEndpoint,const Boolean inEnableReuseIP);
163*ebfedea0SLionel Sambuc 
164*ebfedea0SLionel Sambuc 
165*ebfedea0SLionel Sambuc 
MacSocket_GetSocketErrorInfo(const int inSocketNum,int * outSocketErrCode,char * outSocketErrString,const int inSocketErrStringMaxLength)166*ebfedea0SLionel Sambuc void MacSocket_GetSocketErrorInfo(const int inSocketNum,int *outSocketErrCode,char *outSocketErrString,const int inSocketErrStringMaxLength)
167*ebfedea0SLionel Sambuc {
168*ebfedea0SLionel Sambuc 	if (outSocketErrCode != nil)
169*ebfedea0SLionel Sambuc 	{
170*ebfedea0SLionel Sambuc 		*outSocketErrCode = -1;
171*ebfedea0SLionel Sambuc 	}
172*ebfedea0SLionel Sambuc 
173*ebfedea0SLionel Sambuc 	if (outSocketErrString != nil)
174*ebfedea0SLionel Sambuc 	{
175*ebfedea0SLionel Sambuc 		CopyCStrToCStr("",outSocketErrString,inSocketErrStringMaxLength);
176*ebfedea0SLionel Sambuc 	}
177*ebfedea0SLionel Sambuc 
178*ebfedea0SLionel Sambuc 
179*ebfedea0SLionel Sambuc 	if (SocketIndexIsValid(inSocketNum))
180*ebfedea0SLionel Sambuc 	{
181*ebfedea0SLionel Sambuc 	SocketStruct	*theSocketStruct = &(sSockets[inSocketNum]);
182*ebfedea0SLionel Sambuc 
183*ebfedea0SLionel Sambuc 
184*ebfedea0SLionel Sambuc 		if (outSocketErrCode != nil)
185*ebfedea0SLionel Sambuc 		{
186*ebfedea0SLionel Sambuc 			*outSocketErrCode = theSocketStruct->mLastError;
187*ebfedea0SLionel Sambuc 		}
188*ebfedea0SLionel Sambuc 
189*ebfedea0SLionel Sambuc 		if (outSocketErrString != nil)
190*ebfedea0SLionel Sambuc 		{
191*ebfedea0SLionel Sambuc 			CopyCStrToCStr(theSocketStruct->mErrMessage,outSocketErrString,inSocketErrStringMaxLength);
192*ebfedea0SLionel Sambuc 		}
193*ebfedea0SLionel Sambuc 	}
194*ebfedea0SLionel Sambuc }
195*ebfedea0SLionel Sambuc 
196*ebfedea0SLionel Sambuc 
MacSocket_SetUserRefPtr(const int inSocketNum,void * inNewRefPtr)197*ebfedea0SLionel Sambuc void MacSocket_SetUserRefPtr(const int inSocketNum,void *inNewRefPtr)
198*ebfedea0SLionel Sambuc {
199*ebfedea0SLionel Sambuc 	if (SocketIndexIsValid(inSocketNum))
200*ebfedea0SLionel Sambuc 	{
201*ebfedea0SLionel Sambuc 	SocketStruct	*theSocketStruct = &(sSockets[inSocketNum]);
202*ebfedea0SLionel Sambuc 
203*ebfedea0SLionel Sambuc 		theSocketStruct->mUserRefPtr = inNewRefPtr;
204*ebfedea0SLionel Sambuc 	}
205*ebfedea0SLionel Sambuc }
206*ebfedea0SLionel Sambuc 
207*ebfedea0SLionel Sambuc 
208*ebfedea0SLionel Sambuc 
MacSocket_GetLocalIPAndPort(const int inSocketNum,char * outIPAndPort,const int inIPAndPortLength)209*ebfedea0SLionel Sambuc void MacSocket_GetLocalIPAndPort(const int inSocketNum,char *outIPAndPort,const int inIPAndPortLength)
210*ebfedea0SLionel Sambuc {
211*ebfedea0SLionel Sambuc 	if (outIPAndPort != nil && SocketIndexIsValid(inSocketNum))
212*ebfedea0SLionel Sambuc 	{
213*ebfedea0SLionel Sambuc 	char			tempString[256];
214*ebfedea0SLionel Sambuc 	SocketStruct	*theSocketStruct = &(sSockets[inSocketNum]);
215*ebfedea0SLionel Sambuc 
216*ebfedea0SLionel Sambuc 
217*ebfedea0SLionel Sambuc 		CopyCStrToCStr("",tempString,sizeof(tempString));
218*ebfedea0SLionel Sambuc 
219*ebfedea0SLionel Sambuc 		if (theSocketStruct->mAssignedAddrInfo != nil)
220*ebfedea0SLionel Sambuc 		{
221*ebfedea0SLionel Sambuc 		InetAddress		*theInetAddress = (InetAddress *) theSocketStruct->mAssignedAddrInfo->addr.buf;
222*ebfedea0SLionel Sambuc 		InetHost		theInetHost = theInetAddress->fHost;
223*ebfedea0SLionel Sambuc 
224*ebfedea0SLionel Sambuc 			if (theInetHost == 0)
225*ebfedea0SLionel Sambuc 			{
226*ebfedea0SLionel Sambuc 			InetInterfaceInfo	theInetInterfaceInfo;
227*ebfedea0SLionel Sambuc 
228*ebfedea0SLionel Sambuc 				if (::OTInetGetInterfaceInfo(&theInetInterfaceInfo,kDefaultInetInterface) == noErr)
229*ebfedea0SLionel Sambuc 				{
230*ebfedea0SLionel Sambuc 					theInetHost = theInetInterfaceInfo.fAddress;
231*ebfedea0SLionel Sambuc 				}
232*ebfedea0SLionel Sambuc 			}
233*ebfedea0SLionel Sambuc 
234*ebfedea0SLionel Sambuc 			::OTInetHostToString(theInetHost,tempString);
235*ebfedea0SLionel Sambuc 
236*ebfedea0SLionel Sambuc 			ConcatCStrToCStr(":",tempString,sizeof(tempString));
237*ebfedea0SLionel Sambuc 			ConcatLongIntToCStr(theInetAddress->fPort,tempString,sizeof(tempString));
238*ebfedea0SLionel Sambuc 		}
239*ebfedea0SLionel Sambuc 
240*ebfedea0SLionel Sambuc 		CopyCStrToCStr(tempString,outIPAndPort,inIPAndPortLength);
241*ebfedea0SLionel Sambuc 	}
242*ebfedea0SLionel Sambuc }
243*ebfedea0SLionel Sambuc 
244*ebfedea0SLionel Sambuc 
245*ebfedea0SLionel Sambuc 
MacSocket_GetRemoteIPAndPort(const int inSocketNum,char * outIPAndPort,const int inIPAndPortLength)246*ebfedea0SLionel Sambuc void MacSocket_GetRemoteIPAndPort(const int inSocketNum,char *outIPAndPort,const int inIPAndPortLength)
247*ebfedea0SLionel Sambuc {
248*ebfedea0SLionel Sambuc 	if (outIPAndPort != nil && SocketIndexIsValid(inSocketNum))
249*ebfedea0SLionel Sambuc 	{
250*ebfedea0SLionel Sambuc 	char			tempString[256];
251*ebfedea0SLionel Sambuc 	SocketStruct	*theSocketStruct = &(sSockets[inSocketNum]);
252*ebfedea0SLionel Sambuc 
253*ebfedea0SLionel Sambuc 
254*ebfedea0SLionel Sambuc 		CopyCStrToCStr("",tempString,sizeof(tempString));
255*ebfedea0SLionel Sambuc 
256*ebfedea0SLionel Sambuc 		if (theSocketStruct->mRemoteAddrInfo != nil)
257*ebfedea0SLionel Sambuc 		{
258*ebfedea0SLionel Sambuc 		InetAddress		*theInetAddress = (InetAddress *) theSocketStruct->mRemoteAddrInfo->addr.buf;
259*ebfedea0SLionel Sambuc 		InetHost		theInetHost = theInetAddress->fHost;
260*ebfedea0SLionel Sambuc 
261*ebfedea0SLionel Sambuc 			if (theInetHost == 0)
262*ebfedea0SLionel Sambuc 			{
263*ebfedea0SLionel Sambuc 			InetInterfaceInfo	theInetInterfaceInfo;
264*ebfedea0SLionel Sambuc 
265*ebfedea0SLionel Sambuc 				if (::OTInetGetInterfaceInfo(&theInetInterfaceInfo,kDefaultInetInterface) == noErr)
266*ebfedea0SLionel Sambuc 				{
267*ebfedea0SLionel Sambuc 					theInetHost = theInetInterfaceInfo.fAddress;
268*ebfedea0SLionel Sambuc 				}
269*ebfedea0SLionel Sambuc 			}
270*ebfedea0SLionel Sambuc 
271*ebfedea0SLionel Sambuc 			::OTInetHostToString(theInetHost,tempString);
272*ebfedea0SLionel Sambuc 
273*ebfedea0SLionel Sambuc 			ConcatCStrToCStr(":",tempString,sizeof(tempString));
274*ebfedea0SLionel Sambuc 			ConcatLongIntToCStr(theInetAddress->fPort,tempString,sizeof(tempString));
275*ebfedea0SLionel Sambuc 		}
276*ebfedea0SLionel Sambuc 
277*ebfedea0SLionel Sambuc 		CopyCStrToCStr(tempString,outIPAndPort,inIPAndPortLength);
278*ebfedea0SLionel Sambuc 	}
279*ebfedea0SLionel Sambuc }
280*ebfedea0SLionel Sambuc 
281*ebfedea0SLionel Sambuc 
282*ebfedea0SLionel Sambuc 
MacSocket_RemoteEndIsClosing(const int inSocketNum)283*ebfedea0SLionel Sambuc Boolean MacSocket_RemoteEndIsClosing(const int inSocketNum)
284*ebfedea0SLionel Sambuc {
285*ebfedea0SLionel Sambuc Boolean		theResult = false;
286*ebfedea0SLionel Sambuc 
287*ebfedea0SLionel Sambuc 	if (SocketIndexIsValid(inSocketNum))
288*ebfedea0SLionel Sambuc 	{
289*ebfedea0SLionel Sambuc 	SocketStruct	*theSocketStruct = &(sSockets[inSocketNum]);
290*ebfedea0SLionel Sambuc 
291*ebfedea0SLionel Sambuc 		theResult = theSocketStruct->mReceivedTOrdRel;
292*ebfedea0SLionel Sambuc 	}
293*ebfedea0SLionel Sambuc 
294*ebfedea0SLionel Sambuc 	return(theResult);
295*ebfedea0SLionel Sambuc }
296*ebfedea0SLionel Sambuc 
297*ebfedea0SLionel Sambuc 
298*ebfedea0SLionel Sambuc 
MacSocket_ListenCompleted(const int inSocketNum)299*ebfedea0SLionel Sambuc Boolean MacSocket_ListenCompleted(const int inSocketNum)
300*ebfedea0SLionel Sambuc {
301*ebfedea0SLionel Sambuc Boolean		theResult = false;
302*ebfedea0SLionel Sambuc 
303*ebfedea0SLionel Sambuc 	if (SocketIndexIsValid(inSocketNum))
304*ebfedea0SLionel Sambuc 	{
305*ebfedea0SLionel Sambuc 	SocketStruct	*theSocketStruct = &(sSockets[inSocketNum]);
306*ebfedea0SLionel Sambuc 
307*ebfedea0SLionel Sambuc 		theResult = theSocketStruct->mReceivedTPassCon;
308*ebfedea0SLionel Sambuc 	}
309*ebfedea0SLionel Sambuc 
310*ebfedea0SLionel Sambuc 	return(theResult);
311*ebfedea0SLionel Sambuc }
312*ebfedea0SLionel Sambuc 
313*ebfedea0SLionel Sambuc 
314*ebfedea0SLionel Sambuc 
MacSocket_RemoteEndIsOpen(const int inSocketNum)315*ebfedea0SLionel Sambuc Boolean MacSocket_RemoteEndIsOpen(const int inSocketNum)
316*ebfedea0SLionel Sambuc {
317*ebfedea0SLionel Sambuc 	if (SocketIndexIsValid(inSocketNum))
318*ebfedea0SLionel Sambuc 	{
319*ebfedea0SLionel Sambuc 	SocketStruct	*theSocketStruct = &(sSockets[inSocketNum]);
320*ebfedea0SLionel Sambuc 
321*ebfedea0SLionel Sambuc 		return(theSocketStruct->mRemoteEndIsConnected);
322*ebfedea0SLionel Sambuc 	}
323*ebfedea0SLionel Sambuc 
324*ebfedea0SLionel Sambuc 	else
325*ebfedea0SLionel Sambuc 	{
326*ebfedea0SLionel Sambuc 		return(false);
327*ebfedea0SLionel Sambuc 	}
328*ebfedea0SLionel Sambuc }
329*ebfedea0SLionel Sambuc 
330*ebfedea0SLionel Sambuc 
331*ebfedea0SLionel Sambuc 
MacSocket_LocalEndIsOpen(const int inSocketNum)332*ebfedea0SLionel Sambuc Boolean MacSocket_LocalEndIsOpen(const int inSocketNum)
333*ebfedea0SLionel Sambuc {
334*ebfedea0SLionel Sambuc 	if (SocketIndexIsValid(inSocketNum))
335*ebfedea0SLionel Sambuc 	{
336*ebfedea0SLionel Sambuc 	SocketStruct	*theSocketStruct = &(sSockets[inSocketNum]);
337*ebfedea0SLionel Sambuc 
338*ebfedea0SLionel Sambuc 		return(theSocketStruct->mLocalEndIsConnected);
339*ebfedea0SLionel Sambuc 	}
340*ebfedea0SLionel Sambuc 
341*ebfedea0SLionel Sambuc 	else
342*ebfedea0SLionel Sambuc 	{
343*ebfedea0SLionel Sambuc 		return(false);
344*ebfedea0SLionel Sambuc 	}
345*ebfedea0SLionel Sambuc }
346*ebfedea0SLionel Sambuc 
347*ebfedea0SLionel Sambuc 
348*ebfedea0SLionel Sambuc 
TimeoutElapsed(const SocketStruct * inSocket)349*ebfedea0SLionel Sambuc static Boolean TimeoutElapsed(const SocketStruct *inSocket)
350*ebfedea0SLionel Sambuc {
351*ebfedea0SLionel Sambuc Boolean		timeIsUp = false;
352*ebfedea0SLionel Sambuc 
353*ebfedea0SLionel Sambuc 	if (inSocket != nil && inSocket->mTimeoutTicks > 0 && ::TickCount() > inSocket->mOperationStartTicks + inSocket->mTimeoutTicks)
354*ebfedea0SLionel Sambuc 	{
355*ebfedea0SLionel Sambuc 		timeIsUp = true;
356*ebfedea0SLionel Sambuc 	}
357*ebfedea0SLionel Sambuc 
358*ebfedea0SLionel Sambuc 
359*ebfedea0SLionel Sambuc 	return(timeIsUp);
360*ebfedea0SLionel Sambuc }
361*ebfedea0SLionel Sambuc 
362*ebfedea0SLionel Sambuc 
363*ebfedea0SLionel Sambuc 
SocketIndexIsValid(const int inSocketNum)364*ebfedea0SLionel Sambuc static Boolean SocketIndexIsValid(const int inSocketNum)
365*ebfedea0SLionel Sambuc {
366*ebfedea0SLionel Sambuc 	if (inSocketNum >= 0 && inSocketNum < kMaxNumSockets && sSockets[inSocketNum].mEndPointRef != kOTInvalidEndpointRef)
367*ebfedea0SLionel Sambuc 	{
368*ebfedea0SLionel Sambuc 		return(true);
369*ebfedea0SLionel Sambuc 	}
370*ebfedea0SLionel Sambuc 
371*ebfedea0SLionel Sambuc 	else
372*ebfedea0SLionel Sambuc 	{
373*ebfedea0SLionel Sambuc 		return(false);
374*ebfedea0SLionel Sambuc 	}
375*ebfedea0SLionel Sambuc }
376*ebfedea0SLionel Sambuc 
377*ebfedea0SLionel Sambuc 
378*ebfedea0SLionel Sambuc 
InitSocket(SocketStruct * ioSocket)379*ebfedea0SLionel Sambuc static void InitSocket(SocketStruct *ioSocket)
380*ebfedea0SLionel Sambuc {
381*ebfedea0SLionel Sambuc 	ioSocket->mIsInUse = false;
382*ebfedea0SLionel Sambuc 
383*ebfedea0SLionel Sambuc 	ioSocket->mEndpointIsBound = false;
384*ebfedea0SLionel Sambuc 
385*ebfedea0SLionel Sambuc 	ioSocket->mLocalEndIsConnected = false;
386*ebfedea0SLionel Sambuc 	ioSocket->mRemoteEndIsConnected = false;
387*ebfedea0SLionel Sambuc 
388*ebfedea0SLionel Sambuc 	ioSocket->mReceivedTOpenComplete = false;
389*ebfedea0SLionel Sambuc 	ioSocket->mReceivedTBindComplete = false;
390*ebfedea0SLionel Sambuc 	ioSocket->mReceivedTConnect = false;
391*ebfedea0SLionel Sambuc 	ioSocket->mReceivedTListen = false;
392*ebfedea0SLionel Sambuc 	ioSocket->mReceivedTPassCon = false;
393*ebfedea0SLionel Sambuc 	ioSocket->mReceivedTDisconnect = false;
394*ebfedea0SLionel Sambuc 	ioSocket->mReceivedTOrdRel = false;
395*ebfedea0SLionel Sambuc 	ioSocket->mReceivedTDisconnectComplete = false;
396*ebfedea0SLionel Sambuc 
397*ebfedea0SLionel Sambuc 	ioSocket->mTimeoutTicks = 30 * 60;
398*ebfedea0SLionel Sambuc 	ioSocket->mOperationStartTicks = -1;
399*ebfedea0SLionel Sambuc 
400*ebfedea0SLionel Sambuc 	ioSocket->mIdleWaitCallback = nil;
401*ebfedea0SLionel Sambuc 	ioSocket->mUserRefPtr = nil;
402*ebfedea0SLionel Sambuc 
403*ebfedea0SLionel Sambuc 	ioSocket->mExpectedCode = 0;
404*ebfedea0SLionel Sambuc 	ioSocket->mAsyncOperationResult = noErr;
405*ebfedea0SLionel Sambuc 
406*ebfedea0SLionel Sambuc 	ioSocket->mEndPointRef = kOTInvalidEndpointRef;
407*ebfedea0SLionel Sambuc 
408*ebfedea0SLionel Sambuc 	ioSocket->mBindRequestedAddrInfo = nil;
409*ebfedea0SLionel Sambuc 	ioSocket->mAssignedAddrInfo = nil;
410*ebfedea0SLionel Sambuc 	ioSocket->mRemoteAddrInfo = nil;
411*ebfedea0SLionel Sambuc 
412*ebfedea0SLionel Sambuc 	ioSocket->mReadyToReadData = false;
413*ebfedea0SLionel Sambuc 	ioSocket->mReadyToWriteData = true;
414*ebfedea0SLionel Sambuc 
415*ebfedea0SLionel Sambuc 	ioSocket->mReadBuffer = nil;
416*ebfedea0SLionel Sambuc 	ioSocket->mWriteBuffer = nil;
417*ebfedea0SLionel Sambuc 
418*ebfedea0SLionel Sambuc 	ioSocket->mLastError = noErr;
419*ebfedea0SLionel Sambuc 	CopyCStrToCStr("",ioSocket->mErrMessage,sizeof(ioSocket->mErrMessage));
420*ebfedea0SLionel Sambuc }
421*ebfedea0SLionel Sambuc 
422*ebfedea0SLionel Sambuc 
423*ebfedea0SLionel Sambuc 
PrepareForAsyncOperation(SocketStruct * ioSocket,const OTEventCode inExpectedCode)424*ebfedea0SLionel Sambuc static void PrepareForAsyncOperation(SocketStruct *ioSocket,const OTEventCode inExpectedCode)
425*ebfedea0SLionel Sambuc {
426*ebfedea0SLionel Sambuc 	ioSocket->mOperationStartTicks = ::TickCount();
427*ebfedea0SLionel Sambuc 
428*ebfedea0SLionel Sambuc 	ioSocket->mAsyncOperationResult = noErr;
429*ebfedea0SLionel Sambuc 
430*ebfedea0SLionel Sambuc 	ioSocket->mExpectedCode = inExpectedCode;
431*ebfedea0SLionel Sambuc }
432*ebfedea0SLionel Sambuc 
433*ebfedea0SLionel Sambuc 
434*ebfedea0SLionel Sambuc //	The wait function....
435*ebfedea0SLionel Sambuc 
MyBusyWait(SocketStruct * ioSocket,Boolean returnImmediatelyOnError,OTResult * outOTResult,Boolean * inAsyncOperationCompleteFlag)436*ebfedea0SLionel Sambuc static OSErr MyBusyWait(SocketStruct *ioSocket,Boolean returnImmediatelyOnError,OTResult *outOTResult,Boolean *inAsyncOperationCompleteFlag)
437*ebfedea0SLionel Sambuc {
438*ebfedea0SLionel Sambuc OSErr 		errCode = noErr;
439*ebfedea0SLionel Sambuc OTResult	theOTResult = noErr;
440*ebfedea0SLionel Sambuc 
441*ebfedea0SLionel Sambuc 
442*ebfedea0SLionel Sambuc 	SetErrorMessageAndBailIfNil(ioSocket,"MyBusyWait: Bad parameter, ioSocket = nil");
443*ebfedea0SLionel Sambuc 	SetErrorMessageAndBailIfNil(inAsyncOperationCompleteFlag,"MyBusyWait: Bad parameter, inAsyncOperationCompleteFlag = nil");
444*ebfedea0SLionel Sambuc 
445*ebfedea0SLionel Sambuc 	for (;;)
446*ebfedea0SLionel Sambuc 	{
447*ebfedea0SLionel Sambuc 		if (*inAsyncOperationCompleteFlag)
448*ebfedea0SLionel Sambuc 		{
449*ebfedea0SLionel Sambuc 			theOTResult = ioSocket->mAsyncOperationResult;
450*ebfedea0SLionel Sambuc 
451*ebfedea0SLionel Sambuc 			break;
452*ebfedea0SLionel Sambuc 		}
453*ebfedea0SLionel Sambuc 
454*ebfedea0SLionel Sambuc 		if (ioSocket->mIdleWaitCallback != nil)
455*ebfedea0SLionel Sambuc 		{
456*ebfedea0SLionel Sambuc 			theOTResult = (*(ioSocket->mIdleWaitCallback))(ioSocket->mUserRefPtr);
457*ebfedea0SLionel Sambuc 
458*ebfedea0SLionel Sambuc 			if (theOTResult != noErr && returnImmediatelyOnError)
459*ebfedea0SLionel Sambuc 			{
460*ebfedea0SLionel Sambuc 				break;
461*ebfedea0SLionel Sambuc 			}
462*ebfedea0SLionel Sambuc 		}
463*ebfedea0SLionel Sambuc 
464*ebfedea0SLionel Sambuc 		if (TimeoutElapsed(ioSocket))
465*ebfedea0SLionel Sambuc 		{
466*ebfedea0SLionel Sambuc 			theOTResult = kMacSocket_TimeoutErr;
467*ebfedea0SLionel Sambuc 
468*ebfedea0SLionel Sambuc 			break;
469*ebfedea0SLionel Sambuc 		}
470*ebfedea0SLionel Sambuc 	}
471*ebfedea0SLionel Sambuc 
472*ebfedea0SLionel Sambuc 
473*ebfedea0SLionel Sambuc EXITPOINT:
474*ebfedea0SLionel Sambuc 
475*ebfedea0SLionel Sambuc 	if (outOTResult != nil)
476*ebfedea0SLionel Sambuc 	{
477*ebfedea0SLionel Sambuc 		*outOTResult = theOTResult;
478*ebfedea0SLionel Sambuc 	}
479*ebfedea0SLionel Sambuc 
480*ebfedea0SLionel Sambuc 	return(errCode);
481*ebfedea0SLionel Sambuc }
482*ebfedea0SLionel Sambuc 
483*ebfedea0SLionel Sambuc 
484*ebfedea0SLionel Sambuc 
485*ebfedea0SLionel Sambuc //	I used to do thread switching, but stopped.  It could easily be rolled back in though....
486*ebfedea0SLionel Sambuc 
OTNonYieldingNotifier(void * contextPtr,OTEventCode code,OTResult result,void * cookie)487*ebfedea0SLionel Sambuc static pascal void OTNonYieldingNotifier(void *contextPtr,OTEventCode code,OTResult result,void *cookie)
488*ebfedea0SLionel Sambuc {
489*ebfedea0SLionel Sambuc SocketStruct *theSocketStruct = (SocketStruct *) contextPtr;
490*ebfedea0SLionel Sambuc 
491*ebfedea0SLionel Sambuc 	if (theSocketStruct != nil)
492*ebfedea0SLionel Sambuc 	{
493*ebfedea0SLionel Sambuc 		if (theSocketStruct->mExpectedCode != 0 && code == theSocketStruct->mExpectedCode)
494*ebfedea0SLionel Sambuc 		{
495*ebfedea0SLionel Sambuc 			theSocketStruct->mAsyncOperationResult = result;
496*ebfedea0SLionel Sambuc 
497*ebfedea0SLionel Sambuc 			theSocketStruct->mExpectedCode = 0;
498*ebfedea0SLionel Sambuc 		}
499*ebfedea0SLionel Sambuc 
500*ebfedea0SLionel Sambuc 
501*ebfedea0SLionel Sambuc 		switch (code)
502*ebfedea0SLionel Sambuc 		{
503*ebfedea0SLionel Sambuc 			case T_OPENCOMPLETE:
504*ebfedea0SLionel Sambuc 			{
505*ebfedea0SLionel Sambuc 				theSocketStruct->mReceivedTOpenComplete = true;
506*ebfedea0SLionel Sambuc 
507*ebfedea0SLionel Sambuc 				theSocketStruct->mEndPointRef = (EndpointRef) cookie;
508*ebfedea0SLionel Sambuc 
509*ebfedea0SLionel Sambuc 				break;
510*ebfedea0SLionel Sambuc 			}
511*ebfedea0SLionel Sambuc 
512*ebfedea0SLionel Sambuc 
513*ebfedea0SLionel Sambuc 			case T_BINDCOMPLETE:
514*ebfedea0SLionel Sambuc 			{
515*ebfedea0SLionel Sambuc 				theSocketStruct->mReceivedTBindComplete = true;
516*ebfedea0SLionel Sambuc 
517*ebfedea0SLionel Sambuc 				break;
518*ebfedea0SLionel Sambuc 			}
519*ebfedea0SLionel Sambuc 
520*ebfedea0SLionel Sambuc 
521*ebfedea0SLionel Sambuc 			case T_CONNECT:
522*ebfedea0SLionel Sambuc 			{
523*ebfedea0SLionel Sambuc 				theSocketStruct->mReceivedTConnect = true;
524*ebfedea0SLionel Sambuc 
525*ebfedea0SLionel Sambuc 				theSocketStruct->mLocalEndIsConnected = true;
526*ebfedea0SLionel Sambuc 
527*ebfedea0SLionel Sambuc 				theSocketStruct->mRemoteEndIsConnected = true;
528*ebfedea0SLionel Sambuc 
529*ebfedea0SLionel Sambuc 				break;
530*ebfedea0SLionel Sambuc 			}
531*ebfedea0SLionel Sambuc 
532*ebfedea0SLionel Sambuc 
533*ebfedea0SLionel Sambuc 			case T_LISTEN:
534*ebfedea0SLionel Sambuc 			{
535*ebfedea0SLionel Sambuc 				theSocketStruct->mReceivedTListen = true;
536*ebfedea0SLionel Sambuc 
537*ebfedea0SLionel Sambuc 				break;
538*ebfedea0SLionel Sambuc 			}
539*ebfedea0SLionel Sambuc 
540*ebfedea0SLionel Sambuc 
541*ebfedea0SLionel Sambuc 			case T_PASSCON:
542*ebfedea0SLionel Sambuc 			{
543*ebfedea0SLionel Sambuc 				theSocketStruct->mReceivedTPassCon = true;
544*ebfedea0SLionel Sambuc 
545*ebfedea0SLionel Sambuc 				theSocketStruct->mLocalEndIsConnected = true;
546*ebfedea0SLionel Sambuc 
547*ebfedea0SLionel Sambuc 				theSocketStruct->mRemoteEndIsConnected = true;
548*ebfedea0SLionel Sambuc 
549*ebfedea0SLionel Sambuc 				break;
550*ebfedea0SLionel Sambuc 			}
551*ebfedea0SLionel Sambuc 
552*ebfedea0SLionel Sambuc 
553*ebfedea0SLionel Sambuc 			case T_DATA:
554*ebfedea0SLionel Sambuc 			{
555*ebfedea0SLionel Sambuc 				theSocketStruct->mReadyToReadData = true;
556*ebfedea0SLionel Sambuc 
557*ebfedea0SLionel Sambuc 				break;
558*ebfedea0SLionel Sambuc 			}
559*ebfedea0SLionel Sambuc 
560*ebfedea0SLionel Sambuc 			case T_GODATA:
561*ebfedea0SLionel Sambuc 			{
562*ebfedea0SLionel Sambuc 				theSocketStruct->mReadyToWriteData = true;
563*ebfedea0SLionel Sambuc 
564*ebfedea0SLionel Sambuc 				break;
565*ebfedea0SLionel Sambuc 			}
566*ebfedea0SLionel Sambuc 
567*ebfedea0SLionel Sambuc 			case T_DISCONNECT:
568*ebfedea0SLionel Sambuc 			{
569*ebfedea0SLionel Sambuc 				theSocketStruct->mReceivedTDisconnect = true;
570*ebfedea0SLionel Sambuc 
571*ebfedea0SLionel Sambuc 				theSocketStruct->mRemoteEndIsConnected = false;
572*ebfedea0SLionel Sambuc 
573*ebfedea0SLionel Sambuc 				theSocketStruct->mLocalEndIsConnected = false;
574*ebfedea0SLionel Sambuc 
575*ebfedea0SLionel Sambuc 				::OTRcvDisconnect(theSocketStruct->mEndPointRef,nil);
576*ebfedea0SLionel Sambuc 
577*ebfedea0SLionel Sambuc 				break;
578*ebfedea0SLionel Sambuc 			}
579*ebfedea0SLionel Sambuc 
580*ebfedea0SLionel Sambuc 			case T_ORDREL:
581*ebfedea0SLionel Sambuc 			{
582*ebfedea0SLionel Sambuc 				theSocketStruct->mReceivedTOrdRel = true;
583*ebfedea0SLionel Sambuc 
584*ebfedea0SLionel Sambuc 				//	We can still write data, so don't clear mRemoteEndIsConnected
585*ebfedea0SLionel Sambuc 
586*ebfedea0SLionel Sambuc 				::OTRcvOrderlyDisconnect(theSocketStruct->mEndPointRef);
587*ebfedea0SLionel Sambuc 
588*ebfedea0SLionel Sambuc 				break;
589*ebfedea0SLionel Sambuc 			}
590*ebfedea0SLionel Sambuc 
591*ebfedea0SLionel Sambuc 			case T_DISCONNECTCOMPLETE:
592*ebfedea0SLionel Sambuc 			{
593*ebfedea0SLionel Sambuc 				theSocketStruct->mReceivedTDisconnectComplete = true;
594*ebfedea0SLionel Sambuc 
595*ebfedea0SLionel Sambuc 				theSocketStruct->mRemoteEndIsConnected = false;
596*ebfedea0SLionel Sambuc 
597*ebfedea0SLionel Sambuc 				theSocketStruct->mLocalEndIsConnected = false;
598*ebfedea0SLionel Sambuc 
599*ebfedea0SLionel Sambuc 				break;
600*ebfedea0SLionel Sambuc 			}
601*ebfedea0SLionel Sambuc 		}
602*ebfedea0SLionel Sambuc 	}
603*ebfedea0SLionel Sambuc /*
604*ebfedea0SLionel Sambuc T_LISTEN OTListen
605*ebfedea0SLionel Sambuc T_CONNECT OTRcvConnect
606*ebfedea0SLionel Sambuc T_DATA OTRcv, OTRcvUData
607*ebfedea0SLionel Sambuc T_DISCONNECT OTRcvDisconnect
608*ebfedea0SLionel Sambuc T_ORDREL OTRcvOrderlyDisconnect
609*ebfedea0SLionel Sambuc T_GODATA OTSnd, OTSndUData, OTLook
610*ebfedea0SLionel Sambuc T_PASSCON none
611*ebfedea0SLionel Sambuc 
612*ebfedea0SLionel Sambuc T_EXDATA OTRcv
613*ebfedea0SLionel Sambuc T_GOEXDATA OTSnd, OTLook
614*ebfedea0SLionel Sambuc T_UDERR OTRcvUDErr
615*ebfedea0SLionel Sambuc */
616*ebfedea0SLionel Sambuc }
617*ebfedea0SLionel Sambuc 
618*ebfedea0SLionel Sambuc 
619*ebfedea0SLionel Sambuc 
620*ebfedea0SLionel Sambuc //	Initialize the main socket data structure
621*ebfedea0SLionel Sambuc 
MacSocket_Startup(void)622*ebfedea0SLionel Sambuc OSErr MacSocket_Startup(void)
623*ebfedea0SLionel Sambuc {
624*ebfedea0SLionel Sambuc 	if (!sSocketsSetup)
625*ebfedea0SLionel Sambuc 	{
626*ebfedea0SLionel Sambuc 		for (int i = 0;i < kMaxNumSockets;i++)
627*ebfedea0SLionel Sambuc 		{
628*ebfedea0SLionel Sambuc 			InitSocket(&(sSockets[i]));
629*ebfedea0SLionel Sambuc 		}
630*ebfedea0SLionel Sambuc 
631*ebfedea0SLionel Sambuc 		::InitOpenTransport();
632*ebfedea0SLionel Sambuc 
633*ebfedea0SLionel Sambuc 		sSocketsSetup = true;
634*ebfedea0SLionel Sambuc 	}
635*ebfedea0SLionel Sambuc 
636*ebfedea0SLionel Sambuc 
637*ebfedea0SLionel Sambuc 	return(noErr);
638*ebfedea0SLionel Sambuc }
639*ebfedea0SLionel Sambuc 
640*ebfedea0SLionel Sambuc 
641*ebfedea0SLionel Sambuc 
642*ebfedea0SLionel Sambuc //	Cleanup before exiting
643*ebfedea0SLionel Sambuc 
MacSocket_Shutdown(void)644*ebfedea0SLionel Sambuc OSErr MacSocket_Shutdown(void)
645*ebfedea0SLionel Sambuc {
646*ebfedea0SLionel Sambuc 	if (sSocketsSetup)
647*ebfedea0SLionel Sambuc 	{
648*ebfedea0SLionel Sambuc 		for (int i = 0;i < kMaxNumSockets;i++)
649*ebfedea0SLionel Sambuc 		{
650*ebfedea0SLionel Sambuc 		SocketStruct *theSocketStruct = &(sSockets[i]);
651*ebfedea0SLionel Sambuc 
652*ebfedea0SLionel Sambuc 			if (theSocketStruct->mIsInUse)
653*ebfedea0SLionel Sambuc 			{
654*ebfedea0SLionel Sambuc 				if (theSocketStruct->mEndPointRef != kOTInvalidEndpointRef)
655*ebfedea0SLionel Sambuc 				{
656*ebfedea0SLionel Sambuc 				OTResult	theOTResult;
657*ebfedea0SLionel Sambuc 
658*ebfedea0SLionel Sambuc 
659*ebfedea0SLionel Sambuc 					//	Since we're killing the endpoint, I don't bother to send the disconnect (sorry!)
660*ebfedea0SLionel Sambuc 
661*ebfedea0SLionel Sambuc /*
662*ebfedea0SLionel Sambuc 					if (theSocketStruct->mLocalEndIsConnected)
663*ebfedea0SLionel Sambuc 					{
664*ebfedea0SLionel Sambuc 						//	This is an abortive action, so we do a hard disconnect instead of an OTSndOrderlyDisconnect
665*ebfedea0SLionel Sambuc 
666*ebfedea0SLionel Sambuc 						theOTResult = ::OTSndDisconnect(theSocketStruct->mEndPointRef, nil);
667*ebfedea0SLionel Sambuc 
668*ebfedea0SLionel Sambuc 						//	Now we have to watch for T_DISCONNECTCOMPLETE event
669*ebfedea0SLionel Sambuc 
670*ebfedea0SLionel Sambuc 						theSocketStruct->mLocalEndIsConnected = false;
671*ebfedea0SLionel Sambuc 					}
672*ebfedea0SLionel Sambuc */
673*ebfedea0SLionel Sambuc 
674*ebfedea0SLionel Sambuc 					theOTResult = ::OTCloseProvider(theSocketStruct->mEndPointRef);
675*ebfedea0SLionel Sambuc 
676*ebfedea0SLionel Sambuc 
677*ebfedea0SLionel Sambuc 					theSocketStruct->mEndPointRef = kOTInvalidEndpointRef;
678*ebfedea0SLionel Sambuc 				}
679*ebfedea0SLionel Sambuc 
680*ebfedea0SLionel Sambuc 				if (theSocketStruct->mBindRequestedAddrInfo != nil)
681*ebfedea0SLionel Sambuc 				{
682*ebfedea0SLionel Sambuc 					::OTFree((void *) theSocketStruct->mBindRequestedAddrInfo,T_BIND);
683*ebfedea0SLionel Sambuc 
684*ebfedea0SLionel Sambuc 					theSocketStruct->mBindRequestedAddrInfo = nil;
685*ebfedea0SLionel Sambuc 				}
686*ebfedea0SLionel Sambuc 
687*ebfedea0SLionel Sambuc 				if (theSocketStruct->mAssignedAddrInfo != nil)
688*ebfedea0SLionel Sambuc 				{
689*ebfedea0SLionel Sambuc 					::OTFree((void *) theSocketStruct->mAssignedAddrInfo,T_BIND);
690*ebfedea0SLionel Sambuc 
691*ebfedea0SLionel Sambuc 					theSocketStruct->mAssignedAddrInfo = nil;
692*ebfedea0SLionel Sambuc 				}
693*ebfedea0SLionel Sambuc 
694*ebfedea0SLionel Sambuc 				if (theSocketStruct->mRemoteAddrInfo != nil)
695*ebfedea0SLionel Sambuc 				{
696*ebfedea0SLionel Sambuc 					::OTFree((void *) theSocketStruct->mRemoteAddrInfo,T_CALL);
697*ebfedea0SLionel Sambuc 
698*ebfedea0SLionel Sambuc 					theSocketStruct->mRemoteAddrInfo = nil;
699*ebfedea0SLionel Sambuc 				}
700*ebfedea0SLionel Sambuc 
701*ebfedea0SLionel Sambuc 
702*ebfedea0SLionel Sambuc 			}
703*ebfedea0SLionel Sambuc 		}
704*ebfedea0SLionel Sambuc 
705*ebfedea0SLionel Sambuc 		::CloseOpenTransport();
706*ebfedea0SLionel Sambuc 
707*ebfedea0SLionel Sambuc 		sSocketsSetup = false;
708*ebfedea0SLionel Sambuc 	}
709*ebfedea0SLionel Sambuc 
710*ebfedea0SLionel Sambuc 	return(noErr);
711*ebfedea0SLionel Sambuc }
712*ebfedea0SLionel Sambuc 
713*ebfedea0SLionel Sambuc 
714*ebfedea0SLionel Sambuc 
715*ebfedea0SLionel Sambuc 
716*ebfedea0SLionel Sambuc 
717*ebfedea0SLionel Sambuc 
718*ebfedea0SLionel Sambuc //	Allocate a socket
719*ebfedea0SLionel Sambuc 
MacSocket_socket(int * outSocketNum,const Boolean inDoThreadSwitching,const long inTimeoutTicks,MacSocket_IdleWaitCallback inIdleWaitCallback,void * inUserRefPtr)720*ebfedea0SLionel Sambuc OSErr MacSocket_socket(int *outSocketNum,const Boolean inDoThreadSwitching,const long inTimeoutTicks,MacSocket_IdleWaitCallback inIdleWaitCallback,void *inUserRefPtr)
721*ebfedea0SLionel Sambuc {
722*ebfedea0SLionel Sambuc //	Gotta roll support back in for threads eventually.....
723*ebfedea0SLionel Sambuc 
724*ebfedea0SLionel Sambuc #pragma unused(inDoThreadSwitching)
725*ebfedea0SLionel Sambuc 
726*ebfedea0SLionel Sambuc 
727*ebfedea0SLionel Sambuc OSErr	errCode = noErr;
728*ebfedea0SLionel Sambuc 
729*ebfedea0SLionel Sambuc 
730*ebfedea0SLionel Sambuc 	SetErrorMessageAndBailIfNil(outSocketNum,"MacSocket_socket: Bad parameter, outSocketNum == nil");
731*ebfedea0SLionel Sambuc 
732*ebfedea0SLionel Sambuc 	*outSocketNum = -1;
733*ebfedea0SLionel Sambuc 
734*ebfedea0SLionel Sambuc 
735*ebfedea0SLionel Sambuc 	//	Find an unused socket
736*ebfedea0SLionel Sambuc 
737*ebfedea0SLionel Sambuc 	for (int i = 0;i < kMaxNumSockets;i++)
738*ebfedea0SLionel Sambuc 	{
739*ebfedea0SLionel Sambuc 		if (sSockets[i].mIsInUse == false)
740*ebfedea0SLionel Sambuc 		{
741*ebfedea0SLionel Sambuc 		OTResult		theOTResult;
742*ebfedea0SLionel Sambuc 		SocketStruct	*theSocketStruct = &(sSockets[i]);
743*ebfedea0SLionel Sambuc 
744*ebfedea0SLionel Sambuc 
745*ebfedea0SLionel Sambuc 			InitSocket(theSocketStruct);
746*ebfedea0SLionel Sambuc 
747*ebfedea0SLionel Sambuc 			theSocketStruct->mIdleWaitCallback = inIdleWaitCallback;
748*ebfedea0SLionel Sambuc 			theSocketStruct->mUserRefPtr = inUserRefPtr;
749*ebfedea0SLionel Sambuc 
750*ebfedea0SLionel Sambuc 			theSocketStruct->mTimeoutTicks = inTimeoutTicks;
751*ebfedea0SLionel Sambuc 
752*ebfedea0SLionel Sambuc 
753*ebfedea0SLionel Sambuc 			//	Set up OT endpoint
754*ebfedea0SLionel Sambuc 
755*ebfedea0SLionel Sambuc 			PrepareForAsyncOperation(theSocketStruct,T_OPENCOMPLETE);
756*ebfedea0SLionel Sambuc 
757*ebfedea0SLionel Sambuc 			theOTResult = ::OTAsyncOpenEndpoint(OTCreateConfiguration(kTCPName),0,nil,OTNonYieldingNotifier,(void *) theSocketStruct);
758*ebfedea0SLionel Sambuc 
759*ebfedea0SLionel Sambuc 			SetErrorMessageAndLongIntAndBailIfError(theOTResult,"MacSocket_socket: Can't create OT endpoint, OTAsyncOpenEndpoint() = ",theOTResult);
760*ebfedea0SLionel Sambuc 
761*ebfedea0SLionel Sambuc 			BailIfError(MyBusyWait(theSocketStruct,false,&theOTResult,&(theSocketStruct->mReceivedTOpenComplete)));
762*ebfedea0SLionel Sambuc 
763*ebfedea0SLionel Sambuc 			SetErrorMessageAndLongIntAndBailIfError(theOTResult,"MacSocket_socket: Can't create OT endpoint, OTAsyncOpenEndpoint() = ",theOTResult);
764*ebfedea0SLionel Sambuc 
765*ebfedea0SLionel Sambuc 
766*ebfedea0SLionel Sambuc 			*outSocketNum = i;
767*ebfedea0SLionel Sambuc 
768*ebfedea0SLionel Sambuc 			errCode = noErr;
769*ebfedea0SLionel Sambuc 
770*ebfedea0SLionel Sambuc 			theSocketStruct->mIsInUse = true;
771*ebfedea0SLionel Sambuc 
772*ebfedea0SLionel Sambuc 			break;
773*ebfedea0SLionel Sambuc 		}
774*ebfedea0SLionel Sambuc 
775*ebfedea0SLionel Sambuc 		else if (i == kMaxNumSockets - 1)
776*ebfedea0SLionel Sambuc 		{
777*ebfedea0SLionel Sambuc 			SetErrorMessageAndBail("MacSocket_socket: No sockets available");
778*ebfedea0SLionel Sambuc 		}
779*ebfedea0SLionel Sambuc 	}
780*ebfedea0SLionel Sambuc 
781*ebfedea0SLionel Sambuc 
782*ebfedea0SLionel Sambuc EXITPOINT:
783*ebfedea0SLionel Sambuc 
784*ebfedea0SLionel Sambuc 	errno = errCode;
785*ebfedea0SLionel Sambuc 
786*ebfedea0SLionel Sambuc 	return(errCode);
787*ebfedea0SLionel Sambuc }
788*ebfedea0SLionel Sambuc 
789*ebfedea0SLionel Sambuc 
790*ebfedea0SLionel Sambuc 
791*ebfedea0SLionel Sambuc 
MacSocket_listen(const int inSocketNum,const int inPortNum)792*ebfedea0SLionel Sambuc OSErr MacSocket_listen(const int inSocketNum,const int inPortNum)
793*ebfedea0SLionel Sambuc {
794*ebfedea0SLionel Sambuc OSErr			errCode = noErr;
795*ebfedea0SLionel Sambuc SocketStruct	*theSocketStruct = nil;
796*ebfedea0SLionel Sambuc 
797*ebfedea0SLionel Sambuc 
798*ebfedea0SLionel Sambuc 	if (!SocketIndexIsValid(inSocketNum))
799*ebfedea0SLionel Sambuc 	{
800*ebfedea0SLionel Sambuc 		SetErrorMessageAndBail("MacSocket_listen: Invalid socket number specified");
801*ebfedea0SLionel Sambuc 	}
802*ebfedea0SLionel Sambuc 
803*ebfedea0SLionel Sambuc 
804*ebfedea0SLionel Sambuc 	theSocketStruct = &(sSockets[inSocketNum]);
805*ebfedea0SLionel Sambuc 
806*ebfedea0SLionel Sambuc 
807*ebfedea0SLionel Sambuc OTResult		theOTResult;
808*ebfedea0SLionel Sambuc 
809*ebfedea0SLionel Sambuc 
810*ebfedea0SLionel Sambuc 	if (theSocketStruct->mBindRequestedAddrInfo == nil)
811*ebfedea0SLionel Sambuc 	{
812*ebfedea0SLionel Sambuc 		theSocketStruct->mBindRequestedAddrInfo = (TBind *) ::OTAlloc(theSocketStruct->mEndPointRef,T_BIND,T_ADDR,&theOTResult);
813*ebfedea0SLionel Sambuc 
814*ebfedea0SLionel Sambuc 		SetErrorMessageAndLongIntAndBailIfError(theOTResult,"MacSocket_listen: Can't allocate OT T_BIND structure, OTAlloc() = ",theOTResult);
815*ebfedea0SLionel Sambuc 		SetErrorMessageAndBailIfNil(theSocketStruct->mBindRequestedAddrInfo,"MacSocket_listen: Can't allocate OT T_BIND structure, OTAlloc() returned nil");
816*ebfedea0SLionel Sambuc 	}
817*ebfedea0SLionel Sambuc 
818*ebfedea0SLionel Sambuc 	if (theSocketStruct->mAssignedAddrInfo == nil)
819*ebfedea0SLionel Sambuc 	{
820*ebfedea0SLionel Sambuc 		theSocketStruct->mAssignedAddrInfo = (TBind *) ::OTAlloc(theSocketStruct->mEndPointRef,T_BIND,T_ADDR,&theOTResult);
821*ebfedea0SLionel Sambuc 
822*ebfedea0SLionel Sambuc 		SetErrorMessageAndLongIntAndBailIfError(theOTResult,"MacSocket_listen: Can't allocate OT T_BIND structure, OTAlloc() = ",theOTResult);
823*ebfedea0SLionel Sambuc 		SetErrorMessageAndBailIfNil(theSocketStruct->mAssignedAddrInfo,"MacSocket_listen: Can't allocate OT T_BIND structure, OTAlloc() returned nil");
824*ebfedea0SLionel Sambuc 	}
825*ebfedea0SLionel Sambuc 
826*ebfedea0SLionel Sambuc 	if (theSocketStruct->mRemoteAddrInfo == nil)
827*ebfedea0SLionel Sambuc 	{
828*ebfedea0SLionel Sambuc 		theSocketStruct->mRemoteAddrInfo = (TCall *) ::OTAlloc(theSocketStruct->mEndPointRef,T_CALL,T_ADDR,&theOTResult);
829*ebfedea0SLionel Sambuc 
830*ebfedea0SLionel Sambuc 		SetErrorMessageAndLongIntAndBailIfError(theOTResult,"MacSocket_listen: Can't allocate OT T_CALL structure, OTAlloc() = ",theOTResult);
831*ebfedea0SLionel Sambuc 		SetErrorMessageAndBailIfNil(theSocketStruct->mRemoteAddrInfo,"MacSocket_listen: Can't allocate OT T_CALL structure, OTAlloc() returned nil");
832*ebfedea0SLionel Sambuc 	}
833*ebfedea0SLionel Sambuc 
834*ebfedea0SLionel Sambuc 
835*ebfedea0SLionel Sambuc 	if (!theSocketStruct->mEndpointIsBound)
836*ebfedea0SLionel Sambuc 	{
837*ebfedea0SLionel Sambuc 	InetInterfaceInfo	theInetInterfaceInfo;
838*ebfedea0SLionel Sambuc 
839*ebfedea0SLionel Sambuc 		theOTResult = ::OTInetGetInterfaceInfo(&theInetInterfaceInfo,kDefaultInetInterface);
840*ebfedea0SLionel Sambuc 
841*ebfedea0SLionel Sambuc 		SetErrorMessageAndLongIntAndBailIfError(theOTResult,"MacSocket_listen: Can't determine OT interface info, OTInetGetInterfaceInfo() = ",theOTResult);
842*ebfedea0SLionel Sambuc 
843*ebfedea0SLionel Sambuc 
844*ebfedea0SLionel Sambuc 	InetAddress	*theInetAddress = (InetAddress *) theSocketStruct->mBindRequestedAddrInfo->addr.buf;
845*ebfedea0SLionel Sambuc 
846*ebfedea0SLionel Sambuc //		theInetAddress->fAddressType = AF_INET;
847*ebfedea0SLionel Sambuc //		theInetAddress->fPort = inPortNum;
848*ebfedea0SLionel Sambuc //		theInetAddress->fHost = theInetInterfaceInfo.fAddress;
849*ebfedea0SLionel Sambuc 
850*ebfedea0SLionel Sambuc 		::OTInitInetAddress(theInetAddress,inPortNum,theInetInterfaceInfo.fAddress);
851*ebfedea0SLionel Sambuc 
852*ebfedea0SLionel Sambuc 		theSocketStruct->mBindRequestedAddrInfo->addr.len = sizeof(InetAddress);
853*ebfedea0SLionel Sambuc 
854*ebfedea0SLionel Sambuc 		theSocketStruct->mBindRequestedAddrInfo->qlen = 1;
855*ebfedea0SLionel Sambuc 
856*ebfedea0SLionel Sambuc 
857*ebfedea0SLionel Sambuc 		theOTResult = ::OTSetSynchronous(theSocketStruct->mEndPointRef);
858*ebfedea0SLionel Sambuc 
859*ebfedea0SLionel Sambuc 		SetErrorMessageAndLongIntAndBailIfError(theOTResult,"MacSocket_listen: Can't set OT endpoint mode, OTSetSynchronous() = ",theOTResult);
860*ebfedea0SLionel Sambuc 
861*ebfedea0SLionel Sambuc 		theOTResult = NegotiateIPReuseAddrOption(theSocketStruct->mEndPointRef,true);
862*ebfedea0SLionel Sambuc 
863*ebfedea0SLionel Sambuc 		SetErrorMessageAndLongIntAndBailIfError(theOTResult,"MacSocket_listen: Can't set OT IP address reuse flag, NegotiateIPReuseAddrOption() = ",theOTResult);
864*ebfedea0SLionel Sambuc 
865*ebfedea0SLionel Sambuc 		theOTResult = ::OTSetAsynchronous(theSocketStruct->mEndPointRef);
866*ebfedea0SLionel Sambuc 
867*ebfedea0SLionel Sambuc 		SetErrorMessageAndLongIntAndBailIfError(theOTResult,"MacSocket_listen: Can't set OT endpoint mode, OTSetAsynchronous() = ",theOTResult);
868*ebfedea0SLionel Sambuc 
869*ebfedea0SLionel Sambuc 
870*ebfedea0SLionel Sambuc 		PrepareForAsyncOperation(theSocketStruct,T_BINDCOMPLETE);
871*ebfedea0SLionel Sambuc 
872*ebfedea0SLionel Sambuc 		theOTResult = ::OTBind(theSocketStruct->mEndPointRef,theSocketStruct->mBindRequestedAddrInfo,theSocketStruct->mAssignedAddrInfo);
873*ebfedea0SLionel Sambuc 
874*ebfedea0SLionel Sambuc 		SetErrorMessageAndLongIntAndBailIfError(theOTResult,"MacSocket_listen: Can't bind OT endpoint, OTBind() = ",theOTResult);
875*ebfedea0SLionel Sambuc 
876*ebfedea0SLionel Sambuc 		BailIfError(MyBusyWait(theSocketStruct,false,&theOTResult,&(theSocketStruct->mReceivedTBindComplete)));
877*ebfedea0SLionel Sambuc 
878*ebfedea0SLionel Sambuc 		SetErrorMessageAndLongIntAndBailIfError(theOTResult,"MacSocket_listen: Can't bind OT endpoint, OTBind() = ",theOTResult);
879*ebfedea0SLionel Sambuc 
880*ebfedea0SLionel Sambuc 
881*ebfedea0SLionel Sambuc 		theSocketStruct->mEndpointIsBound = true;
882*ebfedea0SLionel Sambuc 	}
883*ebfedea0SLionel Sambuc 
884*ebfedea0SLionel Sambuc 
885*ebfedea0SLionel Sambuc 	PrepareForAsyncOperation(theSocketStruct,T_LISTEN);
886*ebfedea0SLionel Sambuc 
887*ebfedea0SLionel Sambuc 	theOTResult = ::OTListen(theSocketStruct->mEndPointRef,theSocketStruct->mRemoteAddrInfo);
888*ebfedea0SLionel Sambuc 
889*ebfedea0SLionel Sambuc 	if (theOTResult == noErr)
890*ebfedea0SLionel Sambuc 	{
891*ebfedea0SLionel Sambuc 		PrepareForAsyncOperation(theSocketStruct,T_PASSCON);
892*ebfedea0SLionel Sambuc 
893*ebfedea0SLionel Sambuc 		theOTResult = ::OTAccept(theSocketStruct->mEndPointRef,theSocketStruct->mEndPointRef,theSocketStruct->mRemoteAddrInfo);
894*ebfedea0SLionel Sambuc 
895*ebfedea0SLionel Sambuc 		SetErrorMessageAndLongIntAndBailIfError(theOTResult,"MacSocket_listen: Can't begin OT accept, OTAccept() = ",theOTResult);
896*ebfedea0SLionel Sambuc 
897*ebfedea0SLionel Sambuc 		BailIfError(MyBusyWait(theSocketStruct,false,&theOTResult,&(theSocketStruct->mReceivedTPassCon)));
898*ebfedea0SLionel Sambuc 
899*ebfedea0SLionel Sambuc 		SetErrorMessageAndLongIntAndBailIfError(theOTResult,"MacSocket_listen: Can't accept OT connection, OTAccept() = ",theOTResult);
900*ebfedea0SLionel Sambuc 	}
901*ebfedea0SLionel Sambuc 
902*ebfedea0SLionel Sambuc 	else if (theOTResult == kOTNoDataErr)
903*ebfedea0SLionel Sambuc 	{
904*ebfedea0SLionel Sambuc 		theOTResult = noErr;
905*ebfedea0SLionel Sambuc 	}
906*ebfedea0SLionel Sambuc 
907*ebfedea0SLionel Sambuc 	else
908*ebfedea0SLionel Sambuc 	{
909*ebfedea0SLionel Sambuc 		SetErrorMessageAndLongIntAndBail("MacSocket_listen: Can't begin OT listen, OTListen() = ",theOTResult);
910*ebfedea0SLionel Sambuc 	}
911*ebfedea0SLionel Sambuc 
912*ebfedea0SLionel Sambuc 
913*ebfedea0SLionel Sambuc 	errCode = noErr;
914*ebfedea0SLionel Sambuc 
915*ebfedea0SLionel Sambuc 
916*ebfedea0SLionel Sambuc EXITPOINT:
917*ebfedea0SLionel Sambuc 
918*ebfedea0SLionel Sambuc 	if (theSocketStruct != nil)
919*ebfedea0SLionel Sambuc 	{
920*ebfedea0SLionel Sambuc 		theSocketStruct->mLastError = noErr;
921*ebfedea0SLionel Sambuc 
922*ebfedea0SLionel Sambuc 		CopyCStrToCStr("",theSocketStruct->mErrMessage,sizeof(theSocketStruct->mErrMessage));
923*ebfedea0SLionel Sambuc 
924*ebfedea0SLionel Sambuc 		if (errCode != noErr)
925*ebfedea0SLionel Sambuc 		{
926*ebfedea0SLionel Sambuc 			theSocketStruct->mLastError = errCode;
927*ebfedea0SLionel Sambuc 
928*ebfedea0SLionel Sambuc 			CopyCStrToCStr(GetErrorMessage(),theSocketStruct->mErrMessage,sizeof(theSocketStruct->mErrMessage));
929*ebfedea0SLionel Sambuc 		}
930*ebfedea0SLionel Sambuc 	}
931*ebfedea0SLionel Sambuc 
932*ebfedea0SLionel Sambuc 	errno = errCode;
933*ebfedea0SLionel Sambuc 
934*ebfedea0SLionel Sambuc 	return(errCode);
935*ebfedea0SLionel Sambuc }
936*ebfedea0SLionel Sambuc 
937*ebfedea0SLionel Sambuc 
938*ebfedea0SLionel Sambuc 
939*ebfedea0SLionel Sambuc 
MacSocket_connect(const int inSocketNum,char * inTargetAddressAndPort)940*ebfedea0SLionel Sambuc OSErr MacSocket_connect(const int inSocketNum,char *inTargetAddressAndPort)
941*ebfedea0SLionel Sambuc {
942*ebfedea0SLionel Sambuc OSErr			errCode = noErr;
943*ebfedea0SLionel Sambuc SocketStruct	*theSocketStruct = nil;
944*ebfedea0SLionel Sambuc 
945*ebfedea0SLionel Sambuc 
946*ebfedea0SLionel Sambuc 	if (!SocketIndexIsValid(inSocketNum))
947*ebfedea0SLionel Sambuc 	{
948*ebfedea0SLionel Sambuc 		SetErrorMessageAndBail("MacSocket_connect: Invalid socket number specified");
949*ebfedea0SLionel Sambuc 	}
950*ebfedea0SLionel Sambuc 
951*ebfedea0SLionel Sambuc 	theSocketStruct = &(sSockets[inSocketNum]);
952*ebfedea0SLionel Sambuc 
953*ebfedea0SLionel Sambuc 	if (theSocketStruct->mEndpointIsBound)
954*ebfedea0SLionel Sambuc 	{
955*ebfedea0SLionel Sambuc 		SetErrorMessageAndBail("MacSocket_connect: Socket previously bound");
956*ebfedea0SLionel Sambuc 	}
957*ebfedea0SLionel Sambuc 
958*ebfedea0SLionel Sambuc 
959*ebfedea0SLionel Sambuc OTResult		theOTResult;
960*ebfedea0SLionel Sambuc 
961*ebfedea0SLionel Sambuc 	theSocketStruct->mBindRequestedAddrInfo = (TBind *) ::OTAlloc(theSocketStruct->mEndPointRef,T_BIND,T_ADDR,&theOTResult);
962*ebfedea0SLionel Sambuc 
963*ebfedea0SLionel Sambuc 	SetErrorMessageAndLongIntAndBailIfError(theOTResult,"MacSocket_connect: Can't allocate OT T_BIND structure, OTAlloc() = ",theOTResult);
964*ebfedea0SLionel Sambuc 	SetErrorMessageAndBailIfNil(theSocketStruct->mBindRequestedAddrInfo,"MacSocket_connect: Can't allocate OT T_BIND structure, OTAlloc() returned nil");
965*ebfedea0SLionel Sambuc 
966*ebfedea0SLionel Sambuc 
967*ebfedea0SLionel Sambuc 	theSocketStruct->mAssignedAddrInfo = (TBind *) ::OTAlloc(theSocketStruct->mEndPointRef,T_BIND,T_ADDR,&theOTResult);
968*ebfedea0SLionel Sambuc 
969*ebfedea0SLionel Sambuc 	SetErrorMessageAndLongIntAndBailIfError(theOTResult,"MacSocket_connect: Can't allocate OT T_BIND structure, OTAlloc() = ",theOTResult);
970*ebfedea0SLionel Sambuc 	SetErrorMessageAndBailIfNil(theSocketStruct->mAssignedAddrInfo,"MacSocket_connect: Can't allocate OT T_BIND structure, OTAlloc() returned nil");
971*ebfedea0SLionel Sambuc 
972*ebfedea0SLionel Sambuc 
973*ebfedea0SLionel Sambuc 	theSocketStruct->mRemoteAddrInfo = (TCall *) ::OTAlloc(theSocketStruct->mEndPointRef,T_CALL,T_ADDR,&theOTResult);
974*ebfedea0SLionel Sambuc 
975*ebfedea0SLionel Sambuc 	SetErrorMessageAndLongIntAndBailIfError(theOTResult,"MacSocket_connect: Can't allocate OT T_CALL structure, OTAlloc() = ",theOTResult);
976*ebfedea0SLionel Sambuc 	SetErrorMessageAndBailIfNil(theSocketStruct->mRemoteAddrInfo,"MacSocket_connect: Can't allocate OT T_CALL structure, OTAlloc() returned nil");
977*ebfedea0SLionel Sambuc 
978*ebfedea0SLionel Sambuc 
979*ebfedea0SLionel Sambuc 	PrepareForAsyncOperation(theSocketStruct,T_BINDCOMPLETE);
980*ebfedea0SLionel Sambuc 
981*ebfedea0SLionel Sambuc 	theOTResult = ::OTBind(theSocketStruct->mEndPointRef,nil,theSocketStruct->mAssignedAddrInfo);
982*ebfedea0SLionel Sambuc 
983*ebfedea0SLionel Sambuc 	SetErrorMessageAndLongIntAndBailIfError(theOTResult,"MacSocket_connect: Can't bind OT endpoint, OTBind() = ",theOTResult);
984*ebfedea0SLionel Sambuc 
985*ebfedea0SLionel Sambuc 	BailIfError(MyBusyWait(theSocketStruct,false,&theOTResult,&(theSocketStruct->mReceivedTBindComplete)));
986*ebfedea0SLionel Sambuc 
987*ebfedea0SLionel Sambuc 	SetErrorMessageAndLongIntAndBailIfError(theOTResult,"MacSocket_connect: Can't bind OT endpoint, OTBind() = ",theOTResult);
988*ebfedea0SLionel Sambuc 
989*ebfedea0SLionel Sambuc 	theSocketStruct->mEndpointIsBound = true;
990*ebfedea0SLionel Sambuc 
991*ebfedea0SLionel Sambuc 
992*ebfedea0SLionel Sambuc TCall		sndCall;
993*ebfedea0SLionel Sambuc DNSAddress 	hostDNSAddress;
994*ebfedea0SLionel Sambuc 
995*ebfedea0SLionel Sambuc 	//	Set up target address
996*ebfedea0SLionel Sambuc 
997*ebfedea0SLionel Sambuc 	sndCall.addr.buf = (UInt8 *) &hostDNSAddress;
998*ebfedea0SLionel Sambuc 	sndCall.addr.len = ::OTInitDNSAddress(&hostDNSAddress,inTargetAddressAndPort);
999*ebfedea0SLionel Sambuc 	sndCall.opt.buf = nil;
1000*ebfedea0SLionel Sambuc 	sndCall.opt.len = 0;
1001*ebfedea0SLionel Sambuc 	sndCall.udata.buf = nil;
1002*ebfedea0SLionel Sambuc 	sndCall.udata.len = 0;
1003*ebfedea0SLionel Sambuc 	sndCall.sequence = 0;
1004*ebfedea0SLionel Sambuc 
1005*ebfedea0SLionel Sambuc 	//	Connect!
1006*ebfedea0SLionel Sambuc 
1007*ebfedea0SLionel Sambuc 	PrepareForAsyncOperation(theSocketStruct,T_CONNECT);
1008*ebfedea0SLionel Sambuc 
1009*ebfedea0SLionel Sambuc 	theOTResult = ::OTConnect(theSocketStruct->mEndPointRef,&sndCall,nil);
1010*ebfedea0SLionel Sambuc 
1011*ebfedea0SLionel Sambuc 	if (theOTResult == kOTNoDataErr)
1012*ebfedea0SLionel Sambuc 	{
1013*ebfedea0SLionel Sambuc 		theOTResult = noErr;
1014*ebfedea0SLionel Sambuc 	}
1015*ebfedea0SLionel Sambuc 
1016*ebfedea0SLionel Sambuc 	SetErrorMessageAndLongIntAndBailIfError(theOTResult,"MacSocket_connect: Can't connect OT endpoint, OTConnect() = ",theOTResult);
1017*ebfedea0SLionel Sambuc 
1018*ebfedea0SLionel Sambuc 	BailIfError(MyBusyWait(theSocketStruct,false,&theOTResult,&(theSocketStruct->mReceivedTConnect)));
1019*ebfedea0SLionel Sambuc 
1020*ebfedea0SLionel Sambuc 	if (theOTResult == kMacSocket_TimeoutErr)
1021*ebfedea0SLionel Sambuc 	{
1022*ebfedea0SLionel Sambuc 		SetErrorMessageAndBail("MacSocket_connect: Can't connect OT endpoint, OTConnect() = kMacSocket_TimeoutErr");
1023*ebfedea0SLionel Sambuc 	}
1024*ebfedea0SLionel Sambuc 
1025*ebfedea0SLionel Sambuc 	else
1026*ebfedea0SLionel Sambuc 	{
1027*ebfedea0SLionel Sambuc 		SetErrorMessageAndLongIntAndBailIfError(theOTResult,"MacSocket_connect: Can't connect OT endpoint, OTConnect() = ",theOTResult);
1028*ebfedea0SLionel Sambuc 	}
1029*ebfedea0SLionel Sambuc 
1030*ebfedea0SLionel Sambuc 	theOTResult = ::OTRcvConnect(theSocketStruct->mEndPointRef,nil);
1031*ebfedea0SLionel Sambuc 
1032*ebfedea0SLionel Sambuc 	SetErrorMessageAndLongIntAndBailIfError(theOTResult,"MacSocket_connect: Can't complete connect on OT endpoint, OTRcvConnect() = ",theOTResult);
1033*ebfedea0SLionel Sambuc 
1034*ebfedea0SLionel Sambuc 
1035*ebfedea0SLionel Sambuc 	errCode = noErr;
1036*ebfedea0SLionel Sambuc 
1037*ebfedea0SLionel Sambuc 
1038*ebfedea0SLionel Sambuc #ifdef MACSOCKET_DEBUG
1039*ebfedea0SLionel Sambuc 	printf("MacSocket_connect: connect completed\n");
1040*ebfedea0SLionel Sambuc #endif
1041*ebfedea0SLionel Sambuc 
1042*ebfedea0SLionel Sambuc EXITPOINT:
1043*ebfedea0SLionel Sambuc 
1044*ebfedea0SLionel Sambuc 	if (theSocketStruct != nil)
1045*ebfedea0SLionel Sambuc 	{
1046*ebfedea0SLionel Sambuc 		theSocketStruct->mLastError = noErr;
1047*ebfedea0SLionel Sambuc 
1048*ebfedea0SLionel Sambuc 		CopyCStrToCStr("",theSocketStruct->mErrMessage,sizeof(theSocketStruct->mErrMessage));
1049*ebfedea0SLionel Sambuc 
1050*ebfedea0SLionel Sambuc 		if (errCode != noErr)
1051*ebfedea0SLionel Sambuc 		{
1052*ebfedea0SLionel Sambuc 			theSocketStruct->mLastError = errCode;
1053*ebfedea0SLionel Sambuc 
1054*ebfedea0SLionel Sambuc 			CopyCStrToCStr(GetErrorMessage(),theSocketStruct->mErrMessage,sizeof(theSocketStruct->mErrMessage));
1055*ebfedea0SLionel Sambuc 		}
1056*ebfedea0SLionel Sambuc 	}
1057*ebfedea0SLionel Sambuc 
1058*ebfedea0SLionel Sambuc 	errno = errCode;
1059*ebfedea0SLionel Sambuc 
1060*ebfedea0SLionel Sambuc 	return(errCode);
1061*ebfedea0SLionel Sambuc }
1062*ebfedea0SLionel Sambuc 
1063*ebfedea0SLionel Sambuc 
1064*ebfedea0SLionel Sambuc 
1065*ebfedea0SLionel Sambuc 
1066*ebfedea0SLionel Sambuc //	Close a connection
1067*ebfedea0SLionel Sambuc 
MacSocket_close(const int inSocketNum)1068*ebfedea0SLionel Sambuc OSErr MacSocket_close(const int inSocketNum)
1069*ebfedea0SLionel Sambuc {
1070*ebfedea0SLionel Sambuc OSErr			errCode = noErr;
1071*ebfedea0SLionel Sambuc SocketStruct	*theSocketStruct = nil;
1072*ebfedea0SLionel Sambuc 
1073*ebfedea0SLionel Sambuc 
1074*ebfedea0SLionel Sambuc 	if (!SocketIndexIsValid(inSocketNum))
1075*ebfedea0SLionel Sambuc 	{
1076*ebfedea0SLionel Sambuc 		SetErrorMessageAndBail("MacSocket_close: Invalid socket number specified");
1077*ebfedea0SLionel Sambuc 	}
1078*ebfedea0SLionel Sambuc 
1079*ebfedea0SLionel Sambuc 
1080*ebfedea0SLionel Sambuc 	theSocketStruct = &(sSockets[inSocketNum]);
1081*ebfedea0SLionel Sambuc 
1082*ebfedea0SLionel Sambuc 	if (theSocketStruct->mEndPointRef != kOTInvalidEndpointRef)
1083*ebfedea0SLionel Sambuc 	{
1084*ebfedea0SLionel Sambuc 	OTResult		theOTResult = noErr;
1085*ebfedea0SLionel Sambuc 
1086*ebfedea0SLionel Sambuc 		//	Try to play nice
1087*ebfedea0SLionel Sambuc 
1088*ebfedea0SLionel Sambuc 		if (theSocketStruct->mReceivedTOrdRel)
1089*ebfedea0SLionel Sambuc 		{
1090*ebfedea0SLionel Sambuc 			//	Already did an OTRcvOrderlyDisconnect() in the notifier
1091*ebfedea0SLionel Sambuc 
1092*ebfedea0SLionel Sambuc 			if (theSocketStruct->mLocalEndIsConnected)
1093*ebfedea0SLionel Sambuc 			{
1094*ebfedea0SLionel Sambuc 				theOTResult = ::OTSndOrderlyDisconnect(theSocketStruct->mEndPointRef);
1095*ebfedea0SLionel Sambuc 
1096*ebfedea0SLionel Sambuc 				theSocketStruct->mLocalEndIsConnected = false;
1097*ebfedea0SLionel Sambuc 			}
1098*ebfedea0SLionel Sambuc 		}
1099*ebfedea0SLionel Sambuc 
1100*ebfedea0SLionel Sambuc 		else if (theSocketStruct->mLocalEndIsConnected)
1101*ebfedea0SLionel Sambuc 		{
1102*ebfedea0SLionel Sambuc 			theOTResult = ::OTSndOrderlyDisconnect(theSocketStruct->mEndPointRef);
1103*ebfedea0SLionel Sambuc 
1104*ebfedea0SLionel Sambuc 			theSocketStruct->mLocalEndIsConnected = false;
1105*ebfedea0SLionel Sambuc 
1106*ebfedea0SLionel Sambuc 			//	Wait for other end to hang up too!
1107*ebfedea0SLionel Sambuc 
1108*ebfedea0SLionel Sambuc //			PrepareForAsyncOperation(theSocketStruct,T_ORDREL);
1109*ebfedea0SLionel Sambuc //
1110*ebfedea0SLionel Sambuc //			errCode = MyBusyWait(theSocketStruct,false,&theOTResult,&(theSocketStruct->mReceivedTOrdRel));
1111*ebfedea0SLionel Sambuc 		}
1112*ebfedea0SLionel Sambuc 
1113*ebfedea0SLionel Sambuc 
1114*ebfedea0SLionel Sambuc 		if (theOTResult != noErr)
1115*ebfedea0SLionel Sambuc 		{
1116*ebfedea0SLionel Sambuc 			::OTCloseProvider(theSocketStruct->mEndPointRef);
1117*ebfedea0SLionel Sambuc 		}
1118*ebfedea0SLionel Sambuc 
1119*ebfedea0SLionel Sambuc 		else
1120*ebfedea0SLionel Sambuc 		{
1121*ebfedea0SLionel Sambuc 			theOTResult = ::OTCloseProvider(theSocketStruct->mEndPointRef);
1122*ebfedea0SLionel Sambuc 		}
1123*ebfedea0SLionel Sambuc 
1124*ebfedea0SLionel Sambuc 		theSocketStruct->mEndPointRef = kOTInvalidEndpointRef;
1125*ebfedea0SLionel Sambuc 
1126*ebfedea0SLionel Sambuc 		errCode = theOTResult;
1127*ebfedea0SLionel Sambuc 	}
1128*ebfedea0SLionel Sambuc 
1129*ebfedea0SLionel Sambuc 
1130*ebfedea0SLionel Sambuc 	theSocketStruct->mIsInUse = false;
1131*ebfedea0SLionel Sambuc 
1132*ebfedea0SLionel Sambuc 
1133*ebfedea0SLionel Sambuc EXITPOINT:
1134*ebfedea0SLionel Sambuc 
1135*ebfedea0SLionel Sambuc 	if (theSocketStruct != nil)
1136*ebfedea0SLionel Sambuc 	{
1137*ebfedea0SLionel Sambuc 		theSocketStruct->mLastError = noErr;
1138*ebfedea0SLionel Sambuc 
1139*ebfedea0SLionel Sambuc 		CopyCStrToCStr("",theSocketStruct->mErrMessage,sizeof(theSocketStruct->mErrMessage));
1140*ebfedea0SLionel Sambuc 
1141*ebfedea0SLionel Sambuc 		if (errCode != noErr)
1142*ebfedea0SLionel Sambuc 		{
1143*ebfedea0SLionel Sambuc 			theSocketStruct->mLastError = errCode;
1144*ebfedea0SLionel Sambuc 
1145*ebfedea0SLionel Sambuc 			CopyCStrToCStr(GetErrorMessage(),theSocketStruct->mErrMessage,sizeof(theSocketStruct->mErrMessage));
1146*ebfedea0SLionel Sambuc 		}
1147*ebfedea0SLionel Sambuc 	}
1148*ebfedea0SLionel Sambuc 
1149*ebfedea0SLionel Sambuc 	errno = errCode;
1150*ebfedea0SLionel Sambuc 
1151*ebfedea0SLionel Sambuc 	return(errCode);
1152*ebfedea0SLionel Sambuc }
1153*ebfedea0SLionel Sambuc 
1154*ebfedea0SLionel Sambuc 
1155*ebfedea0SLionel Sambuc 
1156*ebfedea0SLionel Sambuc 
1157*ebfedea0SLionel Sambuc //	Receive some bytes
1158*ebfedea0SLionel Sambuc 
MacSocket_recv(const int inSocketNum,void * outBuff,int outBuffLength,const Boolean inBlock)1159*ebfedea0SLionel Sambuc int MacSocket_recv(const int inSocketNum,void *outBuff,int outBuffLength,const Boolean inBlock)
1160*ebfedea0SLionel Sambuc {
1161*ebfedea0SLionel Sambuc OSErr			errCode = noErr;
1162*ebfedea0SLionel Sambuc int				totalBytesRead = 0;
1163*ebfedea0SLionel Sambuc SocketStruct	*theSocketStruct = nil;
1164*ebfedea0SLionel Sambuc 
1165*ebfedea0SLionel Sambuc 
1166*ebfedea0SLionel Sambuc 	SetErrorMessageAndBailIfNil(outBuff,"MacSocket_recv: Bad parameter, outBuff = nil");
1167*ebfedea0SLionel Sambuc 
1168*ebfedea0SLionel Sambuc 	if (outBuffLength <= 0)
1169*ebfedea0SLionel Sambuc 	{
1170*ebfedea0SLionel Sambuc 		SetErrorMessageAndBail("MacSocket_recv: Bad parameter, outBuffLength <= 0");
1171*ebfedea0SLionel Sambuc 	}
1172*ebfedea0SLionel Sambuc 
1173*ebfedea0SLionel Sambuc 	if (!SocketIndexIsValid(inSocketNum))
1174*ebfedea0SLionel Sambuc 	{
1175*ebfedea0SLionel Sambuc 		SetErrorMessageAndBail("MacSocket_recv: Invalid socket number specified");
1176*ebfedea0SLionel Sambuc 	}
1177*ebfedea0SLionel Sambuc 
1178*ebfedea0SLionel Sambuc 	theSocketStruct = &(sSockets[inSocketNum]);
1179*ebfedea0SLionel Sambuc 
1180*ebfedea0SLionel Sambuc 	if (!theSocketStruct->mLocalEndIsConnected)
1181*ebfedea0SLionel Sambuc 	{
1182*ebfedea0SLionel Sambuc 		SetErrorMessageAndBail("MacSocket_recv: Socket not connected");
1183*ebfedea0SLionel Sambuc 	}
1184*ebfedea0SLionel Sambuc 
1185*ebfedea0SLionel Sambuc 	if (theSocketStruct->mReceivedTOrdRel)
1186*ebfedea0SLionel Sambuc 	{
1187*ebfedea0SLionel Sambuc 		totalBytesRead = 0;
1188*ebfedea0SLionel Sambuc 
1189*ebfedea0SLionel Sambuc 		goto EXITPOINT;
1190*ebfedea0SLionel Sambuc 	}
1191*ebfedea0SLionel Sambuc 
1192*ebfedea0SLionel Sambuc 
1193*ebfedea0SLionel Sambuc 	PrepareForAsyncOperation(theSocketStruct,0);
1194*ebfedea0SLionel Sambuc 
1195*ebfedea0SLionel Sambuc 	for (;;)
1196*ebfedea0SLionel Sambuc 	{
1197*ebfedea0SLionel Sambuc 	int			bytesRead;
1198*ebfedea0SLionel Sambuc 	OTResult	theOTResult;
1199*ebfedea0SLionel Sambuc 
1200*ebfedea0SLionel Sambuc 
1201*ebfedea0SLionel Sambuc 		theOTResult = ::OTRcv(theSocketStruct->mEndPointRef,(void *) ((unsigned long) outBuff + (unsigned long) totalBytesRead),outBuffLength - totalBytesRead,nil);
1202*ebfedea0SLionel Sambuc 
1203*ebfedea0SLionel Sambuc 		if (theOTResult >= 0)
1204*ebfedea0SLionel Sambuc 		{
1205*ebfedea0SLionel Sambuc 			bytesRead = theOTResult;
1206*ebfedea0SLionel Sambuc 
1207*ebfedea0SLionel Sambuc #ifdef MACSOCKET_DEBUG
1208*ebfedea0SLionel Sambuc 	printf("MacSocket_recv: read %d bytes in part\n",bytesRead);
1209*ebfedea0SLionel Sambuc #endif
1210*ebfedea0SLionel Sambuc 		}
1211*ebfedea0SLionel Sambuc 
1212*ebfedea0SLionel Sambuc 		else if (theOTResult == kOTNoDataErr)
1213*ebfedea0SLionel Sambuc 		{
1214*ebfedea0SLionel Sambuc 			bytesRead = 0;
1215*ebfedea0SLionel Sambuc 		}
1216*ebfedea0SLionel Sambuc 
1217*ebfedea0SLionel Sambuc 		else
1218*ebfedea0SLionel Sambuc 		{
1219*ebfedea0SLionel Sambuc 			SetErrorMessageAndLongIntAndBail("MacSocket_recv: Can't receive OT data, OTRcv() = ",theOTResult);
1220*ebfedea0SLionel Sambuc 		}
1221*ebfedea0SLionel Sambuc 
1222*ebfedea0SLionel Sambuc 
1223*ebfedea0SLionel Sambuc 		totalBytesRead += bytesRead;
1224*ebfedea0SLionel Sambuc 
1225*ebfedea0SLionel Sambuc 
1226*ebfedea0SLionel Sambuc 		if (totalBytesRead <= 0)
1227*ebfedea0SLionel Sambuc 		{
1228*ebfedea0SLionel Sambuc 			if (theSocketStruct->mReceivedTOrdRel)
1229*ebfedea0SLionel Sambuc 			{
1230*ebfedea0SLionel Sambuc 				break;
1231*ebfedea0SLionel Sambuc 			}
1232*ebfedea0SLionel Sambuc 
1233*ebfedea0SLionel Sambuc 			//	This seems pretty stupid to me now.  Maybe I'll delete this blocking garbage.
1234*ebfedea0SLionel Sambuc 
1235*ebfedea0SLionel Sambuc 			if (inBlock)
1236*ebfedea0SLionel Sambuc 			{
1237*ebfedea0SLionel Sambuc 				if (TimeoutElapsed(theSocketStruct))
1238*ebfedea0SLionel Sambuc 				{
1239*ebfedea0SLionel Sambuc 					SetErrorCodeAndMessageAndBail(kMacSocket_TimeoutErr,"MacSocket_recv: Receive operation timed-out");
1240*ebfedea0SLionel Sambuc 				}
1241*ebfedea0SLionel Sambuc 
1242*ebfedea0SLionel Sambuc 				if (theSocketStruct->mIdleWaitCallback != nil)
1243*ebfedea0SLionel Sambuc 				{
1244*ebfedea0SLionel Sambuc 					theOTResult = (*(theSocketStruct->mIdleWaitCallback))(theSocketStruct->mUserRefPtr);
1245*ebfedea0SLionel Sambuc 
1246*ebfedea0SLionel Sambuc 					SetErrorMessageAndBailIfError(theOTResult,"MacSocket_recv: User cancelled operation");
1247*ebfedea0SLionel Sambuc 				}
1248*ebfedea0SLionel Sambuc 
1249*ebfedea0SLionel Sambuc 				continue;
1250*ebfedea0SLionel Sambuc 			}
1251*ebfedea0SLionel Sambuc 		}
1252*ebfedea0SLionel Sambuc 
1253*ebfedea0SLionel Sambuc 
1254*ebfedea0SLionel Sambuc 		break;
1255*ebfedea0SLionel Sambuc 	}
1256*ebfedea0SLionel Sambuc 
1257*ebfedea0SLionel Sambuc 	errCode = noErr;
1258*ebfedea0SLionel Sambuc 
1259*ebfedea0SLionel Sambuc 
1260*ebfedea0SLionel Sambuc #ifdef MACSOCKET_DEBUG
1261*ebfedea0SLionel Sambuc 	printf("MacSocket_recv: read %d bytes in total\n",totalBytesRead);
1262*ebfedea0SLionel Sambuc #endif
1263*ebfedea0SLionel Sambuc 
1264*ebfedea0SLionel Sambuc 
1265*ebfedea0SLionel Sambuc EXITPOINT:
1266*ebfedea0SLionel Sambuc 
1267*ebfedea0SLionel Sambuc 	if (theSocketStruct != nil)
1268*ebfedea0SLionel Sambuc 	{
1269*ebfedea0SLionel Sambuc 		theSocketStruct->mLastError = noErr;
1270*ebfedea0SLionel Sambuc 
1271*ebfedea0SLionel Sambuc 		CopyCStrToCStr("",theSocketStruct->mErrMessage,sizeof(theSocketStruct->mErrMessage));
1272*ebfedea0SLionel Sambuc 
1273*ebfedea0SLionel Sambuc 		if (errCode != noErr)
1274*ebfedea0SLionel Sambuc 		{
1275*ebfedea0SLionel Sambuc 			theSocketStruct->mLastError = errCode;
1276*ebfedea0SLionel Sambuc 
1277*ebfedea0SLionel Sambuc 			CopyCStrToCStr(GetErrorMessage(),theSocketStruct->mErrMessage,sizeof(theSocketStruct->mErrMessage));
1278*ebfedea0SLionel Sambuc 		}
1279*ebfedea0SLionel Sambuc 	}
1280*ebfedea0SLionel Sambuc 
1281*ebfedea0SLionel Sambuc 	errno = errCode;
1282*ebfedea0SLionel Sambuc 
1283*ebfedea0SLionel Sambuc 	return(totalBytesRead);
1284*ebfedea0SLionel Sambuc }
1285*ebfedea0SLionel Sambuc 
1286*ebfedea0SLionel Sambuc 
1287*ebfedea0SLionel Sambuc 
1288*ebfedea0SLionel Sambuc //	Send some bytes
1289*ebfedea0SLionel Sambuc 
MacSocket_send(const int inSocketNum,const void * inBuff,int inBuffLength)1290*ebfedea0SLionel Sambuc int MacSocket_send(const int inSocketNum,const void *inBuff,int inBuffLength)
1291*ebfedea0SLionel Sambuc {
1292*ebfedea0SLionel Sambuc OSErr			errCode = noErr;
1293*ebfedea0SLionel Sambuc int				bytesSent = 0;
1294*ebfedea0SLionel Sambuc SocketStruct	*theSocketStruct = nil;
1295*ebfedea0SLionel Sambuc 
1296*ebfedea0SLionel Sambuc 
1297*ebfedea0SLionel Sambuc 	SetErrorMessageAndBailIfNil(inBuff,"MacSocket_send: Bad parameter, inBuff = nil");
1298*ebfedea0SLionel Sambuc 
1299*ebfedea0SLionel Sambuc 	if (inBuffLength <= 0)
1300*ebfedea0SLionel Sambuc 	{
1301*ebfedea0SLionel Sambuc 		SetErrorMessageAndBail("MacSocket_send: Bad parameter, inBuffLength <= 0");
1302*ebfedea0SLionel Sambuc 	}
1303*ebfedea0SLionel Sambuc 
1304*ebfedea0SLionel Sambuc 	if (!SocketIndexIsValid(inSocketNum))
1305*ebfedea0SLionel Sambuc 	{
1306*ebfedea0SLionel Sambuc 		SetErrorMessageAndBail("MacSocket_send: Invalid socket number specified");
1307*ebfedea0SLionel Sambuc 	}
1308*ebfedea0SLionel Sambuc 
1309*ebfedea0SLionel Sambuc 
1310*ebfedea0SLionel Sambuc 	theSocketStruct = &(sSockets[inSocketNum]);
1311*ebfedea0SLionel Sambuc 
1312*ebfedea0SLionel Sambuc 	if (!theSocketStruct->mLocalEndIsConnected)
1313*ebfedea0SLionel Sambuc 	{
1314*ebfedea0SLionel Sambuc 		SetErrorMessageAndBail("MacSocket_send: Socket not connected");
1315*ebfedea0SLionel Sambuc 	}
1316*ebfedea0SLionel Sambuc 
1317*ebfedea0SLionel Sambuc 
1318*ebfedea0SLionel Sambuc OTResult		theOTResult;
1319*ebfedea0SLionel Sambuc 
1320*ebfedea0SLionel Sambuc 
1321*ebfedea0SLionel Sambuc 	PrepareForAsyncOperation(theSocketStruct,0);
1322*ebfedea0SLionel Sambuc 
1323*ebfedea0SLionel Sambuc 	while (bytesSent < inBuffLength)
1324*ebfedea0SLionel Sambuc 	{
1325*ebfedea0SLionel Sambuc 		if (theSocketStruct->mIdleWaitCallback != nil)
1326*ebfedea0SLionel Sambuc 		{
1327*ebfedea0SLionel Sambuc 			theOTResult = (*(theSocketStruct->mIdleWaitCallback))(theSocketStruct->mUserRefPtr);
1328*ebfedea0SLionel Sambuc 
1329*ebfedea0SLionel Sambuc 			SetErrorMessageAndBailIfError(theOTResult,"MacSocket_send: User cancelled");
1330*ebfedea0SLionel Sambuc 		}
1331*ebfedea0SLionel Sambuc 
1332*ebfedea0SLionel Sambuc 
1333*ebfedea0SLionel Sambuc 		theOTResult = ::OTSnd(theSocketStruct->mEndPointRef,(void *) ((unsigned long) inBuff + bytesSent),inBuffLength - bytesSent,0);
1334*ebfedea0SLionel Sambuc 
1335*ebfedea0SLionel Sambuc 		if (theOTResult >= 0)
1336*ebfedea0SLionel Sambuc 		{
1337*ebfedea0SLionel Sambuc 			bytesSent += theOTResult;
1338*ebfedea0SLionel Sambuc 
1339*ebfedea0SLionel Sambuc 			theOTResult = noErr;
1340*ebfedea0SLionel Sambuc 
1341*ebfedea0SLionel Sambuc 			//	Reset timer....
1342*ebfedea0SLionel Sambuc 
1343*ebfedea0SLionel Sambuc 			PrepareForAsyncOperation(theSocketStruct,0);
1344*ebfedea0SLionel Sambuc 		}
1345*ebfedea0SLionel Sambuc 
1346*ebfedea0SLionel Sambuc 		if (theOTResult == kOTFlowErr)
1347*ebfedea0SLionel Sambuc 		{
1348*ebfedea0SLionel Sambuc 			if (TimeoutElapsed(theSocketStruct))
1349*ebfedea0SLionel Sambuc 			{
1350*ebfedea0SLionel Sambuc 				SetErrorCodeAndMessageAndBail(kMacSocket_TimeoutErr,"MacSocket_send: Send timed-out")
1351*ebfedea0SLionel Sambuc 			}
1352*ebfedea0SLionel Sambuc 
1353*ebfedea0SLionel Sambuc 			theOTResult = noErr;
1354*ebfedea0SLionel Sambuc 		}
1355*ebfedea0SLionel Sambuc 
1356*ebfedea0SLionel Sambuc 		SetErrorMessageAndLongIntAndBailIfError(theOTResult,"MacSocket_send: Can't send OT data, OTSnd() = ",theOTResult);
1357*ebfedea0SLionel Sambuc 	}
1358*ebfedea0SLionel Sambuc 
1359*ebfedea0SLionel Sambuc 
1360*ebfedea0SLionel Sambuc 	errCode = noErr;
1361*ebfedea0SLionel Sambuc 
1362*ebfedea0SLionel Sambuc #ifdef MACSOCKET_DEBUG
1363*ebfedea0SLionel Sambuc 	printf("MacSocket_send: sent %d bytes\n",bytesSent);
1364*ebfedea0SLionel Sambuc #endif
1365*ebfedea0SLionel Sambuc 
1366*ebfedea0SLionel Sambuc 
1367*ebfedea0SLionel Sambuc EXITPOINT:
1368*ebfedea0SLionel Sambuc 
1369*ebfedea0SLionel Sambuc 	if (theSocketStruct != nil)
1370*ebfedea0SLionel Sambuc 	{
1371*ebfedea0SLionel Sambuc 		theSocketStruct->mLastError = noErr;
1372*ebfedea0SLionel Sambuc 
1373*ebfedea0SLionel Sambuc 		CopyCStrToCStr("",theSocketStruct->mErrMessage,sizeof(theSocketStruct->mErrMessage));
1374*ebfedea0SLionel Sambuc 
1375*ebfedea0SLionel Sambuc 		if (errCode != noErr)
1376*ebfedea0SLionel Sambuc 		{
1377*ebfedea0SLionel Sambuc 			theSocketStruct->mLastError = errCode;
1378*ebfedea0SLionel Sambuc 
1379*ebfedea0SLionel Sambuc 			CopyCStrToCStr(GetErrorMessage(),theSocketStruct->mErrMessage,sizeof(theSocketStruct->mErrMessage));
1380*ebfedea0SLionel Sambuc 		}
1381*ebfedea0SLionel Sambuc 	}
1382*ebfedea0SLionel Sambuc 
1383*ebfedea0SLionel Sambuc 	if (errCode != noErr)
1384*ebfedea0SLionel Sambuc 	{
1385*ebfedea0SLionel Sambuc 		::SysBeep(1);
1386*ebfedea0SLionel Sambuc 	}
1387*ebfedea0SLionel Sambuc 
1388*ebfedea0SLionel Sambuc 	errno = errCode;
1389*ebfedea0SLionel Sambuc 
1390*ebfedea0SLionel Sambuc 	return(bytesSent);
1391*ebfedea0SLionel Sambuc }
1392*ebfedea0SLionel Sambuc 
1393*ebfedea0SLionel Sambuc 
1394*ebfedea0SLionel Sambuc 
1395*ebfedea0SLionel Sambuc 
1396*ebfedea0SLionel Sambuc 
NegotiateIPReuseAddrOption(EndpointRef inEndpoint,const Boolean inEnableReuseIP)1397*ebfedea0SLionel Sambuc static OSStatus NegotiateIPReuseAddrOption(EndpointRef inEndpoint,const Boolean inEnableReuseIP)
1398*ebfedea0SLionel Sambuc {
1399*ebfedea0SLionel Sambuc OSStatus	errCode;
1400*ebfedea0SLionel Sambuc UInt8		buf[kOTFourByteOptionSize];
1401*ebfedea0SLionel Sambuc TOption*	theOTOption;
1402*ebfedea0SLionel Sambuc TOptMgmt	theOTRequest;
1403*ebfedea0SLionel Sambuc TOptMgmt	theOTResult;
1404*ebfedea0SLionel Sambuc 
1405*ebfedea0SLionel Sambuc 
1406*ebfedea0SLionel Sambuc 	if (!OTIsSynchronous(inEndpoint))
1407*ebfedea0SLionel Sambuc 	{
1408*ebfedea0SLionel Sambuc 		SetErrorMessageAndBail("NegotiateIPReuseAddrOption: Open Transport endpoint is not synchronous");
1409*ebfedea0SLionel Sambuc 	}
1410*ebfedea0SLionel Sambuc 
1411*ebfedea0SLionel Sambuc 	theOTRequest.opt.buf = buf;
1412*ebfedea0SLionel Sambuc 	theOTRequest.opt.len = sizeof(buf);
1413*ebfedea0SLionel Sambuc 	theOTRequest.flags = T_NEGOTIATE;
1414*ebfedea0SLionel Sambuc 
1415*ebfedea0SLionel Sambuc 	theOTResult.opt.buf = buf;
1416*ebfedea0SLionel Sambuc 	theOTResult.opt.maxlen = kOTFourByteOptionSize;
1417*ebfedea0SLionel Sambuc 
1418*ebfedea0SLionel Sambuc 
1419*ebfedea0SLionel Sambuc 	theOTOption = (TOption *) buf;
1420*ebfedea0SLionel Sambuc 
1421*ebfedea0SLionel Sambuc 	theOTOption->level = INET_IP;
1422*ebfedea0SLionel Sambuc 	theOTOption->name = IP_REUSEADDR;
1423*ebfedea0SLionel Sambuc 	theOTOption->len = kOTFourByteOptionSize;
1424*ebfedea0SLionel Sambuc 	theOTOption->status = 0;
1425*ebfedea0SLionel Sambuc 	*((UInt32 *) (theOTOption->value)) = inEnableReuseIP;
1426*ebfedea0SLionel Sambuc 
1427*ebfedea0SLionel Sambuc 	errCode = ::OTOptionManagement(inEndpoint,&theOTRequest,&theOTResult);
1428*ebfedea0SLionel Sambuc 
1429*ebfedea0SLionel Sambuc 	if (errCode == kOTNoError)
1430*ebfedea0SLionel Sambuc 	{
1431*ebfedea0SLionel Sambuc 		if (theOTOption->status != T_SUCCESS)
1432*ebfedea0SLionel Sambuc 		{
1433*ebfedea0SLionel Sambuc 			errCode = theOTOption->status;
1434*ebfedea0SLionel Sambuc 		}
1435*ebfedea0SLionel Sambuc 
1436*ebfedea0SLionel Sambuc 		else
1437*ebfedea0SLionel Sambuc 		{
1438*ebfedea0SLionel Sambuc 			errCode = kOTNoError;
1439*ebfedea0SLionel Sambuc 		}
1440*ebfedea0SLionel Sambuc 	}
1441*ebfedea0SLionel Sambuc 
1442*ebfedea0SLionel Sambuc 
1443*ebfedea0SLionel Sambuc EXITPOINT:
1444*ebfedea0SLionel Sambuc 
1445*ebfedea0SLionel Sambuc 	errno = errCode;
1446*ebfedea0SLionel Sambuc 
1447*ebfedea0SLionel Sambuc 	return(errCode);
1448*ebfedea0SLionel Sambuc }
1449*ebfedea0SLionel Sambuc 
1450*ebfedea0SLionel Sambuc 
1451*ebfedea0SLionel Sambuc 
1452*ebfedea0SLionel Sambuc 
1453*ebfedea0SLionel Sambuc 
1454*ebfedea0SLionel Sambuc //	Some rough notes....
1455*ebfedea0SLionel Sambuc 
1456*ebfedea0SLionel Sambuc 
1457*ebfedea0SLionel Sambuc 
1458*ebfedea0SLionel Sambuc //	OTAckSends(ep);
1459*ebfedea0SLionel Sambuc //	OTAckSends(ep) // enable AckSend option
1460*ebfedea0SLionel Sambuc //	......
1461*ebfedea0SLionel Sambuc //	buf = OTAllocMem( nbytes); // Allocate nbytes of memory from OT
1462*ebfedea0SLionel Sambuc //	OTSnd(ep, buf, nbytes, 0); // send a packet
1463*ebfedea0SLionel Sambuc //	......
1464*ebfedea0SLionel Sambuc //	NotifyProc( .... void* theParam) // Notifier Proc
1465*ebfedea0SLionel Sambuc //	case T_MEMORYRELEASED: // process event
1466*ebfedea0SLionel Sambuc //	OTFreeMem( theParam); // free up memory
1467*ebfedea0SLionel Sambuc //	break;
1468*ebfedea0SLionel Sambuc 
1469*ebfedea0SLionel Sambuc 
1470*ebfedea0SLionel Sambuc 
1471*ebfedea0SLionel Sambuc /*
1472*ebfedea0SLionel Sambuc struct InetInterfaceInfo
1473*ebfedea0SLionel Sambuc {
1474*ebfedea0SLionel Sambuc 	InetHost		fAddress;
1475*ebfedea0SLionel Sambuc 	InetHost		fNetmask;
1476*ebfedea0SLionel Sambuc 	InetHost		fBroadcastAddr;
1477*ebfedea0SLionel Sambuc 	InetHost		fDefaultGatewayAddr;
1478*ebfedea0SLionel Sambuc 	InetHost		fDNSAddr;
1479*ebfedea0SLionel Sambuc 	UInt16			fVersion;
1480*ebfedea0SLionel Sambuc 	UInt16			fHWAddrLen;
1481*ebfedea0SLionel Sambuc 	UInt8*			fHWAddr;
1482*ebfedea0SLionel Sambuc 	UInt32			fIfMTU;
1483*ebfedea0SLionel Sambuc 	UInt8*			fReservedPtrs[2];
1484*ebfedea0SLionel Sambuc 	InetDomainName	fDomainName;
1485*ebfedea0SLionel Sambuc 	UInt32			fIPSecondaryCount;
1486*ebfedea0SLionel Sambuc 	UInt8			fReserved[252];
1487*ebfedea0SLionel Sambuc };
1488*ebfedea0SLionel Sambuc typedef struct InetInterfaceInfo InetInterfaceInfo;
1489*ebfedea0SLionel Sambuc 
1490*ebfedea0SLionel Sambuc 
1491*ebfedea0SLionel Sambuc 
1492*ebfedea0SLionel Sambuc ((InetAddress *) addr.buf)->fHost
1493*ebfedea0SLionel Sambuc 
1494*ebfedea0SLionel Sambuc struct TBind
1495*ebfedea0SLionel Sambuc {
1496*ebfedea0SLionel Sambuc 	TNetbuf	addr;
1497*ebfedea0SLionel Sambuc 	OTQLen	qlen;
1498*ebfedea0SLionel Sambuc };
1499*ebfedea0SLionel Sambuc 
1500*ebfedea0SLionel Sambuc typedef struct TBind	TBind;
1501*ebfedea0SLionel Sambuc 
1502*ebfedea0SLionel Sambuc struct TNetbuf
1503*ebfedea0SLionel Sambuc {
1504*ebfedea0SLionel Sambuc 	size_t	maxlen;
1505*ebfedea0SLionel Sambuc 	size_t	len;
1506*ebfedea0SLionel Sambuc 	UInt8*	buf;
1507*ebfedea0SLionel Sambuc };
1508*ebfedea0SLionel Sambuc 
1509*ebfedea0SLionel Sambuc typedef struct TNetbuf	TNetbuf;
1510*ebfedea0SLionel Sambuc 
1511*ebfedea0SLionel Sambuc 
1512*ebfedea0SLionel Sambuc 	struct InetAddress
1513*ebfedea0SLionel Sambuc {
1514*ebfedea0SLionel Sambuc 		OTAddressType	fAddressType;	// always AF_INET
1515*ebfedea0SLionel Sambuc 		InetPort		fPort;			// Port number
1516*ebfedea0SLionel Sambuc 		InetHost		fHost;			// Host address in net byte order
1517*ebfedea0SLionel Sambuc 		UInt8			fUnused[8];		// Traditional unused bytes
1518*ebfedea0SLionel Sambuc };
1519*ebfedea0SLionel Sambuc typedef struct InetAddress InetAddress;
1520*ebfedea0SLionel Sambuc */
1521*ebfedea0SLionel Sambuc 
1522*ebfedea0SLionel Sambuc 
1523*ebfedea0SLionel Sambuc 
1524*ebfedea0SLionel Sambuc /*
1525*ebfedea0SLionel Sambuc static pascal void Notifier(void* context, OTEventCode event, OTResult result, void* cookie)
1526*ebfedea0SLionel Sambuc {
1527*ebfedea0SLionel Sambuc EPInfo* epi = (EPInfo*) context;
1528*ebfedea0SLionel Sambuc 
1529*ebfedea0SLionel Sambuc 	switch (event)
1530*ebfedea0SLionel Sambuc 	{
1531*ebfedea0SLionel Sambuc 		case T_LISTEN:
1532*ebfedea0SLionel Sambuc 		{
1533*ebfedea0SLionel Sambuc 			DoListenAccept();
1534*ebfedea0SLionel Sambuc 			return;
1535*ebfedea0SLionel Sambuc 		}
1536*ebfedea0SLionel Sambuc 
1537*ebfedea0SLionel Sambuc 		case T_ACCEPTCOMPLETE:
1538*ebfedea0SLionel Sambuc 		{
1539*ebfedea0SLionel Sambuc 			if (result != kOTNoError)
1540*ebfedea0SLionel Sambuc 				DBAlert1("Notifier: T_ACCEPTCOMPLETE - result %d",result);
1541*ebfedea0SLionel Sambuc 			return;
1542*ebfedea0SLionel Sambuc 		}
1543*ebfedea0SLionel Sambuc 
1544*ebfedea0SLionel Sambuc 		case T_PASSCON:
1545*ebfedea0SLionel Sambuc 		{
1546*ebfedea0SLionel Sambuc 			if (result != kOTNoError)
1547*ebfedea0SLionel Sambuc 			{
1548*ebfedea0SLionel Sambuc 				DBAlert1("Notifier: T_PASSCON result %d", result);
1549*ebfedea0SLionel Sambuc 				return;
1550*ebfedea0SLionel Sambuc 			}
1551*ebfedea0SLionel Sambuc 
1552*ebfedea0SLionel Sambuc 			OTAtomicAdd32(1, &gCntrConnections);
1553*ebfedea0SLionel Sambuc 			OTAtomicAdd32(1, &gCntrTotalConnections);
1554*ebfedea0SLionel Sambuc 			OTAtomicAdd32(1, &gCntrIntervalConnects);
1555*ebfedea0SLionel Sambuc 
1556*ebfedea0SLionel Sambuc 			if ( OTAtomicSetBit(&epi->stateFlags, kPassconBit) != 0 )
1557*ebfedea0SLionel Sambuc 			{
1558*ebfedea0SLionel Sambuc 				ReadData(epi);
1559*ebfedea0SLionel Sambuc 			}
1560*ebfedea0SLionel Sambuc 
1561*ebfedea0SLionel Sambuc 			return;
1562*ebfedea0SLionel Sambuc 		}
1563*ebfedea0SLionel Sambuc 
1564*ebfedea0SLionel Sambuc 		case T_DATA:
1565*ebfedea0SLionel Sambuc 		{
1566*ebfedea0SLionel Sambuc 			if ( OTAtomicSetBit(&epi->stateFlags, kPassconBit) != 0 )
1567*ebfedea0SLionel Sambuc 			{
1568*ebfedea0SLionel Sambuc 				ReadData(epi);
1569*ebfedea0SLionel Sambuc 			}
1570*ebfedea0SLionel Sambuc 
1571*ebfedea0SLionel Sambuc 			return;
1572*ebfedea0SLionel Sambuc 		}
1573*ebfedea0SLionel Sambuc 
1574*ebfedea0SLionel Sambuc 		case T_GODATA:
1575*ebfedea0SLionel Sambuc 		{
1576*ebfedea0SLionel Sambuc 			SendData(epi);
1577*ebfedea0SLionel Sambuc 			return;
1578*ebfedea0SLionel Sambuc 		}
1579*ebfedea0SLionel Sambuc 
1580*ebfedea0SLionel Sambuc 		case T_DISCONNECT:
1581*ebfedea0SLionel Sambuc 		{
1582*ebfedea0SLionel Sambuc 			DoRcvDisconnect(epi);
1583*ebfedea0SLionel Sambuc 			return;
1584*ebfedea0SLionel Sambuc 		}
1585*ebfedea0SLionel Sambuc 
1586*ebfedea0SLionel Sambuc 		case T_DISCONNECTCOMPLETE:
1587*ebfedea0SLionel Sambuc 		{
1588*ebfedea0SLionel Sambuc 			if (result != kOTNoError)
1589*ebfedea0SLionel Sambuc 				DBAlert1("Notifier: T_DISCONNECT_COMPLETE result %d",result);
1590*ebfedea0SLionel Sambuc 
1591*ebfedea0SLionel Sambuc 			return;
1592*ebfedea0SLionel Sambuc 		}
1593*ebfedea0SLionel Sambuc 
1594*ebfedea0SLionel Sambuc 		case T_MEMORYRELEASED:
1595*ebfedea0SLionel Sambuc 		{
1596*ebfedea0SLionel Sambuc 			OTAtomicAdd32(-1, &epi->outstandingSends);
1597*ebfedea0SLionel Sambuc 			return;
1598*ebfedea0SLionel Sambuc 		}
1599*ebfedea0SLionel Sambuc 
1600*ebfedea0SLionel Sambuc 		default:
1601*ebfedea0SLionel Sambuc 		{
1602*ebfedea0SLionel Sambuc 			DBAlert1("Notifier: unknown event <%x>", event);
1603*ebfedea0SLionel Sambuc 			return;
1604*ebfedea0SLionel Sambuc 		}
1605*ebfedea0SLionel Sambuc 	}
1606*ebfedea0SLionel Sambuc }
1607*ebfedea0SLionel Sambuc */
1608