From 75b6f1c8e59b9f7737ef104b9391e2b92c911d47 Mon Sep 17 00:00:00 2001 From: Jack Jansen Date: Wed, 18 Jan 1995 13:50:42 +0000 Subject: [PATCH] - Ported to powerpc - Fixed bug with accept() call - Better error checking --- Mac/Unsupported/mactcp/macdnrmodule.c | 17 ++--- Mac/Unsupported/mactcp/mactcpmodule.c | 104 +++++++++++++++++++++++--- Mac/Unsupported/mactcp/tcpglue.c | 45 ++++------- Mac/Unsupported/mactcp/tcpglue.h | 43 ++++++++--- 4 files changed, 146 insertions(+), 63 deletions(-) diff --git a/Mac/Unsupported/mactcp/macdnrmodule.c b/Mac/Unsupported/mactcp/macdnrmodule.c index 75dd89a2ece..ca6ea1e15fa 100644 --- a/Mac/Unsupported/mactcp/macdnrmodule.c +++ b/Mac/Unsupported/mactcp/macdnrmodule.c @@ -190,8 +190,10 @@ dnrr_getattr(self, name) if ( rv ) return rv; err_clear(); if ( self->waiting ) - if ( !dnrwait(self) ) + if ( !dnrwait(self) ) { + err_setstr(ErrorObject, "Resolver busy"); return NULL; + } tp = self->type; return getmember((char *)&self->hinfo, dnrr_mlists[tp], name); } @@ -293,7 +295,7 @@ dnr_StrToAddr(self, args) if ( err == cacheFault ) { rv->waiting++; INCREF(rv); - } else { + } else if ( err ) { DECREF(rv); PyErr_Mac(ErrorObject, err); return NULL; @@ -321,7 +323,7 @@ dnr_AddrToName(self, args) if ( err == cacheFault ) { rv->waiting++; INCREF(rv); - } else { + } else if ( err ) { DECREF(rv); PyErr_Mac(ErrorObject, err); return NULL; @@ -369,7 +371,7 @@ dnr_HInfo(self, args) if ( err == cacheFault ) { rv->waiting++; INCREF(rv); - } else { + } else if ( err ) { DECREF(rv); PyErr_Mac(ErrorObject, err); return NULL; @@ -401,17 +403,12 @@ dnr_MXInfo(self, args) if ( err == cacheFault ) { rv->waiting++; INCREF(rv); - } else { + } else if ( err ) { DECREF(rv); PyErr_Mac(ErrorObject, err); return NULL; } return (object *)rv; - - if (!newgetargs(args, "")) - return NULL; - INCREF(None); - return None; } /* List of methods defined in the module */ diff --git a/Mac/Unsupported/mactcp/mactcpmodule.c b/Mac/Unsupported/mactcp/mactcpmodule.c index 0ba05ec5670..f2c129098c4 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 +/* 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 */ @@ -241,6 +256,34 @@ static typeobject Tcpgstype = { /* End of code for MacTCP global status objects */ /* -------------------------------------------------------- */ +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 */ diff --git a/Mac/Unsupported/mactcp/tcpglue.c b/Mac/Unsupported/mactcp/tcpglue.c index 1c8ecb0f9b4..79042b485d9 100644 --- a/Mac/Unsupported/mactcp/tcpglue.c +++ b/Mac/Unsupported/mactcp/tcpglue.c @@ -15,11 +15,6 @@ #include "tcpglue.h" #include -#ifndef __MWERKS__ -#define TCPIOCompletionUPP TCPIOCompletionProc -#define NewTCPIOCompletionProc(x) (x) -#endif /* __MWERKS__ */ - static short driver = 0; #ifndef __powerc @@ -56,7 +51,7 @@ OSErr xOpenDriver() */ OSErr xTCPCreate(buflen,notify,udp, pb) int buflen; - TCPNotifyProc notify; + TCPNotifyUPP notify; void *udp; TCPiopb *pb; { @@ -73,7 +68,7 @@ OSErr xTCPCreate(buflen,notify,udp, pb) /* * start listening for a TCP connection */ -OSErr xTCPPassiveOpen(TCPiopb *pb, short port, TCPIOCompletionProc completion, +OSErr xTCPPassiveOpen(TCPiopb *pb, short port, TCPIOCompletionUPP completion, void *udp) { if (driver == 0) @@ -101,7 +96,7 @@ OSErr xTCPPassiveOpen(TCPiopb *pb, short port, TCPIOCompletionProc completion, * connect to a remote TCP */ OSErr xTCPActiveOpen(TCPiopb *pb, short port, long rhost, short rport, - TCPIOCompletionProc completion) + TCPIOCompletionUPP completion) { if (driver == 0) return(invalidStreamPtr); @@ -128,7 +123,7 @@ OSErr xTCPNoCopyRcv(pb,rds,rdslen,timeout,completion) rdsEntry *rds; int rdslen; int timeout; - TCPIOCompletionProc completion; + TCPIOCompletionUPP completion; { if (driver == 0) @@ -142,7 +137,7 @@ OSErr xTCPNoCopyRcv(pb,rds,rdslen,timeout,completion) return (xPBControl(pb,completion)); } -OSErr xTCPBufReturn(TCPiopb *pb,rdsEntry *rds,TCPIOCompletionProc completion) +OSErr xTCPBufReturn(TCPiopb *pb,rdsEntry *rds,TCPIOCompletionUPP completion) { pb->ioCRefNum = driver; pb->csCode = TCPRcvBfrReturn; @@ -154,7 +149,7 @@ OSErr xTCPBufReturn(TCPiopb *pb,rdsEntry *rds,TCPIOCompletionProc completion) /* * send data */ -OSErr xTCPSend(TCPiopb *pb, wdsEntry *wds, Boolean push, Boolean urgent, TCPIOCompletionProc completion) +OSErr xTCPSend(TCPiopb *pb, wdsEntry *wds, Boolean push, Boolean urgent, TCPIOCompletionUPP completion) { if (driver == 0) return invalidStreamPtr; @@ -174,7 +169,7 @@ OSErr xTCPSend(TCPiopb *pb, wdsEntry *wds, Boolean push, Boolean urgent, TCPIOCo /* * close a connection */ -OSErr xTCPClose(TCPiopb *pb,TCPIOCompletionProc completion) +OSErr xTCPClose(TCPiopb *pb,TCPIOCompletionUPP completion) { if (driver == 0) return(invalidStreamPtr); @@ -306,7 +301,7 @@ OSErr xTCPStatus(TCPiopb *pb, TCPStatusPB **spb) /* * create a UDP stream, hook it to a socket. */ -OSErr xUDPCreate(UDPiopb *pb,int buflen,ip_port *port, UDPNotifyProc asr, void *udp) +OSErr xUDPCreate(UDPiopb *pb,int buflen,ip_port *port, UDPNotifyUPP asr, void *udp) { OSErr io; @@ -327,7 +322,7 @@ OSErr xUDPCreate(UDPiopb *pb,int buflen,ip_port *port, UDPNotifyProc asr, void * /* * ask for incoming data */ -OSErr xUDPRead(UDPiopb *pb, int timeout, UDPIOCompletionProc completion) +OSErr xUDPRead(UDPiopb *pb, int timeout, UDPIOCompletionUPP completion) { if (driver == 0) @@ -337,7 +332,7 @@ OSErr xUDPRead(UDPiopb *pb, int timeout, UDPIOCompletionProc completion) pb->csCode = UDPRead; pb->csParam.receive.timeOut = timeout; pb->csParam.receive.secondTimeStamp = 0/* must be zero */; - return (xPBControl ( (TCPiopb *)pb, (TCPIOCompletionProc)completion )); + return (xPBControl ( (TCPiopb *)pb, (TCPIOCompletionUPP)completion )); } OSErr xUDPBfrReturn(UDPiopb *pb, char *buff) @@ -349,14 +344,14 @@ OSErr xUDPBfrReturn(UDPiopb *pb, char *buff) pb->ioCRefNum = driver; pb->csCode = UDPBfrReturn; pb->csParam.receive.rcvBuff = buff; - return ( xPBControl( (TCPiopb *)pb,(TCPIOCompletionProc)-1 ) ); + return ( xPBControl( (TCPiopb *)pb,(TCPIOCompletionUPP)-1 ) ); } /* * send data */ OSErr xUDPWrite(UDPiopb *pb,ip_addr host,ip_port port,miniwds *wds, - UDPIOCompletionProc completion) + UDPIOCompletionUPP completion) { if (driver == 0) @@ -369,7 +364,7 @@ OSErr xUDPWrite(UDPiopb *pb,ip_addr host,ip_port port,miniwds *wds, pb->csParam.send.wdsPtr = (Ptr)wds; pb->csParam.send.checkSum = true; pb->csParam.send.sendLength = 0/* must be zero */; - return (xPBControl( (TCPiopb *)pb, (TCPIOCompletionProc)completion)); + return (xPBControl( (TCPiopb *)pb, (TCPIOCompletionUPP)completion)); } /* @@ -443,7 +438,7 @@ OSErr xTCPRcv(pb,buf,buflen,timeout,completion) Ptr buf; int buflen; int timeout; - TCPIOCompletionProc completion; + TCPIOCompletionUPP completion; { if (driver == 0) @@ -457,7 +452,7 @@ OSErr xTCPRcv(pb,buf,buflen,timeout,completion) return (xPBControl(pb,completion)); } -OSErr xPBControl(TCPiopb *pb,TCPIOCompletionProc completion) +OSErr xPBControl(TCPiopb *pb,TCPIOCompletionUPP completion) { #ifndef __MWERKS__ pb->ioNamePtr = ReturnA5(); @@ -468,22 +463,14 @@ OSErr xPBControl(TCPiopb *pb,TCPIOCompletionProc completion) (pb)->ioCompletion = 0L; return(PBControl((ParmBlkPtr)(pb),false)); /* sync */ } - else if (completion == (TCPIOCompletionProc)-1L) + else if (completion == (TCPIOCompletionUPP)-1L) { (pb)->ioCompletion = 0L; return(PBControl((ParmBlkPtr)(pb),true)); /* async */ } else { -#if 0 - /* If I understand the PowerPC calling correctly this is the right - ** code, but the MetroWerks headers seem to disagree. We'll see... -- Jack - */ - TCPIOCompletionUPP comp_upp = NewTCPIOCompletionProc(completion); - (pb)->ioCompletion = comp_upp; -#else (pb)->ioCompletion = completion; -#endif return(PBControl((ParmBlkPtr)(pb),true)); /* async */ } } diff --git a/Mac/Unsupported/mactcp/tcpglue.h b/Mac/Unsupported/mactcp/tcpglue.h index 4db91f004d7..ef9e133a8d1 100644 --- a/Mac/Unsupported/mactcp/tcpglue.h +++ b/Mac/Unsupported/mactcp/tcpglue.h @@ -14,6 +14,21 @@ #include #include +#ifndef __MWERKS__ +#define TCPIOCompletionUPP TCPIOCompletionProc +#define TCPNotifyUPP TCPNotifyProc +#define UDPIOCompletionUPP UDPIOCompletionProc +#define UDPNotifyUPP UDPNotifyProc +#define NewTCPIOCompletionProc(x) (x) +#define NewTCPNotifyProc(x) (x) +#define NewUDPIOCompletionProc(x) (x) +#define NewUDPNotifyProc(x) (x) +#endif /* __MWERKS__ */ + +#if defined(powerc) || defined (__powerc) +#pragma options align=mac68k +#endif + typedef struct miniwds { unsigned short length; @@ -21,26 +36,30 @@ typedef struct miniwds unsigned short terminus; /* must be zero'd for use */ } miniwds; +#if defined(powerc) || defined(__powerc) +#pragma options align=reset +#endif + OSErr xOpenDriver(void); -OSErr xPBControl(TCPiopb *pb, TCPIOCompletionProc completion); +OSErr xPBControl(TCPiopb *pb, TCPIOCompletionUPP completion); OSErr xPBControlSync(TCPiopb *pb); -OSErr xTCPCreate(int buflen, TCPNotifyProc notify, void *udp, TCPiopb *pb); -OSErr xTCPPassiveOpen(TCPiopb *pb, short port, TCPIOCompletionProc completion, void *udp); -OSErr xTCPActiveOpen(TCPiopb *pb, short port, long rhost, short rport, TCPIOCompletionProc completion); -OSErr xTCPRcv(TCPiopb *pb, char *buf, int buflen, int timeout, TCPIOCompletionProc completion); -OSErr xTCPNoCopyRcv(TCPiopb *,rdsEntry *,int,int,TCPIOCompletionProc); -OSErr xTCPBufReturn(TCPiopb *pb,rdsEntry *rds,TCPIOCompletionProc completion); -OSErr xTCPSend(TCPiopb *pb, wdsEntry *wds, Boolean push, Boolean urgent, TCPIOCompletionProc completion); -OSErr xTCPClose(TCPiopb *pb,TCPIOCompletionProc completion); +OSErr xTCPCreate(int buflen, TCPNotifyUPP notify, void *udp, TCPiopb *pb); +OSErr xTCPPassiveOpen(TCPiopb *pb, short port, TCPIOCompletionUPP completion, void *udp); +OSErr xTCPActiveOpen(TCPiopb *pb, short port, long rhost, short rport, TCPIOCompletionUPP completion); +OSErr xTCPRcv(TCPiopb *pb, char *buf, int buflen, int timeout, TCPIOCompletionUPP completion); +OSErr xTCPNoCopyRcv(TCPiopb *,rdsEntry *,int,int,TCPIOCompletionUPP); +OSErr xTCPBufReturn(TCPiopb *pb,rdsEntry *rds,TCPIOCompletionUPP completion); +OSErr xTCPSend(TCPiopb *pb, wdsEntry *wds, Boolean push, Boolean urgent, TCPIOCompletionUPP completion); +OSErr xTCPClose(TCPiopb *pb,TCPIOCompletionUPP completion); OSErr xTCPAbort(TCPiopb *pb); OSErr xTCPRelease(TCPiopb *pb); -OSErr xUDPCreate(UDPiopb *pb,int buflen,ip_port *port, UDPNotifyProc asr, void *udp); -OSErr xUDPRead(UDPiopb *pb,int timeout, UDPIOCompletionProc completion); +OSErr xUDPCreate(UDPiopb *pb,int buflen,ip_port *port, UDPNotifyUPP asr, void *udp); +OSErr xUDPRead(UDPiopb *pb,int timeout, UDPIOCompletionUPP completion); OSErr xUDPBfrReturn(UDPiopb *pb, char *buff); OSErr xUDPWrite(UDPiopb *pb,ip_addr host,ip_port port,miniwds *wds, - UDPIOCompletionProc completion); + UDPIOCompletionUPP completion); OSErr xUDPRelease(UDPiopb *pb); ip_addr xIPAddr(void);