📄 ecostest.cpp
字号:
*d++=_TCHAR('%'); do { c++; } while (_istdigit(*c)); } *d++=*c++; } *d=_TCHAR('\0'); strFormat.ReleaseBuffer(); } _stscanf(pszStr, strFormat, &t.tm_year,&t.tm_mon,&t.tm_mday, &t.tm_hour,&t.tm_min,&t.tm_sec, // Time of day strExecutionHostPort.GetBuffer(1+nLen), // Execution host:port target.GetBuffer(1+nLen), // Target strExecutableTail.GetBuffer(1+nLen), // Executable strStatus.GetBuffer(1+nLen), // Result &nDownloadedSize,&nFileSize, // Sizes &nDownloadTime,&nDownloadTimeFrac, // Times &nDownloadTimeout,&nDownloadTimeoutFrac, &nTotalTime,&nTotalTimeFrac, &nMaxInactiveTime,&nMaxInactiveTimeFrac, &nActiveTimeout,&nActiveTimeoutFrac, strTitle.GetBuffer(1+nLen) // Title ); strExecutionHostPort.ReleaseBuffer(); target.ReleaseBuffer(); strExecutableTail.ReleaseBuffer(); strStatus.ReleaseBuffer(); strTitle.ReleaseBuffer(); status=StatusTypeValue(strStatus); LPCTSTR c1=_tcschr(pszStr,_TCHAR('"')); if(c1){ c1++; LPCTSTR c2=_tcschr(c1+1,_TCHAR('"')); if(c2){ strTitle=String(c1,c2-c1); } } nTotalTime=nTotalTime*1000+nTotalTimeFrac*100; nMaxInactiveTime=nMaxInactiveTime*1000+nMaxInactiveTimeFrac*100; nActiveTimeout=nActiveTimeout*1000+nActiveTimeoutFrac*100; nDownloadTime=nDownloadTime*1000+nDownloadTimeFrac*100; nDownloadTimeout=nDownloadTimeout*1000+nDownloadTimeoutFrac*100; nFileSize*=1024; nDownloadedSize*=1024; t.tm_year-=1900; t.tm_mon--; return t.tm_year>=0 && t.tm_year<=200 && t.tm_mon>=0 && t.tm_mon<=11 && t.tm_mday>=1 && t.tm_mday<=31 && t.tm_hour>=0 && t.tm_hour<=23 && t.tm_min>=0 && t.tm_min<=59 && t.tm_sec>=0 && t.tm_sec<=59 && status!=StatusTypeMax //&& exetype!=ExecutionParameters::ExecutableTypeMax ;} LPCTSTR const CeCosTest::ResultString(bool bIncludeOutput) const{ String strTitle(m_strTitle); String strExecutionHostPort(m_strExecutionHostPort); if(0==strTitle.GetLength()){ strTitle=CeCosTestUtils::SimpleHostName(); strTitle+=_TCHAR(':'); strTitle+=m_strExecutable; } if(0==strExecutionHostPort.GetLength()){ strExecutionHostPort=CeCosTestUtils::SimpleHostName(); strExecutionHostPort+=_T(":0"); } ENTERCRITICAL; time_t ltime; time(<ime); struct tm *now=localtime( <ime ); m_strResultString.Format( pszFormat, 1900+now->tm_year,1+now->tm_mon,now->tm_mday, now->tm_hour,now->tm_min,now->tm_sec, // Time of day (LPCTSTR )strExecutionHostPort, // Execution host:port Target(), // Target ExecutableTail(), // Executable Image(Status()), // Result m_nStrippedSize/1024,m_nFileSize/1024, // Sizes WF(m_nDownloadTime),WF(DownloadTimeout()),WF(m_nTotalTime),// Times WF(m_nMaxInactiveTime),WF(ActiveTimeout()), (LPCTSTR )strTitle // Title ); if(bIncludeOutput && m_strOutput.GetLength()>0){ m_strResultString+=_TCHAR('\n'); m_strResultString+=m_strOutput; } LEAVECRITICAL; return m_strResultString;}// Run as a server, listening on the port given as parameterbool CeCosTest::RunAgent(int nTcpPort){ bool bLocked=false; nAuxPort=nTcpPort+3000;//hack nAuxListenSock=CeCosTestSocket::Listen(nAuxPort);//hack if(-1!=nAuxListenSock){ // Create socket int nSock = CeCosTestSocket::Listen(nTcpPort); int nLastClient=0; int nRejectionCount=0; if (-1!=nSock) { for (;;) { try { CeCosTestSocket *pSock=new CeCosTestSocket(nSock); // AcceptThreadFunc deletes if not deleted below String str; // Read the execution parameters if(!pSock->recvString(str)){ // Socket error on the recv - nothing much we can do TRACE(_T("RunAgent : could not read execution parameters\n")); delete pSock; pSock=0; } else { ExecutionParameters e; e.FromStr(str); TRACE(_T("Execution parameters: %s\n"),(LPCTSTR)e.Image()); bool bNuisance=false; ServerStatus s; CTestResource *pPort=0; String strInfo; if(!e.IsValid()){ // Looks like a confused client ... strInfo.Format(_T("Bad target value %s read from client\n"),e.Target()); s=SERVER_CANT_RUN; } else if(0==CTestResource::Count(e)){ // No chance of running this test strInfo.Format(_T("Cannot run a %s test from this server\n"),e.Target()); s=SERVER_CANT_RUN; } else { switch(e.Request()) { case ExecutionParameters::LOCK: if(bLocked){ s=SERVER_BUSY; } else { WaitForAllInstances(1000,NOTIMEOUT); bLocked=true; s=SERVER_LOCKED; } break; case ExecutionParameters::UNLOCK: if(bLocked){ bLocked=false; s=SERVER_READY; } else { s=SERVER_BUSY; } break; case ExecutionParameters::QUERY: if (bLocked) { s=SERVER_LOCKED; } else { pPort=CTestResource::GetResource(e); if(0==pPort){ s=SERVER_BUSY; strInfo.Format(_T("serving %s"),(LPCTSTR )CeCosTestSocket::ClientName(nLastClient)); } else { s=SERVER_READY; pPort->Release(); pPort=0; } } break; case ExecutionParameters::RUN: if (bLocked) { s=SERVER_LOCKED; } else { pPort=CTestResource::GetResource(e); if(0==pPort){ // We must disappoint our client nRejectionCount++; strInfo.Format(_T("serving %s"),(LPCTSTR )CeCosTestSocket::ClientName(nLastClient)); s=SERVER_BUSY; /* } else if(nLastClient==pSock->Client() && nRejectionCount>10) { // Don't answer the phone to a nuisance caller s=SERVER_BUSY; bNuisance=true; nRejectionCount--; pPort->Release(); pPort=0; */ } else { s=SERVER_READY; nRejectionCount=0; nLastClient=pSock->Client(); } } break; case ExecutionParameters::STOP: s=SERVER_READY; break; default: s=SERVER_CANT_RUN; } } #ifndef VERBOSE if(ExecutionParameters::QUERY!=e.Request())#endif TRACE(_T("RunAgent : %s request tActive=%d tElapsed=%d Target=%s Reply status=%s %s Nuisance=%d\n"), e.Image(e.Request()), e.ActiveTimeout(),e.DownloadTimeout(),e.Target(), Image(s), (LPCTSTR )strInfo, bNuisance); bool bSendok=pSock->sendInteger(s) && pSock->sendString(strInfo); TRACE(_T("RunAgent(1)\n")); if(SERVER_READY==s && bSendok && ExecutionParameters::RUN==e.Request()){ // Create a new class instance // AcceptThreadFunc deletes the instance and closes new_sock // RunLocal, called by AcceptThreadFunc, releases the port // We dream up a temporary name for the executable // No need for meaningful callback, but must run asynchronously String strTempFile; ENTERCRITICAL; strTempFile.Format(_T("%s-%s-%d"),_ttmpnam(0),e.Target(),nTcpPort); LEAVECRITICAL; CeCosTest *pTest=new CeCosTest(e,strTempFile); pTest->m_pSock=pSock; pTest->m_strExecutionHostPort.Format(_T("%s:%d"),CeCosTestUtils::HostName(),nTcpPort); pTest->m_pPort=pPort; CeCosThreadUtils::RunThread(SAcceptThreadFunc,pTest,_T("SAcceptThreadFunc")); // AcceptThreadFunc deletes pSock } else { TRACE(_T("RunAgent(2)\n")); delete pSock; pSock=0; if(pPort){ pPort->Release(); pPort=0; } TRACE(_T("RunAgent(3)\n")); if(CeCosTest::ExecutionParameters::STOP==e.Request()){ CancelAllInstances(); WaitForAllInstances(1000,20*1000); break; } } } } catch(...){ TRACE(_T("!!! Exception caught in RunAgent()\n")); } } CeCosTestSocket::CloseSocket (nSock); } VTRACE(_T("RunAgent(): returning false\n")); CeCosTestSocket::CloseSocket(nAuxListenSock); } return false;}CeCosTest::StatusType CeCosTest::StatusTypeValue(LPCTSTR pszStr){ for(int i=0;i<StatusTypeMax;i++){ StatusType t=(StatusType)i; if(0==_tcsicmp(Image(t),pszStr)){ return t; } } return StatusTypeMax;}// Thread to run ConnectSocketToSerialvoid CeCosTest::ConnectSocketToSerialThreadFunc(){ TRACE(_T("ConnectSocketToSerialThreadFunc sock=%d\n"),nAuxListenSock); { CeCosTestSerialFilter serial_filter; CeCosTestSocket::FilterFunc *serial_filter_function = &SerialFilterFunction; CeCosTestDownloadFilter download_filter; CeCosTestSocket::FilterFunc *download_filter_function = &DownloadFilterFunction; bool accept_connection = true; CeCosTestSerial serial; serial.SetBlockingReads(false); bool rc=false; // Open serial device. if (!serial.Open(m_pPort->Serial(),m_pPort->Baud())){ ERROR(_T("Couldn't open port %s\n"),m_pPort->Serial()); } else { while(accept_connection) { // Flush the serial buffer. serial.Flush(); TRACE(_T("ConnectSocketToSerial: waiting for connection...\n")); CeCosTestSocket socket; if(!socket.Accept(nAuxListenSock,&m_bStopConnectSocketToSerial)){ ERROR(_T("ConnectSocketToSerial - couldn't accept\n")); break; } else if (m_pSock->Client() != socket.Client()){ // Make sure the client is who we think it is... TRACE(_T("ConnectSocketToSerialThread - illegal connection attempted from %s\n"),(LPCTSTR )socket.ClientName(socket.Client())); } else { try { rc=CeCosTestSocket::ConnectSocketToSerial(socket,serial,m_ep.m_bUseFilter?serial_filter_function:NULL, (void*)&serial_filter, m_ep.m_bUseFilter?download_filter_function:NULL, (void*)&download_filter, &m_bStopConnectSocketToSerial); // If the download filter was just active, it may // allow the session to continue. accept_connection = download_filter.ContinueSession(); } catch (LPCTSTR pszMsg){ Log(_T("!!! ConnectSocketToSerial exception caught: %s!!!\n"),pszMsg); rc=false; break; } catch (...){ Log(_T("!!! ConnectSocketToSerial exception caught!!!\n")); rc=false; break; } } } } TRACE(_T("ConnectSocketToSerial : done\n")); }}static bool CALLBACK DerefBool(void *pParam){ return *(bool *)pParam;}// Function called (on a separate thread) to process a successful connection to the RunAgent loopvoid CeCosTest::AcceptThreadFunc(){ SetPath(m_strPath); if(ServerSideGdb()){ int n; if(m_pSock->recvInteger(n,_T("file size"))){ m_nFileSize=n; // Read file from the socket bool bCanRun=true; TRACE(_T("AcceptThreadFunc file size=%d reading...\n"),m_nFileSize); FILE *f2; f2=_tfopen(m_strExecutable,_T("wb")); if(0==f2){ Log(_T("Could not create %s - %s\n"),(LPCTSTR )m_strExecutable,strerror(errno)); bCanRun=false; } unsigned int nBufSize=MIN(100000,m_nFileSize); Buffer b(nBufSize); unsigned int nWritten=0; unsigned int nRead=0; while(nRead<m_nFileSize){ int nToRead=MIN(nBufSize,m_nFileSize-nRead); if(!recv( b.Data(), nToRead, _T("executable"))){ break; } nRead+=nToRead; if(0!=f2){ char *c=(char *)b.Data(); while(nToRead>0){ int w=fwrite(c,1,nToRead,f2); if(-1==w){ Log(_T("Write error on %s - %s\n"),(LPCTSTR )m_strExecutable,strerror(errno)); bCanRun=false; break; } nWritten+=w; c+=w; nToRead-=w; } } } TRACE(_T("Accept - done reading [%d bytes read, %d bytes written]\n"),nRead,nWritten); if(0!=f2){ fclose(f2); _tchmod(m_strExecutable,00700); // user read, write and execute } if(0!=f2 && m_nFileSize!=nWritten){ Log(_T("Failed to create %s correctly [%d/%d bytes written]\n"),(LPCTSTR )m_strExecutable, nWritten, m_nFileSize); bCanRun=false; } SetExecutable(m_strExecutable); // to set stripped length and title RunLocal(); _tunlink(m_strExecutable); } sendResult(); m_pSock->recvInteger(n); // receive an ack } else { bool bTargetReady; if(_TCHAR('\0')==*(m_pPort->ResetString())){ bTargetReady=true; TRACE(_T("No reset possible\n")); } else {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -