Expanded exception handling for file operations during a check, plus some refactoring & cleanup
This commit is contained in:
parent
7af2781a19
commit
e653e83058
|
@ -42,7 +42,6 @@
|
||||||
#include "fsdatasourceiter.h"
|
#include "fsdatasourceiter.h"
|
||||||
#include "fco/fcodatasourceiter.h"
|
#include "fco/fcodatasourceiter.h"
|
||||||
#include "fsobject.h"
|
#include "fsobject.h"
|
||||||
#include "core/fsservices.h"
|
|
||||||
#include "core/errorbucket.h"
|
#include "core/errorbucket.h"
|
||||||
#include "core/corestrings.h"
|
#include "core/corestrings.h"
|
||||||
#include "core/usernotify.h"
|
#include "core/usernotify.h"
|
||||||
|
@ -99,6 +98,12 @@ static bool gCrossFileSystems = false;
|
||||||
gCrossFileSystems = crossFS;
|
gCrossFileSystems = crossFS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void cFSDataSourceIter::AddIterationError(const eError& e)
|
||||||
|
{
|
||||||
|
if(mpErrorBucket)
|
||||||
|
mpErrorBucket->AddError(e);
|
||||||
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
// CreateCopy
|
// CreateCopy
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -151,15 +156,42 @@ void cFSDataSourceIter::GetChildrenNames( const TSTRING& strParentName, std::vec
|
||||||
}
|
}
|
||||||
catch( eError& e )
|
catch( eError& e )
|
||||||
{
|
{
|
||||||
cDebug d("cFSDataSourceIter::GeneratePeers");
|
AddIterationError( eFSDataSourceIterReadDir( strParentName, e.GetMsg(), eError::NON_FATAL) );
|
||||||
d.TraceError("**** ReadDir failed for %s\n", strParentName.c_str() );
|
|
||||||
|
|
||||||
if( mpErrorBucket )
|
|
||||||
{
|
|
||||||
eFSDataSourceIterReadDir eReadDir(e.GetMsg(), eError::NON_FATAL);
|
|
||||||
mpErrorBucket->AddError( eReadDir );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
catch( std::exception& e )
|
||||||
|
{
|
||||||
|
AddIterationError( eFSDataSourceIterReadDir( strParentName, e.what(), eError::NON_FATAL) );
|
||||||
|
}
|
||||||
|
catch(...)
|
||||||
|
{
|
||||||
|
AddIterationError( eFSDataSourceIterReadDir( strParentName, "unknown", eError::NON_FATAL) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool cFSDataSourceIter::DoStat( const TSTRING& name, cFSStatArgs& statArgs )
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
iFSServices::GetInstance()->Stat( name, statArgs);
|
||||||
|
}
|
||||||
|
catch(eError& e)
|
||||||
|
{
|
||||||
|
e.SetFatality(false);
|
||||||
|
AddIterationError(e);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
catch(std::exception& e)
|
||||||
|
{
|
||||||
|
AddIterationError( eFSDataSourceIter( name, e.what(), eError::NON_FATAL) );
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
catch(...)
|
||||||
|
{
|
||||||
|
AddIterationError( eFSDataSourceIter( name, "unknown", eError::NON_FATAL) );
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -173,30 +205,15 @@ bool cFSDataSourceIter::InitializeTypeInfo(iFCO* pFCO)
|
||||||
if( pObj->GetFSPropSet().GetValidVector().ContainsItem( cFSPropSet::PROP_FILETYPE) )
|
if( pObj->GetFSPropSet().GetValidVector().ContainsItem( cFSPropSet::PROP_FILETYPE) )
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
//
|
|
||||||
// assume invalid by default...
|
// assume invalid by default...
|
||||||
//
|
//
|
||||||
cFSPropSet& propSet = pObj->GetFSPropSet();
|
cFSPropSet& propSet = pObj->GetFSPropSet();
|
||||||
propSet.SetFileType(cFSPropSet::FT_INVALID);
|
propSet.SetFileType(cFSPropSet::FT_INVALID);
|
||||||
|
|
||||||
cFSStatArgs statArgs;
|
cFSStatArgs statArgs;
|
||||||
try
|
if( !DoStat( pObj->GetName().AsString(), statArgs ))
|
||||||
{
|
|
||||||
iFSServices::GetInstance()->Stat( pTrans->ToStringAPI( pObj->GetName() ), statArgs);
|
|
||||||
}
|
|
||||||
catch(eError& e)
|
|
||||||
{
|
|
||||||
cDebug d("CreateObject");
|
|
||||||
d.TraceError( "*** Stat of %s failed!!!\n", pObj->GetName().AsString().c_str() );
|
|
||||||
if( mpErrorBucket )
|
|
||||||
{
|
|
||||||
e.SetFatality( false );
|
|
||||||
mpErrorBucket->AddError( e );
|
|
||||||
}
|
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// don't create the object if it is on a different file system...
|
// don't create the object if it is on a different file system...
|
||||||
//
|
//
|
||||||
if( gCrossFileSystems == false && (mDev != 0) && (statArgs.dev != mDev) )
|
if( gCrossFileSystems == false && (mDev != 0) && (statArgs.dev != mDev) )
|
||||||
|
|
|
@ -39,9 +39,11 @@
|
||||||
// INCLUDES
|
// INCLUDES
|
||||||
//=========================================================================
|
//=========================================================================
|
||||||
#include "fco/fcodatasourceiterimpl.h"
|
#include "fco/fcodatasourceiterimpl.h"
|
||||||
|
#include "core/fileerror.h"
|
||||||
|
#include "core/fsservices.h"
|
||||||
|
|
||||||
TSS_EXCEPTION( eFSDataSourceIter, eError )
|
TSS_FILE_EXCEPTION( eFSDataSourceIter, eFileError )
|
||||||
TSS_EXCEPTION( eFSDataSourceIterReadDir, eFSDataSourceIter )
|
TSS_FILE_EXCEPTION( eFSDataSourceIterReadDir, eFSDataSourceIter )
|
||||||
|
|
||||||
|
|
||||||
//=========================================================================
|
//=========================================================================
|
||||||
|
@ -83,6 +85,9 @@ private:
|
||||||
|
|
||||||
virtual iFCO* CreateObject(const cFCOName& name, bool bCreatingPeers );
|
virtual iFCO* CreateObject(const cFCOName& name, bool bCreatingPeers );
|
||||||
virtual bool InitializeTypeInfo(iFCO* pFCO) ;
|
virtual bool InitializeTypeInfo(iFCO* pFCO) ;
|
||||||
|
|
||||||
|
void AddIterationError(const eError& e);
|
||||||
|
bool DoStat(const TSTRING& name, cFSStatArgs& statArgs);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //__FSDATASOURCEITER_H
|
#endif //__FSDATASOURCEITER_H
|
||||||
|
|
|
@ -43,7 +43,7 @@
|
||||||
|
|
||||||
TSS_BEGIN_ERROR_REGISTRATION( fs )
|
TSS_BEGIN_ERROR_REGISTRATION( fs )
|
||||||
|
|
||||||
TSS_REGISTER_ERROR( eFSPropCalc(), _T("NTFS property calculation error.") )
|
TSS_REGISTER_ERROR( eFSPropCalc(), _T("Property calculation error.") )
|
||||||
//TSS_REGISTER_ERROR( eFSPropCalcResetAccessTime(), _T("Could not reset access time for file.") )
|
//TSS_REGISTER_ERROR( eFSPropCalcResetAccessTime(), _T("Could not reset access time for file.") )
|
||||||
TSS_REGISTER_ERROR( eFSDataSourceIter(), _T("Data source iterator error.") )
|
TSS_REGISTER_ERROR( eFSDataSourceIter(), _T("Data source iterator error.") )
|
||||||
TSS_REGISTER_ERROR( eFSDataSourceIterReadDir(), _T("Could not access directory contents.") )
|
TSS_REGISTER_ERROR( eFSDataSourceIterReadDir(), _T("Could not access directory contents.") )
|
||||||
|
|
|
@ -35,13 +35,10 @@
|
||||||
#include "stdfs.h"
|
#include "stdfs.h"
|
||||||
#include "core/debug.h"
|
#include "core/debug.h"
|
||||||
#include "core/errorbucket.h"
|
#include "core/errorbucket.h"
|
||||||
#include "core/fsservices.h"
|
|
||||||
#include "core/errorbucket.h"
|
#include "core/errorbucket.h"
|
||||||
#include "fco/fconame.h"
|
#include "fco/fconame.h"
|
||||||
#include "fco/fconametranslator.h"
|
#include "fco/fconametranslator.h"
|
||||||
#include "fco/twfactory.h"
|
#include "fco/twfactory.h"
|
||||||
#include "core/archive.h"
|
|
||||||
|
|
||||||
#include "fspropcalc.h"
|
#include "fspropcalc.h"
|
||||||
#include "fsobject.h"
|
#include "fsobject.h"
|
||||||
|
|
||||||
|
@ -88,17 +85,15 @@ static bool NeedsStat(const cFCOPropVector& v)
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
static bool GetSymLinkStr(const cFCOName& fileName, cArchive& arch)
|
static bool GetSymLinkStr(const TSTRING& strName, cArchive& arch)
|
||||||
{
|
{
|
||||||
char buf[1024];
|
char buf[1024]; // TODO: is this big enough?
|
||||||
#if defined(O_PATH)
|
#if defined(O_PATH)
|
||||||
int fd = open(iTWFactory::GetInstance()->GetNameTranslator()->ToStringAPI( fileName ).c_str(),
|
int fd = open(strName.c_str(), (O_PATH | O_NOFOLLOW | O_NOATIME));
|
||||||
(O_PATH | O_NOFOLLOW | O_NOATIME));
|
|
||||||
int rtn = readlinkat(fd, 0, buf, 1024);
|
int rtn = readlinkat(fd, 0, buf, 1024);
|
||||||
close(fd);
|
close(fd);
|
||||||
#else
|
#else
|
||||||
int rtn = readlink( iTWFactory::GetInstance()->GetNameTranslator()->ToStringAPI( fileName ).c_str(),
|
int rtn = readlink( strName.c_str(), buf, 1024 );
|
||||||
buf, 1024 );
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if(rtn == -1)
|
if(rtn == -1)
|
||||||
|
@ -110,127 +105,154 @@ static bool GetSymLinkStr(const cFCOName& fileName, cArchive& arch)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void cFSPropCalc::AddPropCalcError(const eError& e)
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
// VisitFSObject -- this is the workhorse method that actually fills out the
|
|
||||||
// passed in FSObject' properties
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
void cFSPropCalc::VisitFSObject(cFSObject& obj)
|
|
||||||
{
|
{
|
||||||
cDebug d("cFSPropCalc::VisitFSObject");
|
if(mpErrorBucket)
|
||||||
d.TraceDetail(_T("Visiting %s\n"), obj.GetName().AsString().c_str());
|
mpErrorBucket->AddError(e);
|
||||||
|
}
|
||||||
|
|
||||||
// if we are not in overwrite mode, we need to alter the
|
bool cFSPropCalc::DoStat( const TSTRING& strName, cFSStatArgs& statArgs )
|
||||||
// properties we are calculating...
|
{
|
||||||
cFCOPropVector propsToCheck(mPropVector);
|
cDebug d("cFSPropCalc::DoStat");
|
||||||
if(mCollAction == iFCOPropCalc::PROP_LEAVE)
|
|
||||||
{
|
|
||||||
cFCOPropVector inBoth = propsToCheck;
|
|
||||||
inBoth &= obj.GetPropSet()->GetValidVector();
|
|
||||||
propsToCheck ^= inBoth;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef _DEBUG
|
|
||||||
d.TraceDetail("----->Collision Action = %s\n", mCollAction == iFCOPropCalc::PROP_LEAVE ? "Leave" : "Replace");
|
|
||||||
d.TraceDetail("----->Object's valid properties (a):\n");
|
|
||||||
obj.GetPropSet()->GetValidVector().TraceContents(cDebug::D_DETAIL);
|
|
||||||
d.TraceDetail("----->Properties to calculate: (b)\n");
|
|
||||||
mPropVector.TraceContents(cDebug::D_DETAIL);
|
|
||||||
d.TraceDetail("----->Properties to change in object ((a&b)^b for Leave or b for Replace):\n");
|
|
||||||
propsToCheck.TraceContents(cDebug::D_DETAIL);
|
|
||||||
#endif //_DEBUG
|
|
||||||
|
|
||||||
// only do the stat() if it is necessary
|
|
||||||
iFSServices* pFSServices = iFSServices::GetInstance();
|
|
||||||
cFSStatArgs ss;
|
|
||||||
bool bDidStat = false;
|
|
||||||
TSTRING strName = iTWFactory::GetInstance()->GetNameTranslator()->ToStringAPI( obj.GetName() );
|
|
||||||
|
|
||||||
// get a reference to the fco's property set
|
|
||||||
cFSPropSet& propSet = obj.GetFSPropSet();
|
|
||||||
|
|
||||||
//
|
|
||||||
// just return if this object is invalid
|
|
||||||
//
|
|
||||||
if( propSet.GetFileType() == cFSPropSet::FT_INVALID )
|
|
||||||
return;
|
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if( NeedsStat(propsToCheck) )
|
d.TraceDetail("---Performing Stat()\n");
|
||||||
{
|
iFSServices::GetInstance()->Stat(strName, statArgs);
|
||||||
d.TraceDetail("---Performing Stat()\n");
|
|
||||||
pFSServices->Stat(strName, ss);
|
|
||||||
bDidStat = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
catch(eError& e)
|
catch(eError& e)
|
||||||
{
|
{
|
||||||
d.TraceError("Error getting stat info for %s : %s\n", strName.c_str(), e.GetMsg().c_str());
|
d.TraceError("Error getting stat info for %s : %s\n", strName.c_str(), e.GetMsg().c_str());
|
||||||
|
e.SetFatality(false);
|
||||||
// add this fco to the error set...
|
AddPropCalcError(e);
|
||||||
// it is assumed that the file name that the error is associated with is in the exception's
|
return false;
|
||||||
// GetMsg()
|
}
|
||||||
e.SetFatality( false );
|
catch(std::exception& e)
|
||||||
if(mpErrorBucket)
|
{
|
||||||
mpErrorBucket->AddError( e );
|
d.TraceError("Error getting stat info for %s : %s\n", strName.c_str(), e.what());
|
||||||
return;
|
AddPropCalcError( eFSPropCalc( strName, e.what(), eError::NON_FATAL ) );
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
catch(...)
|
||||||
|
{
|
||||||
|
d.TraceError("Unknown error getting stat info for %s\n", strName.c_str());
|
||||||
|
AddPropCalcError( eFSPropCalc( strName, "unknown", eError::NON_FATAL ) );
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// for now, I will only fill out the stat info indicated in the property vector,
|
return true;
|
||||||
// but in reality, there is no reason not to fill out everything, since we have the
|
}
|
||||||
// extra information for free!
|
|
||||||
if(bDidStat)
|
bool cFSPropCalc::DoOpen( const TSTRING& strName, cFileArchive& arch )
|
||||||
|
{
|
||||||
|
try
|
||||||
{
|
{
|
||||||
if(propsToCheck.ContainsItem(cFSPropSet::PROP_DEV))
|
arch.OpenRead(strName.c_str(), ((mCalcFlags & iFCOPropCalc::DIRECT_IO) ?
|
||||||
propSet.SetDev(ss.dev);
|
cFileArchive::FA_SCANNING | cFileArchive::FA_DIRECT :
|
||||||
|
cFileArchive::FA_SCANNING) );
|
||||||
|
}
|
||||||
|
catch (eError&)
|
||||||
|
{
|
||||||
|
AddPropCalcError( eArchiveOpen( strName, iFSServices::GetInstance()->GetErrString(), eError::NON_FATAL));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
catch (std::exception& e)
|
||||||
|
{
|
||||||
|
AddPropCalcError( eArchiveOpen( strName, e.what(), eError::NON_FATAL ) );
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
AddPropCalcError( eArchiveOpen( strName, "unknown", eError::NON_FATAL ) );
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if(propsToCheck.ContainsItem(cFSPropSet::PROP_RDEV))
|
return true;
|
||||||
propSet.SetRDev(ss.rdev);
|
}
|
||||||
|
|
||||||
if(propsToCheck.ContainsItem(cFSPropSet::PROP_INODE))
|
bool cFSPropCalc::DoHash( const TSTRING& strName, cBidirArchive* pTheArch, cArchiveSigGen& asg, cFileArchive& arch )
|
||||||
propSet.SetInode(ss.ino);
|
{
|
||||||
|
cDebug d("cFSPropCalc::DoHash");
|
||||||
|
try
|
||||||
|
{
|
||||||
|
pTheArch->Seek( 0, cBidirArchive::BEGINNING );
|
||||||
|
asg.CalculateSignatures( *pTheArch );
|
||||||
|
arch.Close();
|
||||||
|
}
|
||||||
|
catch (eError& e)
|
||||||
|
{
|
||||||
|
d.TraceError("Error generating hashes for %s : %s\n", strName.c_str(), e.GetMsg().c_str());
|
||||||
|
e.SetFatality(false);
|
||||||
|
AddPropCalcError(e);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
catch (std::exception& e)
|
||||||
|
{
|
||||||
|
d.TraceError("Error generating hashes for %s : %s\n", strName.c_str(), e.what());
|
||||||
|
AddPropCalcError( eArchiveRead( strName, e.what(), eError::NON_FATAL ) );
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
d.TraceError("Unknown error generating hashes for %s\n", strName.c_str());
|
||||||
|
AddPropCalcError( eArchiveRead( strName, "unknown", eError::NON_FATAL ) );
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if(propsToCheck.ContainsItem(cFSPropSet::PROP_MODE))
|
return true;
|
||||||
propSet.SetMode(ss.mode);
|
}
|
||||||
|
|
||||||
if(propsToCheck.ContainsItem(cFSPropSet::PROP_NLINK))
|
void cFSPropCalc::HandleStatProperties( const cFCOPropVector& propsToCheck, const cFSStatArgs& ss, cFSPropSet& propSet)
|
||||||
propSet.SetNLink(ss.nlink);
|
{
|
||||||
|
if(propsToCheck.ContainsItem(cFSPropSet::PROP_DEV))
|
||||||
|
propSet.SetDev(ss.dev);
|
||||||
|
|
||||||
if(propsToCheck.ContainsItem(cFSPropSet::PROP_UID))
|
if(propsToCheck.ContainsItem(cFSPropSet::PROP_RDEV))
|
||||||
propSet.SetUID(ss.uid);
|
propSet.SetRDev(ss.rdev);
|
||||||
|
|
||||||
if(propsToCheck.ContainsItem(cFSPropSet::PROP_GID))
|
if(propsToCheck.ContainsItem(cFSPropSet::PROP_INODE))
|
||||||
propSet.SetGID(ss.gid);
|
propSet.SetInode(ss.ino);
|
||||||
|
|
||||||
if(propsToCheck.ContainsItem(cFSPropSet::PROP_SIZE))
|
if(propsToCheck.ContainsItem(cFSPropSet::PROP_MODE))
|
||||||
propSet.SetSize(ss.size);
|
propSet.SetMode(ss.mode);
|
||||||
|
|
||||||
if(propsToCheck.ContainsItem(cFSPropSet::PROP_ATIME))
|
if(propsToCheck.ContainsItem(cFSPropSet::PROP_NLINK))
|
||||||
propSet.SetAccessTime(ss.atime);
|
propSet.SetNLink(ss.nlink);
|
||||||
|
|
||||||
if(propsToCheck.ContainsItem(cFSPropSet::PROP_MTIME))
|
if(propsToCheck.ContainsItem(cFSPropSet::PROP_UID))
|
||||||
propSet.SetModifyTime(ss.mtime);
|
propSet.SetUID(ss.uid);
|
||||||
|
|
||||||
if(propsToCheck.ContainsItem(cFSPropSet::PROP_CTIME))
|
if(propsToCheck.ContainsItem(cFSPropSet::PROP_GID))
|
||||||
propSet.SetCreateTime(ss.ctime);
|
propSet.SetGID(ss.gid);
|
||||||
|
|
||||||
if(propsToCheck.ContainsItem(cFSPropSet::PROP_BLOCK_SIZE))
|
if(propsToCheck.ContainsItem(cFSPropSet::PROP_SIZE))
|
||||||
propSet.SetBlockSize(ss.blksize);
|
propSet.SetSize(ss.size);
|
||||||
|
|
||||||
if(propsToCheck.ContainsItem(cFSPropSet::PROP_BLOCKS))
|
if(propsToCheck.ContainsItem(cFSPropSet::PROP_ATIME))
|
||||||
propSet.SetBlocks(ss.blocks);
|
propSet.SetAccessTime(ss.atime);
|
||||||
|
|
||||||
if(propsToCheck.ContainsItem(cFSPropSet::PROP_GROWING_FILE))
|
if(propsToCheck.ContainsItem(cFSPropSet::PROP_MTIME))
|
||||||
propSet.SetGrowingFile(ss.size);
|
propSet.SetModifyTime(ss.mtime);
|
||||||
|
|
||||||
if(propsToCheck.ContainsItem(cFSPropSet::PROP_FILETYPE))
|
if(propsToCheck.ContainsItem(cFSPropSet::PROP_CTIME))
|
||||||
|
propSet.SetCreateTime(ss.ctime);
|
||||||
|
|
||||||
|
if(propsToCheck.ContainsItem(cFSPropSet::PROP_BLOCK_SIZE))
|
||||||
|
propSet.SetBlockSize(ss.blksize);
|
||||||
|
|
||||||
|
if(propsToCheck.ContainsItem(cFSPropSet::PROP_BLOCKS))
|
||||||
|
propSet.SetBlocks(ss.blocks);
|
||||||
|
|
||||||
|
if(propsToCheck.ContainsItem(cFSPropSet::PROP_GROWING_FILE))
|
||||||
|
propSet.SetGrowingFile(ss.size);
|
||||||
|
|
||||||
|
if(propsToCheck.ContainsItem(cFSPropSet::PROP_FILETYPE))
|
||||||
|
{
|
||||||
|
// TODO -- It _really_ bites duplicating code here and in fsdatasource.cpp
|
||||||
|
// *** This _has_ to be remedied somehow!
|
||||||
|
// set the file type
|
||||||
|
switch(ss.mFileType)
|
||||||
{
|
{
|
||||||
// TODO -- It _really_ bites duplicating code here and in fsdatasource.cpp
|
|
||||||
// *** This _has_ to be remedied somehow!
|
|
||||||
// set the file type
|
|
||||||
switch(ss.mFileType)
|
|
||||||
{
|
|
||||||
case cFSStatArgs::TY_FILE:
|
case cFSStatArgs::TY_FILE:
|
||||||
propSet.SetFileType(cFSPropSet::FT_FILE);
|
propSet.SetFileType(cFSPropSet::FT_FILE);
|
||||||
break;
|
break;
|
||||||
|
@ -261,10 +283,12 @@ void cFSPropCalc::VisitFSObject(cFSObject& obj)
|
||||||
default:
|
default:
|
||||||
// set it to invalid
|
// set it to invalid
|
||||||
propSet.SetFileType(cFSPropSet::FT_INVALID);
|
propSet.SetFileType(cFSPropSet::FT_INVALID);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void cFSPropCalc::HandleHashes( const cFCOPropVector& propsToCheck, const TSTRING& strName, cFSPropSet& propSet)
|
||||||
|
{
|
||||||
bool hash_success = false;
|
bool hash_success = false;
|
||||||
|
|
||||||
// if the file type is not a regular file, we will
|
// if the file type is not a regular file, we will
|
||||||
|
@ -273,11 +297,11 @@ void cFSPropCalc::VisitFSObject(cFSObject& obj)
|
||||||
if( propSet.GetFileType() == cFSPropSet::FT_FILE || propSet.GetFileType() == cFSPropSet::FT_SYMLINK )
|
if( propSet.GetFileType() == cFSPropSet::FT_FILE || propSet.GetFileType() == cFSPropSet::FT_SYMLINK )
|
||||||
{
|
{
|
||||||
if( // if we need to open the file
|
if( // if we need to open the file
|
||||||
propsToCheck.ContainsItem(cFSPropSet::PROP_CRC32) ||
|
propsToCheck.ContainsItem(cFSPropSet::PROP_CRC32) ||
|
||||||
propsToCheck.ContainsItem(cFSPropSet::PROP_MD5) ||
|
propsToCheck.ContainsItem(cFSPropSet::PROP_MD5) ||
|
||||||
propsToCheck.ContainsItem(cFSPropSet::PROP_SHA) ||
|
propsToCheck.ContainsItem(cFSPropSet::PROP_SHA) ||
|
||||||
propsToCheck.ContainsItem(cFSPropSet::PROP_HAVAL)
|
propsToCheck.ContainsItem(cFSPropSet::PROP_HAVAL)
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
cFileArchive arch;
|
cFileArchive arch;
|
||||||
cMemoryArchive memArch;
|
cMemoryArchive memArch;
|
||||||
|
@ -287,31 +311,17 @@ void cFSPropCalc::VisitFSObject(cFSObject& obj)
|
||||||
if(propSet.GetFileType() == cFSPropSet::FT_SYMLINK)
|
if(propSet.GetFileType() == cFSPropSet::FT_SYMLINK)
|
||||||
{
|
{
|
||||||
pTheArch = &memArch;
|
pTheArch = &memArch;
|
||||||
if(! GetSymLinkStr(obj.GetName(), memArch))
|
if(! GetSymLinkStr(strName, memArch))
|
||||||
{
|
{
|
||||||
// add it to the bucket...
|
// add it to the bucket...
|
||||||
if(mpErrorBucket)
|
AddPropCalcError( eArchiveOpen( strName, iFSServices::GetInstance()->GetErrString(), eError::NON_FATAL ) );
|
||||||
mpErrorBucket->AddError( eArchiveOpen( strName, iFSServices::GetInstance()->GetErrString(), eError::NON_FATAL ) );
|
|
||||||
hash_success = false;
|
hash_success = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
pTheArch = &arch;
|
pTheArch = &arch;
|
||||||
try
|
hash_success = DoOpen(strName, arch);
|
||||||
{
|
|
||||||
arch.OpenRead(strName.c_str(), ((mCalcFlags & iFCOPropCalc::DIRECT_IO) ?
|
|
||||||
cFileArchive::FA_SCANNING | cFileArchive::FA_DIRECT :
|
|
||||||
cFileArchive::FA_SCANNING) );
|
|
||||||
}
|
|
||||||
catch (eError&)
|
|
||||||
{
|
|
||||||
// add it to the bucket...
|
|
||||||
if(mpErrorBucket)
|
|
||||||
mpErrorBucket->AddError( eArchiveOpen( strName, iFSServices::GetInstance()->GetErrString(), eError::NON_FATAL ) );
|
|
||||||
hash_success = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -348,21 +358,7 @@ void cFSPropCalc::VisitFSObject(cFSObject& obj)
|
||||||
//
|
//
|
||||||
// calculate the signatures
|
// calculate the signatures
|
||||||
//
|
//
|
||||||
try
|
hash_success = DoHash(strName, pTheArch, asg, arch);
|
||||||
{
|
|
||||||
pTheArch->Seek( 0, cBidirArchive::BEGINNING );
|
|
||||||
asg.CalculateSignatures( *pTheArch );
|
|
||||||
arch.Close();
|
|
||||||
}
|
|
||||||
catch (eError& e)
|
|
||||||
{
|
|
||||||
d.TraceError("Error generating hashes for %s : %s\n", strName.c_str(), e.GetMsg().c_str());
|
|
||||||
|
|
||||||
e.SetFatality(false);
|
|
||||||
if(mpErrorBucket)
|
|
||||||
mpErrorBucket->AddError(e);
|
|
||||||
hash_success = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -384,6 +380,59 @@ void cFSPropCalc::VisitFSObject(cFSObject& obj)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
// VisitFSObject -- this is the workhorse method that actually fills out the
|
||||||
|
// passed in FSObject' properties
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
void cFSPropCalc::VisitFSObject(cFSObject& obj)
|
||||||
|
{
|
||||||
|
cDebug d("cFSPropCalc::VisitFSObject");
|
||||||
|
d.TraceDetail(_T("Visiting %s\n"), obj.GetName().AsString().c_str());
|
||||||
|
|
||||||
|
// if we are not in overwrite mode, we need to alter the
|
||||||
|
// properties we are calculating...
|
||||||
|
cFCOPropVector propsToCheck(mPropVector);
|
||||||
|
if(mCollAction == iFCOPropCalc::PROP_LEAVE)
|
||||||
|
{
|
||||||
|
cFCOPropVector inBoth = propsToCheck;
|
||||||
|
inBoth &= obj.GetPropSet()->GetValidVector();
|
||||||
|
propsToCheck ^= inBoth;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef _DEBUG
|
||||||
|
d.TraceDetail("----->Collision Action = %s\n", mCollAction == iFCOPropCalc::PROP_LEAVE ? "Leave" : "Replace");
|
||||||
|
d.TraceDetail("----->Object's valid properties (a):\n");
|
||||||
|
obj.GetPropSet()->GetValidVector().TraceContents(cDebug::D_DETAIL);
|
||||||
|
d.TraceDetail("----->Properties to calculate: (b)\n");
|
||||||
|
mPropVector.TraceContents(cDebug::D_DETAIL);
|
||||||
|
d.TraceDetail("----->Properties to change in object ((a&b)^b for Leave or b for Replace):\n");
|
||||||
|
propsToCheck.TraceContents(cDebug::D_DETAIL);
|
||||||
|
#endif //_DEBUG
|
||||||
|
|
||||||
|
// only do the stat() if it is necessary
|
||||||
|
cFSStatArgs ss;
|
||||||
|
TSTRING strName = iTWFactory::GetInstance()->GetNameTranslator()->ToStringAPI( obj.GetName() );
|
||||||
|
|
||||||
|
// get a reference to the fco's property set
|
||||||
|
cFSPropSet& propSet = obj.GetFSPropSet();
|
||||||
|
|
||||||
|
//
|
||||||
|
// just return if this object is invalid
|
||||||
|
//
|
||||||
|
if( propSet.GetFileType() == cFSPropSet::FT_INVALID )
|
||||||
|
return;
|
||||||
|
|
||||||
|
if( NeedsStat(propsToCheck) )
|
||||||
|
{
|
||||||
|
if (!DoStat(strName, ss))
|
||||||
|
return;
|
||||||
|
|
||||||
|
HandleStatProperties(propsToCheck, ss, propSet);
|
||||||
|
}
|
||||||
|
|
||||||
|
HandleHashes(propsToCheck, strName, propSet);
|
||||||
|
}
|
||||||
|
|
||||||
void cFSPropCalc::SetPropVector(const cFCOPropVector& pv)
|
void cFSPropCalc::SetPropVector(const cFCOPropVector& pv)
|
||||||
{
|
{
|
||||||
mPropVector = pv;
|
mPropVector = pv;
|
||||||
|
|
|
@ -47,7 +47,13 @@
|
||||||
#include "fco/fcopropvector.h"
|
#include "fco/fcopropvector.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
TSS_EXCEPTION( eFSPropCalc, eError )
|
#include "fco/signature.h"
|
||||||
|
#include "core/fileerror.h"
|
||||||
|
#include "core/fsservices.h"
|
||||||
|
#include "core/archive.h"
|
||||||
|
#include "fspropset.h"
|
||||||
|
|
||||||
|
TSS_FILE_EXCEPTION( eFSPropCalc, eFileError )
|
||||||
//TSS_EXCEPTION( eFSPropCalcResetAccessTime, eFSPropCalc ) // this was never used
|
//TSS_EXCEPTION( eFSPropCalcResetAccessTime, eFSPropCalc ) // this was never used
|
||||||
|
|
||||||
class cFSPropCalc : public iFCOPropCalc, public iFSVisitor
|
class cFSPropCalc : public iFCOPropCalc, public iFSVisitor
|
||||||
|
@ -78,6 +84,14 @@ private:
|
||||||
cFSPropCalc( const cFSPropCalc& );
|
cFSPropCalc( const cFSPropCalc& );
|
||||||
void operator =( const cFSPropCalc& );
|
void operator =( const cFSPropCalc& );
|
||||||
|
|
||||||
|
void AddPropCalcError(const eError& e);
|
||||||
|
|
||||||
|
bool DoStat(const TSTRING& name, cFSStatArgs& statArgs);
|
||||||
|
bool DoOpen(const TSTRING& name, cFileArchive& arch);
|
||||||
|
bool DoHash( const TSTRING& name, cBidirArchive* pTheArch, cArchiveSigGen& asg, cFileArchive& arch );
|
||||||
|
void HandleStatProperties( const cFCOPropVector& propsToCheck, const cFSStatArgs& ss, cFSPropSet& propSet);
|
||||||
|
void HandleHashes( const cFCOPropVector& propsToCheck, const TSTRING& strName, cFSPropSet& propSet);
|
||||||
|
|
||||||
cFCOPropVector mPropVector;
|
cFCOPropVector mPropVector;
|
||||||
iFCOPropCalc::CollisionAction mCollAction;
|
iFCOPropCalc::CollisionAction mCollAction;
|
||||||
int mCalcFlags;
|
int mCalcFlags;
|
||||||
|
|
Loading…
Reference in New Issue