📄 ot_net.cp
字号:
#else theErr = InitOpenTransport();#endif if (theErr != HXR_OK) return HX_OPEN_DRIVER_ERROR; } else theErr = -1; return(theErr);} // close_drivers() should close any network drivers used by the program// NOTE: The program MUST not make any other calls to the network drivers// until init_drivers() has been calledHX_RESULTOT_net::close_drivers(void *params){ if(sHaveOT) {#ifdef _CARBON CloseOpenTransportInContext(sOToutClientContext);#else CloseOpenTransport();#endif } return(HXR_OK);} HX_RESULTOT_net::host_to_ip_str(char *host, char *ip, UINT32 ulBufLen){ HX_RESULT theErr = HXR_OK; ULONG32 addr; UINT16 port; theErr = lookup_host(host,&addr, &port); if(!theErr) OTInetHostToString(addr,ip); if(theErr) theErr = HXR_BIND; return(theErr);}ULONG32 OT_net::AddRef(){ return InterlockedIncrement(&m_lRefCount);}ULONG32 OT_net::Release(){ if (InterlockedDecrement(&m_lRefCount) > 0) { return m_lRefCount; } delete this; return 0;}HX_RESULTOT_net::lookup_host ( char *name, ULONG32 *addr, UINT16 *port, UINT16 defaultPort) { HX_RESULT theErr = HXR_OK; InetHostInfo hInfoOT; char domainName[256]; char *p, *q; OTSvcInfo svcInfo; p = name; q = domainName; while (*p != 0 && *p != ',' && *p != ' ' && *p != ':') *q++ = *p++; *q = 0; q = p; while (*q == ' ') q++; if (*q == 0) *port = defaultPort; else { p++; if (!isdigit(*p)) return HXR_BIND; q = p+1; while (isdigit(*q)) q++; while (*q == ' ') q++; if (*q != 0) return HXR_BIND; *port = atoi(p); } // check if DNS has been cached if(conn::is_cached(domainName,addr)) return HXR_OK; theErr = OTInetStringToHost(domainName, addr); if (theErr != HXR_OK) { theErr = OpenInetServices(&svcInfo); if (theErr == kEINVALErr) return HXR_BIND; if (theErr != HXR_OK) return (theErr); svcInfo.complete = false; theErr = OTInetStringToAddress(svcInfo.ref, domainName, &hInfoOT); if (theErr == HXR_OK) theErr = OTSvcWait(&svcInfo); OTCloseProvider(svcInfo.ref); if (theErr != HXR_OK) { if (theErr == kOTNoDataErr || theErr == kOTBadNameErr) theErr = HXR_BIND; return (theErr); } *addr = hInfoOT.addrs[0]; } conn::add_to_cache(domainName, *addr); return HXR_OK;}HX_RESULT OT_net::dns_find_ip_addr(const char * host, UINT16 blocking){ if(!host) { mLastError = HX_INVALID_HOST; return mLastError; }//XXXCWB// if(get_sock() < 0) // {// mLastError = HX_NET_SOCKET_INVALID;// return mLastError;// } if (conn::is_cached((char *) host, &mHostIPAddr)) { mHostIPValid = TRUE; mDNSDone = TRUE; if (mCallBack) { mCallBack->Func(DNS_NOTIFICATION, TRUE); } return( mLastError = HXR_OK); } char* pTemp = strrchr(host, '.'); if (pTemp && atoi(pTemp + 1)) { /* IP address. */ struct in_addr addr; mHostIPValid = FALSE; mHostIPAddr = 0; mDNSDone = TRUE; ::OTInetStringToHost((char*)host, &addr.s_addr); //!!!!! if ((UINT)addr.s_addr == (UINT)-1) { mLastError = HX_INVALID_HOST; if (mCallBack) { mCallBack->Func(DNS_NOTIFICATION, FALSE); } return mLastError; } mHostIPValid = TRUE; mHostIPAddr = *(ULONG32 *) &addr; conn::add_to_cache((char *) host, mHostIPAddr); if (mCallBack) { mCallBack->Func(DNS_NOTIFICATION, TRUE); } return HXR_OK; } if (blocking) { struct in_addr addr; mHostIPValid = FALSE; mHostIPAddr = 0; mDNSDone = TRUE; InetHostInfo ihost; OTSvcInfo svcInfo; OSErr theErr = OpenInetServices(&svcInfo); if (theErr == kEINVALErr) return HXR_BIND; if (theErr != HXR_OK) return (theErr); svcInfo.complete = false; ::OTInetStringToAddress(svcInfo.ref,(char*)host,&ihost); if (theErr == HXR_OK) theErr = OTSvcWait(&svcInfo); OTCloseProvider(svcInfo.ref); if (!ihost.addrs ) { mLastError = HX_INVALID_HOST; if (mCallBack) { mCallBack->Func(DNS_NOTIFICATION, FALSE); } return mLastError; } memcpy(&addr, ihost.addrs, sizeof(struct in_addr)); mHostIPValid = TRUE; mHostIPAddr = *(ULONG32 *) &addr; conn::add_to_cache((char *) host, mHostIPAddr); if (mCallBack) { mCallBack->Func(DNS_NOTIFICATION, TRUE); } return( mLastError = HXR_OK); } else // non-blocking { mDNSDone = TRUE; mHostIPValid = FALSE; mHostIPAddr = 0; HX_RESULT theErr; MyOTInfo myOTInfo; ::memset(&myOTInfo, 0, sizeof(myOTInfo)); myOTInfo.hostName = host; myOTInfo.complete = false; #ifdef _CARBON theErr = OTAsyncOpenInternetServicesInContext(kDefaultInternetServicesPath, 0, ::NewOTNotifyUPP(MyOTNotifyProc), &myOTInfo, NULL);#else theErr = OTAsyncOpenInternetServices(kDefaultInternetServicesPath, 0, MyOTNotifyProc, &myOTInfo);#endif if (theErr != HXR_OK) { return( mLastError = HXR_BIND); } // MyOTNotifyProc() handles asynch. functionality of this routine Boolean cancel = false; do { cancel = Mac_net::CheckForCancel(); } while (!myOTInfo.complete && !cancel); // Save the IP address Boolean bFound; if (myOTInfo.hostInfo.addrs && *myOTInfo.hostInfo.addrs) { bFound = true; mLastError = HXR_OK; struct in_addr addr; memcpy(&addr, myOTInfo.hostInfo.addrs, sizeof(struct in_addr)); mHostIPValid = TRUE; mHostIPAddr = *(ULONG32 *) &addr; conn::add_to_cache((char *) host, mHostIPAddr); } else { bFound = false; mLastError = HX_INVALID_HOST; } ::OTRemoveNotifier(myOTInfo.inetSvcRef); ::OTCloseProvider (myOTInfo.inetSvcRef); if (mCallBack) { mCallBack->Func(DNS_NOTIFICATION, bFound); } return(mLastError); } return FALSE;}pascal void OT_net::MyOTNotifyProc( void* contextPtr, OTEventCode code, OTResult result, void* cookie){ MyOTInfo* myOTInfoPtr = (MyOTInfo *) contextPtr; switch (code) { case T_OPENCOMPLETE: myOTInfoPtr->inetSvcRef = (InetSvcRef)cookie; ::OTInetStringToAddress(myOTInfoPtr->inetSvcRef, (char*)myOTInfoPtr->hostName, &myOTInfoPtr->hostInfo); break; case T_DNRSTRINGTOADDRCOMPLETE: case T_DNRADDRTONAMECOMPLETE: myOTInfoPtr->complete = true; break; }}BOOL OT_net::dns_ip_addr_found(BOOL * valid, ULONG32 *addr){ if (mDNSDone) { *valid = mHostIPValid; *addr = mHostIPAddr; return TRUE; } else return FALSE; return FALSE;}/***********Common code for OT_UDP/OT_TCP*************************/pascal void OT_net::UDPTCPNotifyProc ( void *stream, OTEventCode code, OTResult result, void *cookie ) { HXMM_INTERRUPTON(); OT_net* s = (OT_net*) stream;#ifdef _USE_OT_DEFER if (s->m_OTDeferredCookie != 0)#else if (s->m_DeferredTaskStruct.dtAddr != NULL)#endif { OTCallbackInfo* pOTCallbackInfo = new OTCallbackInfo(code, result, cookie); s->AddToThePendingList((void*) pOTCallbackInfo); if (!s->m_bDeferredTaskPending) { if ( !s->m_bIsQuitting ) { s->m_bDeferredTaskPending = TRUE;#ifdef _USE_OT_DEFER OTScheduleDeferredTask(s->m_OTDeferredCookie);#else DTInstall(&s->m_DeferredTaskStruct);#endif } } } HXMM_INTERRUPTOFF();}#ifdef _USE_OT_DEFERpascal void OT_net::DeferredTaskProc(void* inParam)#elsepascal void OT_net::DeferredTaskProc(long inParam)#endif{ HXMM_INTERRUPTON(); OT_net* s = (OT_net*) inParam; if(s) { if ( !s->m_bIsQuitting ) { s->ProcessPendingCallbacks(); } s->m_bDeferredTaskPending = FALSE; } HXMM_INTERRUPTOFF();}void OT_net::AddToThePendingList(void* pNode){ /* Atleast one of the list MUST be free to operate on */ HX_ASSERT(!m_bUsingListOne || !m_bUsingListTwo); if (!m_bUsingListOne) { if (!m_pPendingCallbackListOne) { m_pPendingCallbackListOne = new CHXSimpleList; } m_pPendingCallbackListOne->AddTail(pNode); } else if (!m_bUsingListTwo) { if (!m_pPendingCallbackListTwo) { m_pPendingCallbackListTwo = new CHXSimpleList; } m_pPendingCallbackListTwo->AddTail(pNode); } } void OT_net::ProcessPendingCallbacks(){start: m_bUsingListOne = TRUE; while (m_pPendingCallbackListOne && !m_pPendingCallbackListOne->IsEmpty()) { OTCallbackInfo* cmd = (OTCallbackInfo*) m_pPendingCallbackListOne->RemoveHead(); /* Send time sync for ONLY the last pending audio callback */ ProcessCmd(cmd->m_Code, cmd->m_Result, cmd->m_Cookie); delete cmd; } m_bUsingListOne = FALSE; m_bUsingListTwo = TRUE; while (m_pPendingCallbackListTwo && !m_pPendingCallbackListTwo->IsEmpty()) { OTCallbackInfo* cmd = (OTCallbackInfo*) m_pPendingCallbackListTwo->RemoveHead(); /* Send time sync for ONLY the last pending audio callback */ ProcessCmd(cmd->m_Code, cmd->m_Result, cmd->m_Cookie); delete cmd; } m_bUsingListTwo = FALSE; /* Do we still have more pending callbacks to process? */ if ((m_pPendingCallbackListOne && m_pPendingCallbackListOne->GetCount() > 0) || (m_pPendingCallbackListTwo && m_pPendingCallbackListTwo->GetCount() > 0)) { goto start; } } void OT_net::CleanupPendingLists(){ m_bUsingListOne = TRUE; while(m_pPendingCallbackListOne && !m_pPendingCallbackListOne->IsEmpty()) { SndCommand* cmd = (SndCommand*)m_pPendingCallbackListOne->RemoveHead(); delete cmd; } m_bUsingListOne = FALSE; m_bUsingListTwo = TRUE; while(m_pPendingCallbackListTwo && !m_pPendingCallbackListTwo->IsEmpty()) { SndCommand* cmd = (SndCommand*)m_pPendingCallbackListTwo->RemoveHead(); delete cmd; } m_bUsingListTwo = FALSE;}OTResult OT_net::GetFourByteOption(EndpointRef ep, OTXTILevel level, OTXTIName name, UInt32 *value){ OTResult err; TOption option; TOptMgmt request; TOptMgmt result; /* Set up the option buffer */ option.len = kOTFourByteOptionSize; option.level= level; option.name = name; option.status = 0; option.value[0] = 0;// Ignored because we're getting the value. /* Set up the request parameter for OTOptionManagement to point to the option buffer we just filled out */ request.opt.buf= (UInt8 *) &option; request.opt.len= sizeof(option); request.flags= T_CURRENT; /* Set up the reply parameter for OTOptionManagement. */ result.opt.buf = (UInt8 *) &option; result.opt.maxlen = sizeof(option); err = OTOptionManagement(ep, &request, &result); if (err == noErr) { switch (option.status) { case T_SUCCESS: case T_READONLY: *value = option.value[0]; break; default: err = option.status; break; } } return (err);}OTResult OT_net::SetFourByteOption(EndpointRef ep, OTXTILevel level, OTXTIName name, UInt32 value){ OTResult err; TOption option; TOptMgmt request; TOptMgmt result; /* Set up the option buffer */ option.len = kOTFourByteOptionSize; option.level= level; option.name = name; option.status = 0; option.value[0] = value; // set the value here /* Set up the request parameter for OTOptionManagement to point to the option buffer we just filled out */ request.opt.buf= (UInt8 *) &option; request.opt.len= sizeof(option); request.flags= T_NEGOTIATE; /* Set up the reply parameter for OTOptionManagement. */ result.opt.buf = (UInt8 *) &option; result.opt.maxlen = sizeof(option); err = OTOptionManagement(ep, &request, &result); if (err == noErr) { switch (option.status) { case T_SUCCESS: case T_READONLY: value = option.value[0]; break; default: err = option.status; break; } } return (err);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -