// // // Copyright 1997,1999 Perforce Software. All rights reserved. // // This file is part of Perforce - the FAST SCM System. // // // Cmd_Fstat.cpp #include "stdafx.h" #include "p4win.h" #include "cmd_fstat.h" #include "tokenstring.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif // don't confuse these. different case // const CString g_sClientViewOnly = _T("-C"); const CString g_sChangeList = _T("-c"); const CString g_sChangeList_e = _T("-e"); const CString g_sMaxOutput = _T("-m"); IMPLEMENT_DYNCREATE(CCmd_Fstat, CP4Command) CCmd_Fstat::CCmd_Fstat(CGuiClient *client) : CP4Command(client) { m_ReplyMsg= WM_P4FSTAT; m_TaskName= _T("Fstat"); m_pBatch= NULL; m_IncludeAddedFiles = m_bWorking = FALSE; } CCmd_Fstat::~CCmd_Fstat() { if(m_pBatch != NULL) delete m_pBatch; } BOOL CCmd_Fstat::Run( BOOL suppress, LPCTSTR spec, BOOL bShowEntireDepot, long minChange) { m_SpecList.RemoveAll(); m_SpecList.AddHead( spec ); return Run( suppress, &m_SpecList, bShowEntireDepot, minChange ); } BOOL CCmd_Fstat::Run(BOOL suppress, CStringList *specList, BOOL bShowEntireDepot, long minChange/*=0*/, BOOL bWorking/*=FALSE*/, long wkChgNbr/*=-1*/, long maxOutput/*=0*/) { ASSERT_KINDOF( CStringList, specList ); ASSERT( specList->GetCount() ); ClearArgs(); m_BaseArgs= AddArg(_T("fstat")); if(GET_SERVERLEVEL() >= 19) // 2005.1 or later? { m_BaseArgs= AddArg(_T("-Ol")); m_BaseArgs= AddArg(_T("-Oh")); if (bWorking) { m_bWorking = TRUE; m_BaseArgs= AddArg(_T("-Ro")); if (wkChgNbr != -1) { AddArg( g_sChangeList_e ); if (!wkChgNbr) m_BaseArgs= AddArg(_T("default")); else m_BaseArgs= AddArg(wkChgNbr); } } } else if (bWorking) { ASSERT(0); return FALSE; } if(suppress) m_BaseArgs= AddArg(_T("-s")); if(minChange > 0) { AddArg( g_sChangeList ); m_BaseArgs= AddArg(minChange); } if ( ! bShowEntireDepot && GET_SERVERLEVEL() > 3 ) m_BaseArgs= AddArg ( g_sClientViewOnly ); if ( maxOutput && GET_SERVERLEVEL() > 20 ) { if (maxOutput == -1) m_IgnorePermissionErrs = TRUE; else { m_BaseArgs= AddArg ( g_sMaxOutput ); m_BaseArgs= AddArg ( maxOutput ); if (maxOutput == 1) m_IgnorePermissionErrs = TRUE; } } m_pBatch= new CObList; m_posStrListIn= specList->GetHeadPosition(); m_pStrListIn= specList; // Put the first few files into the arg list NextListArgs(); return CP4Command::Run(); } BOOL CCmd_Fstat::HandledCmdSpecificError(LPCTSTR errBuf, LPCTSTR errMsg) { if ((StrStr(errBuf, _T(" - file(s) not in client view"))) || (StrStr(errBuf, _T(" - protected namespace - access denied"))) || (m_bWorking && StrStr(errBuf, _T(" - file(s) not opened on this client")))) { return TRUE; } else if ((GET_P4REGPTR( )->ShowEntireDepot( ) > SDF_DEPOT) && (StrStr(errBuf, _T(" - no mappings in client view")))) { m_ErrorList.AddHead(errBuf); return TRUE; } else if ( StrStr(errBuf, _T("no such file") ) ) { TheApp()->StatusAdd( LoadStringResource(IDS_NO_FILES_UNDER_FOLDER), SV_DEBUG ); return TRUE ; } else if ( StrStr(errBuf, _T(" database access failed.") ) ) { m_FatalError = TRUE; return FALSE; } return StrStr(errBuf, _T("up-to-date.") ) != 0; } void CCmd_Fstat::OnOutputStat( StrDict *varList ) { // Check for possible abort request if(APP_ABORTING()) { ReleaseServerLock(); ExitThread(0); } else { CP4FileStats *stats= new CP4FileStats; if(stats->Create(varList)) AddFstatRow(stats); else delete stats; } } void CCmd_Fstat::AddFstatRow(CP4FileStats *stats) { // Files open by other users for add or new integ arent reported by fstat, but files open // for add or new branch by this client are, so suppress them - they arent in the depot yet if( !m_IncludeAddedFiles && (stats->GetMyOpenAction() == F_ADD || stats->GetMyOpenAction() == F_BRANCH) && stats->GetHeadRev() == 0 ) { delete stats; return; } // Note: GUI should work this list from head to tail to preserve order m_pBatch->AddTail(stats); if(!m_IsChildTask && m_pBatch->GetCount() > 49) { // Send a full batch to gui if ( m_ReplyWnd ) { // First get a this ptr and the list into a suitable wrapper CFstatWrapper *pWrap= new CFstatWrapper; pWrap->pCmd= this; pWrap->pList= m_pBatch; ::PostMessage(m_ReplyWnd, m_ReplyMsg, (WPARAM) pWrap, -1 ); m_pBatch= new CObList; } } } void CCmd_Fstat::PostProcess() { if(!m_IsChildTask && m_pBatch->GetCount() > 0) { // Send a partial batch to gui (and only if there's a window to receive it) if ( m_ReplyWnd ) { // First get a this ptr and the list into a suitable wrapper CFstatWrapper *pWrap= new CFstatWrapper; pWrap->pCmd= this; pWrap->pList= m_pBatch; ::PostMessage(m_ReplyWnd, m_ReplyMsg, (WPARAM) pWrap, -1 ); m_pBatch= NULL; } } } /* _________________________________________________________________ use this when running fstat synchronously, since we cant post messages, etc. _________________________________________________________________ */ CObList *CCmd_Fstat::GetFileList( ) { return m_pBatch; }