changes by Barry, e.g. font lock & email addresses
[python/dscho.git] / Mac / Unsupported / mactcp / tcpglue.c
blob79042b485d97dce34d54d2b34f1549f26361325d
1 /*
2 * Glue routines for mactcp module.
3 * Jack Jansen, CWI, 1994.
5 * Adapted from mactcp socket library, which was in turn
6 * adapted from ncsa telnet code.
8 * Original authors: Tom Milligan, Charlie Reiman
9 */
11 # include <Memory.h>
12 # include <Files.h>
13 # include <Errors.h>
15 #include "tcpglue.h"
16 #include <Devices.h>
18 static short driver = 0;
20 #ifndef __powerc
22 * Hack fix for MacTCP 1.0.X bug
24 * This hack doesn't work on the PPC. But then, people with new machines
25 * shouldn't run ancient buggy software. -- Jack.
28 pascal char *ReturnA5(void) = {0x2E8D};
29 #endif /* !__powerc */
31 OSErr xOpenDriver()
33 if (driver == 0)
35 ParamBlockRec pb;
36 OSErr io;
38 pb.ioParam.ioCompletion = 0L;
39 pb.ioParam.ioNamePtr = "\p.IPP";
40 pb.ioParam.ioPermssn = fsCurPerm;
41 io = PBOpen(&pb,false);
42 if (io != noErr)
43 return(io);
44 driver = pb.ioParam.ioRefNum;
46 return noErr;
50 * create a TCP stream
52 OSErr xTCPCreate(buflen,notify,udp, pb)
53 int buflen;
54 TCPNotifyUPP notify;
55 void *udp;
56 TCPiopb *pb;
58 pb->ioCRefNum = driver;
59 pb->csCode = TCPCreate;
60 pb->csParam.create.rcvBuff = (char *)NewPtr(buflen);
61 pb->csParam.create.rcvBuffLen = buflen;
62 pb->csParam.create.notifyProc = notify;
63 pb->csParam.create.userDataPtr = udp;
64 return (xPBControlSync(pb));
69 * start listening for a TCP connection
71 OSErr xTCPPassiveOpen(TCPiopb *pb, short port, TCPIOCompletionUPP completion,
72 void *udp)
74 if (driver == 0)
75 return(invalidStreamPtr);
77 pb->ioCRefNum = driver;
78 pb->csCode = TCPPassiveOpen;
79 pb->csParam.open.validityFlags = timeoutValue | timeoutAction;
80 pb->csParam.open.ulpTimeoutValue = 255 /* seconds */;
81 pb->csParam.open.ulpTimeoutAction = 0 /* 1:abort 0:report */;
82 pb->csParam.open.commandTimeoutValue = 0 /* infinity */;
83 pb->csParam.open.remoteHost = 0;
84 pb->csParam.open.remotePort = 0;
85 pb->csParam.open.localHost = 0;
86 pb->csParam.open.localPort = port;
87 pb->csParam.open.dontFrag = 0;
88 pb->csParam.open.timeToLive = 0;
89 pb->csParam.open.security = 0;
90 pb->csParam.open.optionCnt = 0;
91 pb->csParam.open.userDataPtr = udp;
92 return (xPBControl(pb,completion));
96 * connect to a remote TCP
98 OSErr xTCPActiveOpen(TCPiopb *pb, short port, long rhost, short rport,
99 TCPIOCompletionUPP completion)
101 if (driver == 0)
102 return(invalidStreamPtr);
104 pb->ioCRefNum = driver;
105 pb->csCode = TCPActiveOpen;
106 pb->csParam.open.validityFlags = timeoutValue | timeoutAction;
107 pb->csParam.open.ulpTimeoutValue = 60 /* seconds */;
108 pb->csParam.open.ulpTimeoutAction = 1 /* 1:abort 0:report */;
109 pb->csParam.open.commandTimeoutValue = 0;
110 pb->csParam.open.remoteHost = rhost;
111 pb->csParam.open.remotePort = rport;
112 pb->csParam.open.localHost = 0;
113 pb->csParam.open.localPort = port;
114 pb->csParam.open.dontFrag = 0;
115 pb->csParam.open.timeToLive = 0;
116 pb->csParam.open.security = 0;
117 pb->csParam.open.optionCnt = 0;
118 return (xPBControl(pb,completion));
121 OSErr xTCPNoCopyRcv(pb,rds,rdslen,timeout,completion)
122 TCPiopb *pb;
123 rdsEntry *rds;
124 int rdslen;
125 int timeout;
126 TCPIOCompletionUPP completion;
129 if (driver == 0)
130 return(invalidStreamPtr);
132 pb->ioCRefNum = driver;
133 pb->csCode = TCPNoCopyRcv;
134 pb->csParam.receive.commandTimeoutValue = timeout; /* seconds, 0 = blocking */
135 pb->csParam.receive.rdsPtr = (Ptr)rds;
136 pb->csParam.receive.rdsLength = rdslen;
137 return (xPBControl(pb,completion));
140 OSErr xTCPBufReturn(TCPiopb *pb,rdsEntry *rds,TCPIOCompletionUPP completion)
142 pb->ioCRefNum = driver;
143 pb->csCode = TCPRcvBfrReturn;
144 pb->csParam.receive.rdsPtr = (Ptr)rds;
146 return (xPBControl(pb,completion));
150 * send data
152 OSErr xTCPSend(TCPiopb *pb, wdsEntry *wds, Boolean push, Boolean urgent, TCPIOCompletionUPP completion)
154 if (driver == 0)
155 return invalidStreamPtr;
157 pb->ioCRefNum = driver;
158 pb->csCode = TCPSend;
159 pb->csParam.send.validityFlags = timeoutValue | timeoutAction;
160 pb->csParam.send.ulpTimeoutValue = 60 /* seconds */;
161 pb->csParam.send.ulpTimeoutAction = 0 /* 0:abort 1:report */;
162 pb->csParam.send.pushFlag = push;
163 pb->csParam.send.urgentFlag = urgent;
164 pb->csParam.send.wdsPtr = (Ptr)wds;
165 return (xPBControl(pb,completion));
170 * close a connection
172 OSErr xTCPClose(TCPiopb *pb,TCPIOCompletionUPP completion)
174 if (driver == 0)
175 return(invalidStreamPtr);
177 pb->ioCRefNum = driver;
178 pb->csCode = TCPClose;
179 pb->csParam.close.validityFlags = timeoutValue | timeoutAction;
180 pb->csParam.close.ulpTimeoutValue = 60 /* seconds */;
181 pb->csParam.close.ulpTimeoutAction = 1 /* 1:abort 0:report */;
182 return (xPBControl(pb,completion));
186 * abort a connection
188 OSErr xTCPAbort(TCPiopb *pb)
190 if (driver == 0)
191 return(invalidStreamPtr);
193 pb->ioCRefNum = driver;
194 pb->csCode = TCPAbort;
195 return (xPBControlSync(pb));
199 * close down a TCP stream (aborting a connection, if necessary)
201 OSErr xTCPRelease(pb)
202 TCPiopb *pb;
204 OSErr io;
206 if (driver == 0)
207 return(invalidStreamPtr);
209 pb->ioCRefNum = driver;
210 pb->csCode = TCPRelease;
211 io = xPBControlSync(pb);
212 if (io == noErr)
213 DisposPtr(pb->csParam.create.rcvBuff); /* there is no release pb */
214 return(io);
217 #if 0
220 xTCPBytesUnread(sp)
221 SocketPtr sp;
223 TCPiopb *pb;
224 OSErr io;
226 if (!(pb = sock_fetch_pb(sp)))
227 return -1; /* panic */
229 if (driver == 0)
230 return(-1);
232 pb->ioCRefNum = driver;
233 pb->csCode = TCPStatus;
234 io = xPBControlSync(pb);
235 if (io != noErr)
236 return(-1);
237 return(pb->csParam.status.amtUnreadData);
241 xTCPBytesWriteable(sp)
242 SocketPtr sp;
244 TCPiopb *pb;
245 OSErr io;
246 long amount;
248 if (!(pb = sock_fetch_pb(sp)))
249 return -1; /* panic */
251 if (driver == 0)
252 return(-1);
254 pb->ioCRefNum = driver;
255 pb->csCode = TCPStatus;
256 io = xPBControlSync(pb);
257 if (io != noErr)
258 return(-1);
259 amount = pb->csParam.status.sendWindow-pb->csParam.status.amtUnackedData;
260 if (amount < 0)
261 amount = 0;
262 return amount;
265 int xTCPWriteBytesLeft(SocketPtr sp)
267 TCPiopb *pb;
268 OSErr io;
270 if (!(pb = sock_fetch_pb(sp)))
271 return -1; /* panic */
273 if (driver == 0)
274 return(-1);
276 pb->ioCRefNum = driver;
277 pb->csCode = TCPStatus;
278 io = xPBControlSync(pb);
279 if (io != noErr)
280 return(-1);
281 return (pb->csParam.status.amtUnackedData);
283 #endif
285 OSErr xTCPStatus(TCPiopb *pb, TCPStatusPB **spb)
287 OSErr io;
289 if (driver == 0)
290 return(-1);
292 pb->ioCRefNum = driver;
293 pb->csCode = TCPStatus;
294 io = xPBControlSync(pb);
295 if (io == noErr)
296 *spb = &pb->csParam.status;
297 return(io);
302 * create a UDP stream, hook it to a socket.
304 OSErr xUDPCreate(UDPiopb *pb,int buflen,ip_port *port, UDPNotifyUPP asr, void *udp)
306 OSErr io;
308 pb->ioCRefNum = driver;
309 pb->csCode = UDPCreate;
310 pb->csParam.create.rcvBuff = (char *)NewPtr(buflen);
311 pb->csParam.create.rcvBuffLen = buflen;
312 pb->csParam.create.notifyProc = asr;
313 pb->csParam.create.userDataPtr = udp;
314 pb->csParam.create.localPort = *port;
315 if ( (io = xPBControlSync( (TCPiopb *)pb ) ) != noErr)
316 return io;
318 *port = pb->csParam.create.localPort;
319 return noErr;
323 * ask for incoming data
325 OSErr xUDPRead(UDPiopb *pb, int timeout, UDPIOCompletionUPP completion)
328 if (driver == 0)
329 return(invalidStreamPtr);
331 pb->ioCRefNum = driver;
332 pb->csCode = UDPRead;
333 pb->csParam.receive.timeOut = timeout;
334 pb->csParam.receive.secondTimeStamp = 0/* must be zero */;
335 return (xPBControl ( (TCPiopb *)pb, (TCPIOCompletionUPP)completion ));
338 OSErr xUDPBfrReturn(UDPiopb *pb, char *buff)
341 if (driver == 0)
342 return(invalidStreamPtr);
344 pb->ioCRefNum = driver;
345 pb->csCode = UDPBfrReturn;
346 pb->csParam.receive.rcvBuff = buff;
347 return ( xPBControl( (TCPiopb *)pb,(TCPIOCompletionUPP)-1 ) );
351 * send data
353 OSErr xUDPWrite(UDPiopb *pb,ip_addr host,ip_port port,miniwds *wds,
354 UDPIOCompletionUPP completion)
357 if (driver == 0)
358 return(invalidStreamPtr);
360 pb->ioCRefNum = driver;
361 pb->csCode = UDPWrite;
362 pb->csParam.send.remoteHost = host;
363 pb->csParam.send.remotePort = port;
364 pb->csParam.send.wdsPtr = (Ptr)wds;
365 pb->csParam.send.checkSum = true;
366 pb->csParam.send.sendLength = 0/* must be zero */;
367 return (xPBControl( (TCPiopb *)pb, (TCPIOCompletionUPP)completion));
371 * close down a UDP stream (aborting a read, if necessary)
373 OSErr xUDPRelease(UDPiopb *pb) {
374 OSErr io;
376 if (driver == 0)
377 return(invalidStreamPtr);
379 pb->ioCRefNum = driver;
380 pb->csCode = UDPRelease;
381 io = xPBControlSync( (TCPiopb *)pb );
382 if (io == noErr) {
383 DisposPtr(pb->csParam.create.rcvBuff);
385 return(io);
388 ip_addr xIPAddr(void)
390 struct GetAddrParamBlock pbr;
391 OSErr io;
393 pbr.ioCRefNum = driver;
394 pbr.csCode = ipctlGetAddr;
395 io = xPBControlSync( (TCPiopb *)&pbr );
396 if (io != noErr)
397 return(0);
398 return(pbr.ourAddress);
401 long xNetMask()
403 struct GetAddrParamBlock pbr;
404 OSErr io;
406 pbr.ioCRefNum = driver;
407 pbr.csCode = ipctlGetAddr;
408 io = xPBControlSync( (TCPiopb *)&pbr);
409 if (io != noErr)
410 return(0);
411 return(pbr.ourNetMask);
414 unsigned short xMaxMTU()
416 struct UDPiopb pbr;
417 OSErr io;
419 pbr.ioCRefNum = driver;
420 pbr.csCode = UDPMaxMTUSize;
421 pbr.csParam.mtu.remoteHost = xIPAddr();
422 io = xPBControlSync( (TCPiopb *)&pbr );
423 if (io != noErr)
424 return(0);
425 return(pbr.csParam.mtu.mtuSize);
428 OSErr xPBControlSync(TCPiopb *pb)
430 (pb)->ioCompletion = 0L;
431 return PBControl((ParmBlkPtr)(pb),false);
434 #pragma segment SOCK_RESIDENT
436 OSErr xTCPRcv(pb,buf,buflen,timeout,completion)
437 TCPiopb *pb;
438 Ptr buf;
439 int buflen;
440 int timeout;
441 TCPIOCompletionUPP completion;
444 if (driver == 0)
445 return(invalidStreamPtr);
447 pb->ioCRefNum = driver;
448 pb->csCode = TCPRcv;
449 pb->csParam.receive.commandTimeoutValue = timeout; /* seconds, 0 = blocking */
450 pb->csParam.receive.rcvBuff = buf;
451 pb->csParam.receive.rcvBuffLen = buflen;
452 return (xPBControl(pb,completion));
455 OSErr xPBControl(TCPiopb *pb,TCPIOCompletionUPP completion)
457 #ifndef __MWERKS__
458 pb->ioNamePtr = ReturnA5();
459 #endif
461 if (completion == 0L)
463 (pb)->ioCompletion = 0L;
464 return(PBControl((ParmBlkPtr)(pb),false)); /* sync */
466 else if (completion == (TCPIOCompletionUPP)-1L)
468 (pb)->ioCompletion = 0L;
469 return(PBControl((ParmBlkPtr)(pb),true)); /* async */
471 else
473 (pb)->ioCompletion = completion;
474 return(PBControl((ParmBlkPtr)(pb),true)); /* async */