summaryrefslogtreecommitdiffstats
path: root/Mac/Unsupported/mactcp/mactcpmodule.c
diff options
context:
space:
mode:
authorJack Jansen <jack.jansen@cwi.nl>1994-12-14 13:36:34 (GMT)
committerJack Jansen <jack.jansen@cwi.nl>1994-12-14 13:36:34 (GMT)
commitedf585579c637fc70ff80fc33d9bc4251313ce99 (patch)
tree7aa642d5ed115a21285b68f75d4fb1353addd0c5 /Mac/Unsupported/mactcp/mactcpmodule.c
parent114ca5c170d8d53d3e62e52a4a0bc912d5dad60f (diff)
downloadcpython-edf585579c637fc70ff80fc33d9bc4251313ce99.zip
cpython-edf585579c637fc70ff80fc33d9bc4251313ce99.tar.gz
cpython-edf585579c637fc70ff80fc33d9bc4251313ce99.tar.bz2
Interface to MacTCP and the MacTCP Domain Name Resolver
Diffstat (limited to 'Mac/Unsupported/mactcp/mactcpmodule.c')
-rw-r--r--Mac/Unsupported/mactcp/mactcpmodule.c908
1 files changed, 908 insertions, 0 deletions
diff --git a/Mac/Unsupported/mactcp/mactcpmodule.c b/Mac/Unsupported/mactcp/mactcpmodule.c
new file mode 100644
index 0000000..0ba05ec
--- /dev/null
+++ b/Mac/Unsupported/mactcp/mactcpmodule.c
@@ -0,0 +1,908 @@
+/***********************************************************
+Copyright 1991, 1992, 1993, 1994 by Stichting Mathematisch Centrum,
+Amsterdam, The Netherlands.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the names of Stichting Mathematisch
+Centrum or CWI not be used in advertising or publicity pertaining to
+distribution of the software without specific, written prior permission.
+
+STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
+THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
+FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+******************************************************************/
+
+#include "allobjects.h"
+#include "modsupport.h" /* For getargs() etc. */
+
+#include "macglue.h"
+#include "tcpglue.h"
+
+#include <Desk.h>
+
+static object *ErrorObject;
+
+/* ----------------------------------------------------- */
+/* Declarations for objects of type MacTCP connection status */
+
+typedef struct {
+ OB_HEAD
+ TCPStatusPB status;
+} tcpcsobject;
+
+staticforward typeobject Tcpcstype;
+
+#define is_tcpcsobject(v) ((v)->ob_type == &Tcpcstype)
+
+/* ---------------------------------------------------------------- */
+/* Declarations for objects of type MacTCP global status */
+
+#ifdef TCP_GS
+typedef struct {
+ OB_HEAD
+ TCPParam *ptr;
+} tcpgsobject;
+
+staticforward typeobject Tcpgstype;
+
+#define is_tcpgsobject(v) ((v)->ob_type == &Tcpgstype)
+#endif /* TCP_GS */
+
+/* ---------------------------------------------------------------- */
+/* Declarations for objects of type MacTCP TCP stream */
+
+typedef struct {
+ OB_HEAD
+ TCPiopb iop;
+ object *asr; /* Optional async notification routine */
+ int asr_ec; /* error code parameter to asr */
+ int asr_reason; /* detail for some errors */
+ int async_busy; /* True when completion routine pending */
+ int async_err; /* the error for the async call */
+} tcpsobject;
+
+staticforward typeobject Tcpstype;
+
+#define is_tcpsobject(v) ((v)->ob_type == &Tcpstype)
+
+/* ---------------------------------------------------------------- */
+/* Declarations for objects of type MacTCP UDP stream */
+
+typedef struct {
+ OB_HEAD
+ UDPiopb iop;
+ object *asr;
+ int asr_ec; /* error code parameter to asr */
+ ip_port port;
+} udpsobject;
+
+staticforward typeobject Udpstype;
+
+#define is_udpsobject(v) ((v)->ob_type == &Udpstype)
+
+/* ---------------------------------------------------------------- */
+
+static tcpcsobject *
+newtcpcsobject(ptr)
+ TCPStatusPB *ptr;
+{
+ tcpcsobject *self;
+
+ self = NEWOBJ(tcpcsobject, &Tcpcstype);
+ if (self == NULL)
+ return NULL;
+ self->status = *ptr;
+ return self;
+}
+
+static void
+tcpcs_dealloc(self)
+ tcpcsobject *self;
+{
+ DEL(self);
+}
+/* Code to access structure members by accessing attributes */
+
+#include "structmember.h"
+
+#define OFF(x) offsetof(TCPStatusPB, x)
+
+static struct memberlist tcpcs_memberlist[] = {
+ {"remoteHost", T_ULONG, OFF(remoteHost), RO},
+ {"remotePort", T_USHORT, OFF(remotePort), RO},
+ {"localHost", T_UINT, OFF(localHost), RO},
+ {"localPort", T_USHORT, OFF(localPort), RO},
+ {"tosFlags", T_BYTE, OFF(tosFlags), RO},
+#if 0 /* Bug in header file: cannot access precedence */
+ {"precedence" T_BYTE, OFF(precedence), RO},
+#endif
+ {"connectionState", T_BYTE, OFF(connectionState), RO},
+ {"sendWindow", T_USHORT, OFF(sendWindow), RO},
+ {"rcvWindow", T_USHORT, OFF(rcvWindow), RO},
+ {"amtUnackedData", T_USHORT, OFF(amtUnackedData), RO},
+ {"amtUnreadData", T_USHORT, OFF(amtUnreadData), RO},
+ {"sendUnacked", T_UINT, OFF(sendUnacked), RO},
+ {"sendNext", T_UINT, OFF(sendNext), RO},
+ {"congestionWindow", T_UINT, OFF(congestionWindow), RO},
+ {"rcvNext", T_UINT, OFF(rcvNext), RO},
+ {"srtt", T_UINT, OFF(srtt), RO},
+ {"lastRTT", T_UINT, OFF(lastRTT), RO},
+ {"sendMaxSegSize", T_UINT, OFF(sendMaxSegSize), RO},
+ {NULL} /* Sentinel */
+};
+
+static object *
+tcpcs_getattr(self, name)
+ tcpcsobject *self;
+ char *name;
+{
+ object *rv;
+
+ return getmember((char *)&self->status, tcpcs_memberlist, name);
+}
+
+
+static typeobject Tcpcstype = {
+ OB_HEAD_INIT(&Typetype)
+ 0, /*ob_size*/
+ "MacTCP connection status", /*tp_name*/
+ sizeof(tcpcsobject), /*tp_basicsize*/
+ 0, /*tp_itemsize*/
+ /* methods */
+ (destructor)tcpcs_dealloc, /*tp_dealloc*/
+ (printfunc)0, /*tp_print*/
+ (getattrfunc)tcpcs_getattr, /*tp_getattr*/
+ (setattrfunc)0, /*tp_setattr*/
+ (cmpfunc)0, /*tp_compare*/
+ (reprfunc)0, /*tp_repr*/
+ 0, /*tp_as_number*/
+ 0, /*tp_as_sequence*/
+ 0, /*tp_as_mapping*/
+ (hashfunc)0, /*tp_hash*/
+};
+
+/* End of code for MacTCP connection status objects */
+/* -------------------------------------------------------- */
+
+#ifdef TCP_GS
+static tcpgsobject *
+newtcpgsobject(ptr)
+ TCPParam *ptr;
+{
+ tcpgsobject *self;
+
+ self = NEWOBJ(tcpgsobject, &Tcpgstype);
+ if (self == NULL)
+ return NULL;
+ self->ptr = ptr;
+ return self;
+}
+
+static void
+tcpgs_dealloc(self)
+ tcpgsobject *self;
+{
+ DEL(self);
+}
+/* Code to access structure members by accessing attributes */
+#undef OFF
+#define OFF(x) offsetof(TCPParam, x)
+
+static struct memberlist tcpgs_memberlist[] = {
+ {"RtoA", T_UINT, OFF(tcpRtoA), RO},
+ {"RtoMin", T_UINT, OFF(tcpRtoMin), RO},
+ {"RtoMax", T_UINT, OFF(tcpRtoMax), RO},
+ {"MaxSegSize", T_UINT, OFF(tcpMaxSegSize), RO},
+ {"MaxConn", T_UINT, OFF(tcpMaxConn), RO},
+ {"MaxWindow", T_UINT, OFF(tcpMaxWindow), RO},
+ {NULL} /* Sentinel */
+};
+
+static object *
+tcpgs_getattr(self, name)
+ tcpgsobject *self;
+ char *name;
+{
+ object *rv;
+
+ return getmember((char *)self->ptr, tcpgs_memberlist, name);
+}
+
+static typeobject Tcpgstype = {
+ OB_HEAD_INIT(&Typetype)
+ 0, /*ob_size*/
+ "MacTCP global status", /*tp_name*/
+ sizeof(tcpgsobject), /*tp_basicsize*/
+ 0, /*tp_itemsize*/
+ /* methods */
+ (destructor)tcpgs_dealloc, /*tp_dealloc*/
+ (printfunc)0, /*tp_print*/
+ (getattrfunc)tcpgs_getattr, /*tp_getattr*/
+ (setattrfunc)0, /*tp_setattr*/
+ (cmpfunc)0, /*tp_compare*/
+ (reprfunc)0, /*tp_repr*/
+ 0, /*tp_as_number*/
+ 0, /*tp_as_sequence*/
+ 0, /*tp_as_mapping*/
+ (hashfunc)0, /*tp_hash*/
+};
+#endif /* TCP_GS */
+
+/* End of code for MacTCP global status objects */
+/* -------------------------------------------------------- */
+
+static int
+tcps_asr_safe(arg)
+ void *arg;
+{
+ tcpsobject *self = (tcpsobject *)arg;
+ object *args, *rv;
+
+ if ( self->asr == None )
+ return;
+ args = mkvalue("(ii)", self->asr_ec, self->asr_reason);
+ rv = call_object(self->asr, args);
+ DECREF(args);
+ if ( rv ) {
+ DECREF(rv);
+ return 0;
+ }
+ return -1;
+}
+
+static pascal void
+tcps_asr(str, ec, self, reason, icmp)
+ StreamPtr str;
+ unsigned short ec;
+ tcpsobject *self;
+ unsigned short reason;
+ struct ICMPReport icmp;
+{
+ if ( self->asr == None )
+ return;
+ self->asr_ec = ec;
+ self->asr_reason = reason;
+ Py_AddPendingCall(tcps_asr_safe, (void *)self);
+}
+
+static void
+tcps_opendone(pb)
+ TCPiopb *pb;
+{
+ tcpsobject *self = (tcpsobject *)pb->csParam.open.userDataPtr;
+
+ if ( pb != &self->iop || !self->async_busy ) {
+ /* Oops... problems */
+ printf("tcps_opendone: unexpected call\n");
+ return;
+ }
+ self->async_busy = 0;
+ self->async_err = pb->ioResult;
+ /* Extension of mactcp semantics: also call asr on open complete */
+ if ( self->asr == None )
+ return;
+ self->asr_ec = lastEvent-1;
+ self->asr_reason = 0;
+ Py_AddPendingCall(tcps_asr_safe, (void *)self);
+}
+
+static object *
+tcps_isdone(self, args)
+ tcpsobject *self;
+ object *args;
+{
+ if (!newgetargs(args, ""))
+ return NULL;
+ return newintobject(!self->async_busy);
+}
+
+static object *
+tcps_wait(self, args)
+ tcpsobject *self;
+ object *args;
+{
+ if (!newgetargs(args, ""))
+ return NULL;
+ while ( self->async_busy ) {
+ if ( !PyMac_Idle() ) {
+ INCREF(None);
+ return None;
+ }
+ }
+ if ( self->async_err ) {
+ PyErr_Mac(ErrorObject, self->async_err);
+ self->async_err = 0;
+ return NULL;
+ }
+ INCREF(None);
+ return None;
+}
+
+
+static object *
+tcps_PassiveOpen(self, args)
+ tcpsobject *self;
+ object *args;
+{
+ short port;
+ OSErr err;
+
+ if (!newgetargs(args, "h", &port))
+ return NULL;
+ self->async_busy = 1;
+ self->async_err = 0;
+ err = xTCPPassiveOpen(&self->iop, port, (TCPIOCompletionProc)tcps_opendone,
+ (void *)self);
+ if ( err ) {
+ self->async_busy = 0;
+ PyErr_Mac(ErrorObject, err);
+ return NULL;
+ }
+ INCREF(None);
+ return None;
+}
+
+static object *
+tcps_ActiveOpen(self, args)
+ tcpsobject *self;
+ object *args;
+{
+ short lport, rport;
+ long rhost;
+ OSErr err;
+
+ if (!newgetargs(args, "hlh", &lport, &rhost, &rport))
+ return NULL;
+ err = xTCPActiveOpen(&self->iop, lport, rhost, rport, (TCPIOCompletionProc)0);
+ if ( err ) {
+ PyErr_Mac(ErrorObject, err);
+ return NULL;
+ }
+ INCREF(None);
+ return None;
+}
+
+static object *
+tcps_Send(self, args)
+ tcpsobject *self;
+ object *args;
+{
+ char *buf;
+ int bufsize;
+ int push = 0, urgent = 0;
+ OSErr err;
+ miniwds wds;
+
+ if (!newgetargs(args, "s#|ii", &buf, &bufsize, &push, &urgent))
+ return NULL;
+ wds.length = bufsize;
+ wds.ptr = buf;
+ wds.terminus = 0;
+ err = xTCPSend(&self->iop, (wdsEntry *)&wds, (Boolean)push, (Boolean)urgent,
+ (TCPIOCompletionProc)0);
+ if ( err ) {
+ PyErr_Mac(ErrorObject, err);
+ return NULL;
+ }
+ INCREF(None);
+ return None;
+}
+
+static object *
+tcps_Rcv(self, args)
+ tcpsobject *self;
+ object *args;
+{
+ int length;
+ int timeout;
+ rdsEntry rds[2];
+ OSErr err;
+ object *rv;
+ int urgent, mark;
+
+ if (!newgetargs(args, "i", &timeout))
+ return NULL;
+ memset((char *)&rds, 0, sizeof(rds));
+ err = xTCPNoCopyRcv(&self->iop, rds, 1, timeout, (TCPIOCompletionProc)0);
+ if ( err ) {
+ PyErr_Mac(ErrorObject, err);
+ return NULL;
+ }
+ urgent = self->iop.csParam.receive.urgentFlag;
+ mark = self->iop.csParam.receive.markFlag;
+ rv = newsizedstringobject((char *)rds[0].ptr, rds[0].length);
+ err = xTCPBufReturn(&self->iop, rds, (TCPIOCompletionProc)0);
+ if ( err ) {
+ /* Should not happen */printf("mactcp module: BufReturn failed?\n");
+ PyErr_Mac(ErrorObject, err);
+ DECREF(rv);
+ return NULL;
+ }
+ return mkvalue("(Oii)", rv, urgent, mark);
+}
+
+static object *
+tcps_Close(self, args)
+ tcpsobject *self;
+ object *args;
+{
+ OSErr err;
+
+ if (!newgetargs(args, ""))
+ return NULL;
+ err = xTCPClose(&self->iop, (TCPIOCompletionProc)0);
+ if ( err ) {
+ PyErr_Mac(ErrorObject, err);
+ return NULL;
+ }
+ INCREF(None);
+ return None;
+}
+
+static object *
+tcps_Abort(self, args)
+ tcpsobject *self;
+ object *args;
+{
+ OSErr err;
+
+ if (!newgetargs(args, ""))
+ return NULL;
+ err = xTCPAbort(&self->iop);
+ if ( err ) {
+ PyErr_Mac(ErrorObject, err);
+ return NULL;
+ }
+ INCREF(None);
+ return None;
+}
+
+static object *
+tcps_Status(self, args)
+ tcpsobject *self;
+ object *args;
+{
+ OSErr err;
+ TCPStatusPB *pb;
+
+ if (!newgetargs(args, ""))
+ return NULL;
+ err = xTCPStatus(&self->iop, &pb);
+ if ( err ) {
+ PyErr_Mac(ErrorObject, err);
+ return NULL;
+ }
+ return (object *)newtcpcsobject(pb);
+}
+
+static struct methodlist tcps_methods[] = {
+ {"isdone", (method)tcps_isdone, 1},
+ {"wait", (method)tcps_wait, 1},
+ {"PassiveOpen", (method)tcps_PassiveOpen, 1},
+ {"ActiveOpen", (method)tcps_ActiveOpen, 1},
+ {"Send", (method)tcps_Send, 1},
+ {"Rcv", (method)tcps_Rcv, 1},
+ {"Close", (method)tcps_Close, 1},
+ {"Abort", (method)tcps_Abort, 1},
+ {"Status", (method)tcps_Status, 1},
+ {NULL, NULL} /* sentinel */
+};
+
+/* ---------- */
+
+static object *
+tcps_getattr(self, name)
+ tcpsobject *self;
+ char *name;
+{
+ if ( strcmp(name, "asr") == 0 ) {
+ INCREF(self->asr);
+ return self->asr;
+ }
+ return findmethod(tcps_methods, (object *)self, name);
+}
+
+static int
+tcps_setattr(self, name, value)
+ tcpsobject *self;
+ char *name;
+ object *value;
+{
+ if ( strcmp(name, "asr") != 0 || value == NULL )
+ return -1;
+ self->asr = value; /* XXXX Assuming I don't have to incref */
+ return 0;
+}
+
+static tcpsobject *
+newtcpsobject(bufsize)
+ int bufsize;
+{
+ tcpsobject *self;
+ OSErr err;
+
+ self = NEWOBJ(tcpsobject, &Tcpstype);
+ if (self == NULL)
+ return NULL;
+ memset((char *)&self->iop, 0, sizeof(self->iop));
+ err= xTCPCreate(bufsize, (TCPNotifyProc)tcps_asr, (void *)self, &self->iop);
+ if ( err ) {
+ DEL(self);
+ PyErr_Mac(ErrorObject, err);
+ return NULL;
+ }
+ INCREF(None);
+ self->asr = None;
+ self->async_busy = 0;
+ self->async_err = 0;
+ return self;
+}
+
+static void
+tcps_dealloc(self)
+ tcpsobject *self;
+{
+ if ( self->async_busy ) {
+ printf("mactcp module: error: dealloc with async busy\n");
+ return;
+ }
+ xTCPRelease(&self->iop);
+ DEL(self);
+}
+
+static typeobject Tcpstype = {
+ OB_HEAD_INIT(&Typetype)
+ 0, /*ob_size*/
+ "MacTCP TCP stream", /*tp_name*/
+ sizeof(tcpsobject), /*tp_basicsize*/
+ 0, /*tp_itemsize*/
+ /* methods */
+ (destructor)tcps_dealloc, /*tp_dealloc*/
+ (printfunc)0, /*tp_print*/
+ (getattrfunc)tcps_getattr, /*tp_getattr*/
+ (setattrfunc)tcps_setattr, /*tp_setattr*/
+ (cmpfunc)0, /*tp_compare*/
+ (reprfunc)0, /*tp_repr*/
+ 0, /*tp_as_number*/
+ 0, /*tp_as_sequence*/
+ 0, /*tp_as_mapping*/
+ (hashfunc)0, /*tp_hash*/
+};
+
+/* End of code for MacTCP TCP stream objects */
+/* -------------------------------------------------------- */
+
+static int
+udps_asr_safe(arg)
+ void *arg;
+{
+ udpsobject *self = (udpsobject *)arg;
+ object *args, *rv;
+
+ if ( self->asr == None )
+ return;
+ args = mkvalue("(i)", self->asr_ec);
+ rv = call_object(self->asr, args);
+ DECREF(args);
+ if ( rv ) {
+ DECREF(rv);
+ return 0;
+ }
+ return -1;
+}
+
+static pascal void
+udps_asr(str, ec, self, icmp)
+ StreamPtr str;
+ unsigned short ec;
+ udpsobject *self;
+ struct ICMPReport icmp;
+{
+ if ( self->asr == None )
+ return;
+ self->asr_ec = ec;
+ Py_AddPendingCall(udps_asr_safe, (void *)self);
+}
+
+
+static object *
+udps_Read(self, args)
+ udpsobject *self;
+ object *args;
+{
+ OSErr err;
+ object *rv;
+ int timeout;
+
+ if (!newgetargs(args, "i", &timeout))
+ return NULL;
+ err = xUDPRead(&self->iop, timeout, (UDPIOCompletionProc)0);
+ if ( err ) {
+ PyErr_Mac(ErrorObject, err);
+ return NULL;
+ }
+ rv = newsizedstringobject((char *)self->iop.csParam.receive.rcvBuff,
+ self->iop.csParam.receive.rcvBuffLen);
+ err = xUDPBfrReturn(&self->iop, self->iop.csParam.receive.rcvBuff);
+ if ( err ) {
+ PyErr_Mac(ErrorObject, err);
+ DECREF(rv);
+ return NULL;
+ }
+ return rv;
+}
+
+static object *
+udps_Write(self, args)
+ udpsobject *self;
+ object *args;
+{
+ unsigned long host;
+ unsigned short port;
+ char *buf;
+ int bufsize;
+ OSErr err;
+ miniwds wds;
+
+ if (!newgetargs(args, "lhs#", &host, &port, &buf, &bufsize))
+ return NULL;
+ wds.length = bufsize;
+ wds.ptr = buf;
+ wds.terminus = 0;
+ err = xUDPWrite(&self->iop, host, port, &wds, (UDPIOCompletionProc)0);
+ if ( err ) {
+ PyErr_Mac(ErrorObject, err);
+ return NULL;
+ }
+ INCREF(None);
+ return None;
+}
+static struct methodlist udps_methods[] = {
+ {"Read", (method)udps_Read, 1},
+ {"Write", (method)udps_Write, 1},
+
+ {NULL, NULL} /* sentinel */
+};
+
+/* ---------- */
+
+static object *
+udps_getattr(self, name)
+ udpsobject *self;
+ char *name;
+{
+ if ( strcmp(name, "asr") == 0 ) {
+ INCREF(self->asr);
+ return self->asr;
+ }
+ if ( strcmp(name, "port") == 0 )
+ return newintobject((int)self->port);
+ return findmethod(udps_methods, (object *)self, name);
+}
+
+static int
+udps_setattr(self, name, value)
+ udpsobject *self;
+ char *name;
+ object *value;
+{
+ if ( strcmp(name, "asr") != 0 || value == NULL )
+ return -1;
+ self->asr = value; /* XXXX Assuming I don't have to incref */
+ return 0;
+}
+
+static udpsobject *
+newudpsobject(bufsize, port)
+ int bufsize;
+ int port;
+{
+ udpsobject *self;
+ OSErr err;
+
+ self = NEWOBJ(udpsobject, &Udpstype);
+ if (self == NULL)
+ return NULL;
+ memset((char *)&self->iop, 0, sizeof(self->iop));
+ self->port = port;
+ err= xUDPCreate(&self->iop, bufsize, &self->port, (UDPNotifyProc)udps_asr,
+ (void *)self);
+ if ( err ) {
+ DEL(self);
+ PyErr_Mac(ErrorObject, err);
+ return NULL;
+ }
+ INCREF(None);
+ self->asr = None;
+ return self;
+}
+
+static void
+udps_dealloc(self)
+ udpsobject *self;
+{
+ xUDPRelease(&self->iop);
+ DEL(self);
+}
+
+static typeobject Udpstype = {
+ OB_HEAD_INIT(&Typetype)
+ 0, /*ob_size*/
+ "MacTCP UDP stream", /*tp_name*/
+ sizeof(udpsobject), /*tp_basicsize*/
+ 0, /*tp_itemsize*/
+ /* methods */
+ (destructor)udps_dealloc, /*tp_dealloc*/
+ (printfunc)0, /*tp_print*/
+ (getattrfunc)udps_getattr, /*tp_getattr*/
+ (setattrfunc)udps_setattr, /*tp_setattr*/
+ (cmpfunc)0, /*tp_compare*/
+ (reprfunc)0, /*tp_repr*/
+ 0, /*tp_as_number*/
+ 0, /*tp_as_sequence*/
+ 0, /*tp_as_mapping*/
+ (hashfunc)0, /*tp_hash*/
+};
+
+/* End of code for MacTCP UDP stream objects */
+/* -------------------------------------------------------- */
+
+static object *
+mactcp_TCPCreate(self, args)
+ object *self; /* Not used */
+ object *args;
+{
+ OSErr err;
+ object *rv;
+ int bufsize;
+
+ if (!newgetargs(args, "i", &bufsize))
+ return NULL;
+ if ( (err = xOpenDriver()) != noErr ) {
+ PyErr_Mac(ErrorObject, err);
+ return NULL;
+ }
+ rv = (object *)newtcpsobject(bufsize);
+ return rv;
+}
+
+static object *
+mactcp_UDPCreate(self, args)
+ object *self; /* Not used */
+ object *args;
+{
+ OSErr err;
+ object *rv;
+ int bufsize, port;
+
+ if (!newgetargs(args, "ii", &bufsize, &port))
+ return NULL;
+ if ( (err = xOpenDriver()) != noErr ) {
+ PyErr_Mac(ErrorObject, err);
+ return NULL;
+ }
+ rv = (object *)newudpsobject(bufsize, port);
+ return rv;
+}
+
+static object *
+mactcp_MTU(self, args)
+ object *self; /* Not used */
+ object *args;
+{
+ OSErr err;
+ unsigned short mtu;
+
+ if (!newgetargs(args, ""))
+ return NULL;
+ if ( (err = xOpenDriver()) != noErr ) {
+ PyErr_Mac(ErrorObject, err);
+ return NULL;
+ }
+ mtu = xMaxMTU();
+ return newintobject((int)mtu);
+}
+
+static object *
+mactcp_IPAddr(self, args)
+ object *self; /* Not used */
+ object *args;
+{
+ OSErr err;
+ unsigned long rv;
+
+ if (!newgetargs(args, ""))
+ return NULL;
+ if ( (err = xOpenDriver()) != noErr ) {
+ PyErr_Mac(ErrorObject, err);
+ return NULL;
+ }
+ rv = xIPAddr();
+ return newintobject((int)rv);
+}
+
+static object *
+mactcp_NetMask(self, args)
+ object *self; /* Not used */
+ object *args;
+{
+ OSErr err;
+ unsigned long rv;
+
+ if (!newgetargs(args, ""))
+ return NULL;
+ if ( (err = xOpenDriver()) != noErr ) {
+ PyErr_Mac(ErrorObject, err);
+ return NULL;
+ }
+ rv = xNetMask();
+ return newintobject((int)rv);
+}
+
+#ifdef TCP_GS
+static object *
+mactcp_GlobalInfo(self, args)
+ object *self; /* Not used */
+ object *args;
+{
+ OSErr err;
+
+ if (!newgetargs(args, ""))
+ return NULL;
+ if ( (err = xOpenDriver()) != noErr ) {
+ PyErr_Mac(ErrorObject, err);
+ return NULL;
+ }
+ /* XXXX Allocate, fill */
+ INCREF(None);
+ return None;
+}
+#endif /* TCP_GS */
+
+/* List of methods defined in the module */
+
+static struct methodlist mactcp_methods[] = {
+ {"TCPCreate", mactcp_TCPCreate, 1},
+ {"UDPCreate", mactcp_UDPCreate, 1},
+ {"MTU", mactcp_MTU, 1},
+ {"IPAddr", mactcp_IPAddr, 1},
+ {"NetMask", mactcp_NetMask, 1},
+#ifdef TCP_GS
+ {"GlobalInfo", mactcp_GlobalInfo, 1},
+#endif
+
+ {NULL, NULL} /* sentinel */
+};
+
+
+/* Initialization function for the module (*must* be called initmactcp) */
+
+void
+initmactcp()
+{
+ object *m, *d;
+
+ /* Create the module and add the functions */
+ m = initmodule("mactcp", mactcp_methods);
+
+ /* Add some symbolic constants to the module */
+ d = getmoduledict(m);
+ ErrorObject = newstringobject("mactcp.error");
+ dictinsert(d, "error", ErrorObject);
+
+ /* XXXX Add constants here */
+
+ /* Check for errors */
+ if (err_occurred())
+ fatal("can't initialize module mactcp");
+}