diff options
Diffstat (limited to 'Mac/Unsupported/mactcp/mactcpmodule.c')
-rw-r--r-- | Mac/Unsupported/mactcp/mactcpmodule.c | 104 |
1 files changed, 92 insertions, 12 deletions
diff --git a/Mac/Unsupported/mactcp/mactcpmodule.c b/Mac/Unsupported/mactcp/mactcpmodule.c index 0ba05ec..f2c1290 100644 --- a/Mac/Unsupported/mactcp/mactcpmodule.c +++ b/Mac/Unsupported/mactcp/mactcpmodule.c @@ -30,8 +30,21 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include <Desk.h> +/* State of a tcp stream, in the connectionState field */ +#define STATE_CLOSED 0 +#define STATE_LISTEN 2 +#define STATE_ESTAB 8 +#define STATE_CWAIT 18 + static object *ErrorObject; +TCPIOCompletionUPP upp_tcp_done; +TCPNotifyUPP upp_tcp_asr; +#if 0 +UDPIOCompletionUPP upp_udp_done; +#endif +UDPNotifyUPP upp_udp_asr; + /* ----------------------------------------------------- */ /* Declarations for objects of type MacTCP connection status */ @@ -64,6 +77,8 @@ staticforward typeobject Tcpgstype; typedef struct { OB_HEAD TCPiopb iop; + long localhost; /* Our IP address */ + short localport; /* Our port number */ object *asr; /* Optional async notification routine */ int asr_ec; /* error code parameter to asr */ int asr_reason; /* detail for some errors */ @@ -242,6 +257,34 @@ static typeobject Tcpgstype = { /* -------------------------------------------------------- */ static int +tcps_checkstate(self, state, state2) + tcpsobject *self; + int state, state2; +{ + OSErr err; + TCPStatusPB *pb; + char buf[80]; + + if ( self->async_busy ) { + err_setstr(ErrorObject, "Operation not allowed, PassiveOpen in progress"); + return -1; + } + if ( state < 0 && state2 < 0 ) + return 0; + err = xTCPStatus(&self->iop, &pb); + if ( err ) { + PyErr_Mac(ErrorObject, err); + return -1; + } + if ( state == pb->connectionState || + state2 == pb->connectionState ) + return 0; + sprintf(buf, "Operation not allowed, connection state=%d", pb->connectionState); + err_setstr(ErrorObject, buf); + return -1; +} + +static int tcps_asr_safe(arg) void *arg; { @@ -276,14 +319,14 @@ tcps_asr(str, ec, self, reason, icmp) } static void -tcps_opendone(pb) +tcps_done(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"); + printf("tcps_done: unexpected call\n"); return; } self->async_busy = 0; @@ -339,15 +382,19 @@ tcps_PassiveOpen(self, args) if (!newgetargs(args, "h", &port)) return NULL; + if ( tcps_checkstate(self, -1, -1) < 0 ) + return NULL; self->async_busy = 1; self->async_err = 0; - err = xTCPPassiveOpen(&self->iop, port, (TCPIOCompletionProc)tcps_opendone, + err = xTCPPassiveOpen(&self->iop, port, upp_tcp_done, (void *)self); if ( err ) { self->async_busy = 0; PyErr_Mac(ErrorObject, err); return NULL; } + self->localhost = self->iop.csParam.open.localHost; + self->localport = self->iop.csParam.open.localPort; INCREF(None); return None; } @@ -363,11 +410,15 @@ tcps_ActiveOpen(self, args) if (!newgetargs(args, "hlh", &lport, &rhost, &rport)) return NULL; - err = xTCPActiveOpen(&self->iop, lport, rhost, rport, (TCPIOCompletionProc)0); + if ( tcps_checkstate(self, -1, -1) < 0 ) + return NULL; + err = xTCPActiveOpen(&self->iop, lport, rhost, rport, (TCPIOCompletionUPP)0); if ( err ) { PyErr_Mac(ErrorObject, err); return NULL; } + self->localhost = self->iop.csParam.open.localHost; + self->localport = self->iop.csParam.open.localPort; INCREF(None); return None; } @@ -385,11 +436,13 @@ tcps_Send(self, args) if (!newgetargs(args, "s#|ii", &buf, &bufsize, &push, &urgent)) return NULL; + if ( tcps_checkstate(self, STATE_ESTAB, STATE_CWAIT) < 0 ) + return NULL; wds.length = bufsize; wds.ptr = buf; wds.terminus = 0; err = xTCPSend(&self->iop, (wdsEntry *)&wds, (Boolean)push, (Boolean)urgent, - (TCPIOCompletionProc)0); + (TCPIOCompletionUPP)0); if ( err ) { PyErr_Mac(ErrorObject, err); return NULL; @@ -412,8 +465,10 @@ tcps_Rcv(self, args) if (!newgetargs(args, "i", &timeout)) return NULL; + if ( tcps_checkstate(self, -1, -1) < 0 ) + return NULL; memset((char *)&rds, 0, sizeof(rds)); - err = xTCPNoCopyRcv(&self->iop, rds, 1, timeout, (TCPIOCompletionProc)0); + err = xTCPNoCopyRcv(&self->iop, rds, 1, timeout, (TCPIOCompletionUPP)0); if ( err ) { PyErr_Mac(ErrorObject, err); return NULL; @@ -421,7 +476,7 @@ tcps_Rcv(self, args) 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); + err = xTCPBufReturn(&self->iop, rds, (TCPIOCompletionUPP)0); if ( err ) { /* Should not happen */printf("mactcp module: BufReturn failed?\n"); PyErr_Mac(ErrorObject, err); @@ -440,7 +495,7 @@ tcps_Close(self, args) if (!newgetargs(args, "")) return NULL; - err = xTCPClose(&self->iop, (TCPIOCompletionProc)0); + err = xTCPClose(&self->iop, (TCPIOCompletionUPP)0); if ( err ) { PyErr_Mac(ErrorObject, err); return NULL; @@ -477,6 +532,8 @@ tcps_Status(self, args) if (!newgetargs(args, "")) return NULL; + if ( tcps_checkstate(self, -1, -1) < 0 ) + return NULL; err = xTCPStatus(&self->iop, &pb); if ( err ) { PyErr_Mac(ErrorObject, err); @@ -485,6 +542,21 @@ tcps_Status(self, args) return (object *)newtcpcsobject(pb); } +static object * +tcps_GetSockName(self, args) + tcpsobject *self; + object *args; +{ + /* This routine is needed so we can get at the local port even when + ** a PassiveOpen is in progress (when we can't do a Status call). + ** This is needed for socket listen(); getsockname(); accept() emulation + ** as used by ftp and the like. + */ + if (!newgetargs(args, "")) + return NULL; + return mkvalue("(lh)", self->localhost, self->localport); +} + static struct methodlist tcps_methods[] = { {"isdone", (method)tcps_isdone, 1}, {"wait", (method)tcps_wait, 1}, @@ -495,6 +567,7 @@ static struct methodlist tcps_methods[] = { {"Close", (method)tcps_Close, 1}, {"Abort", (method)tcps_Abort, 1}, {"Status", (method)tcps_Status, 1}, + {"GetSockName", (method)tcps_GetSockName, 1}, {NULL, NULL} /* sentinel */ }; @@ -535,7 +608,7 @@ newtcpsobject(bufsize) if (self == NULL) return NULL; memset((char *)&self->iop, 0, sizeof(self->iop)); - err= xTCPCreate(bufsize, (TCPNotifyProc)tcps_asr, (void *)self, &self->iop); + err= xTCPCreate(bufsize, upp_tcp_asr, (void *)self, &self->iop); if ( err ) { DEL(self); PyErr_Mac(ErrorObject, err); @@ -626,7 +699,7 @@ udps_Read(self, args) if (!newgetargs(args, "i", &timeout)) return NULL; - err = xUDPRead(&self->iop, timeout, (UDPIOCompletionProc)0); + err = xUDPRead(&self->iop, timeout, (UDPIOCompletionUPP)0); if ( err ) { PyErr_Mac(ErrorObject, err); return NULL; @@ -659,7 +732,7 @@ udps_Write(self, args) wds.length = bufsize; wds.ptr = buf; wds.terminus = 0; - err = xUDPWrite(&self->iop, host, port, &wds, (UDPIOCompletionProc)0); + err = xUDPWrite(&self->iop, host, port, &wds, (UDPIOCompletionUPP)0); if ( err ) { PyErr_Mac(ErrorObject, err); return NULL; @@ -715,7 +788,7 @@ newudpsobject(bufsize, port) return NULL; memset((char *)&self->iop, 0, sizeof(self->iop)); self->port = port; - err= xUDPCreate(&self->iop, bufsize, &self->port, (UDPNotifyProc)udps_asr, + err= xUDPCreate(&self->iop, bufsize, &self->port, upp_udp_asr, (void *)self); if ( err ) { DEL(self); @@ -899,6 +972,13 @@ initmactcp() d = getmoduledict(m); ErrorObject = newstringobject("mactcp.error"); dictinsert(d, "error", ErrorObject); + + upp_tcp_done = NewTCPIOCompletionProc(tcps_done); + upp_tcp_asr = NewTCPNotifyProc(tcps_asr); +#if 0 + upp_udp_done = NewUDPIOCompletionProc(udps_done); +#endif + upp_udp_asr = NewUDPNotifyProc(udps_asr); /* XXXX Add constants here */ |