/* GSocket_Shutdown: * Disallow further read/write operations on this socket, close * the fd and disable all callbacks. */ void GSocket_Shutdown(GSocket *socket) { OSStatus err ; int evt; assert(socket != NULL); /* If socket has been created, shutdown it */ if (socket->m_endpoint != kOTInvalidEndpointRef ) { err = OTSndOrderlyDisconnect( socket->m_endpoint ) ; if ( err != kOTNoError ) { } err = OTRcvOrderlyDisconnect( socket->m_endpoint ) ; err = OTUnbind( socket->m_endpoint ) ; err = OTCloseProvider( socket->m_endpoint ) ; socket->m_endpoint = kOTInvalidEndpointRef ; } /* Disable GUI callbacks */ for (evt = 0; evt < GSOCK_MAX_EVENT; evt++) socket->m_cbacks[evt] = NULL; socket->m_detected = 0; _GSocket_Disable_Events(socket); wxMacRemoveAllNotifiersForData( wxMacGetNotifierTable() , socket ) ; }
NMErr OTIPEnumerator::EndEnumeration(void) { OSStatus status; if (! bActive) return kNMNoError; if (mEP == kOTInvalidEndpointRef) return kNMNoError; status = OTUnbind(mEP); if (status == kNMNoError) { for (NMSInt32 i = 0; i < 1000; i++) { if (OTGetEndpointState(mEP) == T_UNBND) break; } } status = OTCloseProvider(mEP); InterruptSafe_free(mIncomingData.udata.buf); return kNMNoError; }
void unbind_from_qelem (void* arg) { int tries; OSStatus s; OTUDP *x; x = (OTUDP *) arg; // post("*** Entering unbind_from_qelem()"); /* First, if we're trying to change the host, make sure the desired new host is OK. */ if (x->o_desiredNewHostName != 0) { InetHost host; // post("*** about to call LookUpInetHost"); if (LookUpInetHost(x->o_desiredNewHostName, &host) == 0) { error("¥ Can't change Internet host: \"%s\" makes no sense.", x->o_desiredNewHostName); /* No harm done; just ignore the host change request. */ x->o_desiredNewHostName = 0; return; } // post("*** looked up new host"); // Remember new host info so we can rebind when the Unbind completes. x->o_inetHostName = x->o_desiredNewHostName; x->o_inetHost = host; x->o_inetPort = x->o_desiredNewPort; x->o_desiredNewHostName = 0; } tries = 0; while (1) { // post("*** About to unbind"); s = OTUnbind(x->o_udp_ep); if (s == kOTNoError) { // Groovy; now we just wait for T_UNBINDCOMPLETE in OTUDPNotifier() } else if (s == kOTLookErr) { // Probably more data has arrived, so we have to read it all out // before this can work. if (tries > 3) { error("¥ OTUDP: kept getting kOTLookErr when trying to unbind; I give up."); break; } error("OTUDP: Couldn't unbind because kOTLookErr; reading then trying again."); otudp_read(x); ++tries; continue; } else { error("¥ OTUDP: OTUnbind returned %ld; can't change host.", s); } break; } }
void ot_cleanup(void) { Actual_Socket s; for (s = ot.socklist; s !=NULL; s = s->next) { OTUnbind(s->ep); OTCloseProvider(s->ep); } CloseOpenTransport(); }
PRInt32 _MD_closesocket(PRInt32 osfd) { OSStatus err; EndpointRef endpoint = (EndpointRef) osfd; PRThread *me = _PR_MD_CURRENT_THREAD(); if (endpoint == NULL) { err = kEBADFErr; goto ErrorExit; } if (me->io_pending && me->io_fd == osfd) me->io_pending = PR_FALSE; #if 0 { OTResult state; state = OTGetEndpointState(endpoint); err = OTSndOrderlyDisconnect(endpoint); if (err != kOTNoError && err != kOTOutStateErr) goto ErrorExit; state = OTGetEndpointState(endpoint); err = OTUnbind(endpoint); if (err != kOTNoError && err != kOTOutStateErr) goto ErrorExit; state = OTGetEndpointState(endpoint); err = OTSetSynchronous(endpoint); if (err != kOTNoError) goto ErrorExit; err = OTSetBlocking(endpoint); if (err != kOTNoError) goto ErrorExit; } #endif (void) OTSndOrderlyDisconnect(endpoint); err = OTCloseProvider(endpoint); if (err != kOTNoError) goto ErrorExit; return kOTNoError; ErrorExit: macsock_map_error(err); return -1; }
/*---------------------------------------------------------------------------*/ static sword AGNetSocketClose(AGNetCtx *ctx, AGSocket *soc) { /* Note that in this implementation we don't actually need the AGNetCtx pointer. Left in for source-code compatibility. */ if (NULL != soc) { if (soc->bound) OTUnbind(soc->ep); if (kOTInvalidEndpointRef != soc->ep) OTCloseProvider(soc->ep); } return 0; }
/* Close a UDP network socket */ extern void SDLNet_UDP_Close(UDPsocket sock) { if ( sock != NULL ) { if ( sock->channel != INVALID_SOCKET ) { #ifdef MACOS_OPENTRANSPORT OTUnbind(sock->channel); OTCloseProvider(sock->channel); #else closesocket(sock->channel); #endif /* MACOS_OPENTRANSPORT */ } free(sock); } }
// Errors: // EBADF -- bad socket id PRInt32 _MD_listen(PRFileDesc *fd, PRIntn backlog) { #if 0 PRInt32 osfd = fd->secret->md.osfd; OSStatus err; EndpointRef endpoint = (EndpointRef) osfd; TBind bindReq; PRNetAddr addr; PRThread *me = _PR_MD_CURRENT_THREAD(); if (backlog == 0) backlog = 1; if (endpoint == NULL) { err = EBADF; goto ErrorExit; } addr.inet.port = addr.inet.ip = 0; bindReq.addr.maxlen = PR_NETADDR_SIZE (&addr); bindReq.addr.len = 0; bindReq.addr.buf = (UInt8*) &addr; bindReq.qlen = 0; PrepareThreadForAsyncIO(me, endpoint, osfd); err = OTGetProtAddress(endpoint, &bindReq, NULL); if (err != kOTNoError) goto ErrorExit; WaitOnThisThread(me, PR_INTERVAL_NO_TIMEOUT); err = me->md.osErrCode; if (err != kOTNoError) goto ErrorExit; PrepareThreadForAsyncIO(me, endpoint, osfd); err = OTUnbind(endpoint); if (err != kOTNoError) goto ErrorExit; WaitOnThisThread(me, PR_INTERVAL_NO_TIMEOUT); err = me->md.osErrCode; if (err != kOTNoError) goto ErrorExit; bindReq.qlen = backlog; PrepareThreadForAsyncIO(me, endpoint, osfd); err = OTBind(endpoint, &bindReq, NULL); if (err != kOTNoError) goto ErrorExit; WaitOnThisThread(me, PR_INTERVAL_NO_TIMEOUT); err = me->md.osErrCode; if (err != kOTNoError) goto ErrorExit; PR_ASSERT(me->md.cookie == NULL); return kOTNoError; ErrorExit: macsock_map_error(err); return -1; #endif #pragma unused (fd, backlog) return kOTNoError; }
static void change_connection(OTTCP *x) { // This sets in motion the following sequence of events: // - Disconnect the endpoint // - Unbind the endpoint // - If (x->o_inetHost != 0), bind the endpoint again // - connect the endpoint // Each of these events is triggered in the notifier function when the previous // event completes, so the job of this procedure is just to see what state we're // in and start the process. OTResult r; OSStatus s; ChangeState(x, SETTING_UP); r = OTGetEndpointState(x->o_tcp_ep); if (r == T_UNINIT) { // This shouldn't happen ouchstring("OTTCP: Connect: didn't expect endpoint state to be T_UNINIT!"); } else if (r == T_UNBND) { // Endpoint is already unbound, so we're completely disconnected. // If we have a new inetHost, try to bind it if (x->o_inetHost != 0) { BindTheEndpoint(x); // Now we expect T_BINDCOMPLETE } // Now we expect T_BINDCOMPLETE } else if (r == T_IDLE) { // Endpoint is bound, but not connected. s = OTUnbind(x->o_tcp_ep); if (s != kOTNoError) { post("OTTCP: warning: OTUnbind returned %ld", s); } // Now we expect T_UNBINDCOMPLETE } else if (r == T_OUTCON || r == T_DATAXFER) { // We're either starting a connection or the connection is currently established, // so send an orderly disconnect post ("** Sending orderly disconnect "); s = OTSndOrderlyDisconnect(x->o_tcp_ep); if (s != kOTNoError) { post("OTTCP: warning: OTSndOrderlyDisconnect returned %ld", s); } // I guess now we expect T_DISCONNECTCOMPLETE } else if (r == T_INCON) { ouchstring("OTTCP: Connect: didn't expect endpoint state to be T_INCON!"); } else if (r == T_OUTREL) { // We already tried an orderly disconnect, but it still hasn't been acknowledged, // so screw orderliness and try a regular diconnect TCall call; call.addr.len = 0; call.opt.len = 0; call.udata.len = 0; call.addr.maxlen = 0; call.opt.maxlen = 0; call.udata.maxlen = 0; s = OTSndDisconnect(x->o_tcp_ep, &call); if (s != kOTNoError) { post("OTTCP: warning: OTSndDisconnect returned %ld", s); } // Now we expect T_DISCONNECTCOMPLETE } else if (r == T_INREL) { // Our peer wants an orderly disonnect, so let's acknowlegde it! } else { post(" еее Unrecognized endpoint state %ld!", r); } }
pascal void OTTCPNotifier(void* vobj, OTEventCode code, OTResult result, void* cookie) { OTTCP *x = (OTTCP *) vobj; long oldA5; OSStatus s; EnterCallback(); oldA5 = SetA5(x->o_a5); post("*** OTTCPNotifier(code %x, result %ld)", (long) code, (long) result); if (code == T_OPENCOMPLETE) { if (result != noErr) { post("OTTCPNotifier got a T_OPENCOMPLETE code with error %ld", result); } // Even if we got an error, we'll use the endpoint. x->o_tcp_ep = (EndpointRef) cookie; if (x->o_inetHostName != 0) { BindTheEndpoint(x); // Now we expect a T_BINDCOMPLETE message. } } else if (code == T_BINDCOMPLETE) { TCall sndCall; InetAddress inAddr; // See what ephemeral port number OT gave us x->o_receiveInetPort = x->o_addrWeActuallyGot.fPort; // Now the endpoint has been bound; next trick is connecting OTInitInetAddress(&inAddr, x->o_inetPort, x->o_inetHost); OTMemzero(&sndCall, sizeof(TCall)); sndCall.addr.buf = (void *) &inAddr; sndCall.addr.len = sizeof(InetAddress); post("** About to OTConnect"); s = OTConnect(x->o_tcp_ep, &sndCall, NULL); if (s == kOTNoDataErr) { // No problem; that means connection is in progress post("** OTConnect returned kOTNoDataErr - good"); } else { post("е OTTCP: error: OTConnect returned %ld; not connecting.", s); } // Now we expect T_CONNECT } else if (code == T_CONNECT) { if (result == kOTBadAddressErr) { post("е OTTCP: error: bad address. Disconnecting"); x->o_inetHost = 0; change_connection(x); } else { post("** Got T_CONNECT"); post("** Result passed to notifier: %ld", (long) result); post("** Endpoint state before OTRcvConnect: %ld", (long) OTGetEndpointState(x->o_tcp_ep)); // We could pass in buffers to find out the actual address we connected to, etc. s = OTRcvConnect(x->o_tcp_ep, nil); if (s != kOTNoError) { post("е OTTCP: error: RcvConnect returned %ld", s); } post("** Endpoint state after OTRcvConnect: %ld", (long) OTGetEndpointState(x->o_tcp_ep)); ChangeState(x, NO_REQUEST); x->o_connectionSymbol = ps_connected; clock_delay(x->o_connectedclock, 0); } } else if (code == T_UNBINDCOMPLETE) { // If we have a new inetHost, try to bind it if (x->o_inetHost != 0) { BindTheEndpoint(x); // Now we expect T_BINDCOMPLETE } else { // No inetHost, so we're disonnected x->o_connectionSymbol = ps_disconnected; clock_delay(x->o_connectedclock, 0); } } else if (code == T_DISCONNECTCOMPLETE) { // We always want to rebind when we reconnect, so after disconnecting we unbind s = OTUnbind(x->o_tcp_ep); if (s != kOTNoError) { post("OTTCP: warning: OTUnbind returned %ld", s); } } else if (code == T_DATA) { ottcp_handleIncomingData(x); } else if (code == T_UDERR) { if (x->o_errorreporting) { PostUDERR("OTTCPNotifier was called for a T_UDERR code", x->o_tcp_ep); } else { /* We still have to receive the error to clear the condition */ OTRcvUDErr(x->o_tcp_ep, 0); } } else if (code == T_GODATA) { // Flow control restriction has lifted; now it's OK to send more data. do_write(x, 0, 0); } else if (code == T_DISCONNECT) { // The other dude wants to disconnect post("OTTCP: peer wants to disconnect"); s = OTRcvDisconnect(x->o_tcp_ep, NULL); if (s == kOTNoError) { x->o_inetHost = 0; change_connection(x); } else if (s == kOTNoDisconnectErr) { // false alarm } else { post("е OTTCP: error: OTRcvDisconnect returned %ld", s); } } else if (code == T_ORDREL) { post("*** Got T_ORDREL"); s = OTRcvOrderlyDisconnect(x->o_tcp_ep); if (s == kOTNoReleaseErr) { post("...false alarm!"); } else if (s == kOTNoError) { x->o_inetHost = 0; change_connection(x); } else { post("е OTTCP: error: OTRcvOrderlyDisconnect returned %ld", s); } } else { if (x->o_errorreporting) { post("OTTCP: Unrecognized OTEventCode %ld in event handler. Oh well.", (long) code); } } done: SetA5(oldA5); ExitCallback(); }
int connect_chuukei_server(char *prf_name) { #ifndef MACINTOSH #ifdef WINDOWS WSADATA wsaData; WORD wVersionRequested = (WORD) (( 1) | ( 1 << 8)); #endif struct sockaddr_in ask; struct hostent *hp; if (read_chuukei_prf(prf_name) < 0) { printf("Wrong prf file\n"); return (-1); } if (init_buffer() < 0) { printf("Malloc error\n"); return (-1); } #ifdef WINDOWS if (WSAStartup(wVersionRequested, &wsaData)) { msg_print("Report: WSAStartup failed."); return (-1); } #endif printf("server = %s\nport = %d\n", server_name, server_port); if ((hp = gethostbyname(server_name)) != NULL) { memset(&ask, 0, sizeof(ask)); memcpy(&ask.sin_addr, hp->h_addr_list[0], hp->h_length); } else { if ((ask.sin_addr.s_addr=inet_addr(server_name)) == 0) { printf("Bad hostname\n"); return (-1); } } ask.sin_family = AF_INET; ask.sin_port = htons((unsigned short)server_port); #ifndef WINDOWS if ((sd=socket(PF_INET,SOCK_STREAM, 0)) < 0) #else if ((sd=socket(PF_INET,SOCK_STREAM, 0)) == INVALID_SOCKET) #endif { printf("Can't create socket\n"); return (-1); } if (connect(sd, (struct sockaddr *)&ask, sizeof(ask)) < 0) { close(sd); printf("Can't connect %s port %d\n", server_name, server_port); return (-1); } return (0); #else /* MACINTOSH */ OSStatus err; InetHostInfo response; InetHost host_addr; InetAddress inAddr; TCall sndCall; Boolean bind = false; OSStatus junk; if (read_chuukei_prf(prf_name) < 0){ printf("Wrong prf file\n"); return (-1); } init_buffer(); printf("server = %s\nport = %d\n", server_name, server_port); #if TARGET_API_MAC_CARBON err = InitOpenTransportInContext(kInitOTForApplicationMask, NULL); #else err = InitOpenTransport(); #endif memset(&response, 0, sizeof(response)); #if TARGET_API_MAC_CARBON inet_services = OTOpenInternetServicesInContext(kDefaultInternetServicesPath, 0, &err, NULL); #else inet_services = OTOpenInternetServices(kDefaultInternetServicesPath, 0, &err); #endif if (err == noErr) { err = OTInetStringToAddress(inet_services, (char *)server_name, &response); if (err == noErr) { host_addr = response.addrs[0]; } else { printf("Bad hostname\n"); } #if TARGET_API_MAC_CARBON ep = (void *)OTOpenEndpointInContext(OTCreateConfiguration(kTCPName), 0, nil, &err, NULL); #else ep = (void *)OTOpenEndpoint(OTCreateConfiguration(kTCPName), 0, nil, &err); #endif if (err == noErr) { err = OTBind(ep, nil, nil); bind = (err == noErr); } if (err == noErr){ OTInitInetAddress(&inAddr, server_port, host_addr); sndCall.addr.len = sizeof(InetAddress); sndCall.addr.buf = (unsigned char*) &inAddr; sndCall.opt.buf = nil; /* no connection options */ sndCall.opt.len = 0; sndCall.udata.buf = nil; /* no connection data */ sndCall.udata.len = 0; sndCall.sequence = 0; /* ignored by OTConnect */ err = OTConnect(ep, &sndCall, NULL); if( err != noErr ){ printf("Can't connect %s port %d\n", server_name, server_port); } } err = OTSetSynchronous(ep); if (err == noErr) err = OTSetBlocking(ep); } if( err != noErr ){ if( bind ){ OTUnbind(ep); } /* Clean up. */ if (ep != kOTInvalidEndpointRef) { OTCloseProvider(ep); ep = nil; } if (inet_services != nil) { OTCloseProvider(inet_services); inet_services = nil; } return -1; } return 0; #endif }