Expanded exception handling for file operations during a check, plus some refactoring & cleanup

This commit is contained in:
Brian Cox 2017-04-11 21:23:25 -07:00
parent 7af2781a19
commit e653e83058
5 changed files with 271 additions and 186 deletions

View File

@ -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) )

View File

@ -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

View File

@ -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.") )

View File

@ -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) );
if(propsToCheck.ContainsItem(cFSPropSet::PROP_RDEV)) }
propSet.SetRDev(ss.rdev); 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_INODE)) return true;
propSet.SetInode(ss.ino); }
if(propsToCheck.ContainsItem(cFSPropSet::PROP_MODE))
propSet.SetMode(ss.mode);
if(propsToCheck.ContainsItem(cFSPropSet::PROP_NLINK))
propSet.SetNLink(ss.nlink);
if(propsToCheck.ContainsItem(cFSPropSet::PROP_UID))
propSet.SetUID(ss.uid);
if(propsToCheck.ContainsItem(cFSPropSet::PROP_GID))
propSet.SetGID(ss.gid);
if(propsToCheck.ContainsItem(cFSPropSet::PROP_SIZE))
propSet.SetSize(ss.size);
if(propsToCheck.ContainsItem(cFSPropSet::PROP_ATIME))
propSet.SetAccessTime(ss.atime);
if(propsToCheck.ContainsItem(cFSPropSet::PROP_MTIME))
propSet.SetModifyTime(ss.mtime);
if(propsToCheck.ContainsItem(cFSPropSet::PROP_CTIME))
propSet.SetCreateTime(ss.ctime);
if(propsToCheck.ContainsItem(cFSPropSet::PROP_BLOCK_SIZE)) bool cFSPropCalc::DoHash( const TSTRING& strName, cBidirArchive* pTheArch, cArchiveSigGen& asg, cFileArchive& arch )
propSet.SetBlockSize(ss.blksize); {
cDebug d("cFSPropCalc::DoHash");
if(propsToCheck.ContainsItem(cFSPropSet::PROP_BLOCKS)) try
propSet.SetBlocks(ss.blocks); {
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;
}
return true;
}
if(propsToCheck.ContainsItem(cFSPropSet::PROP_GROWING_FILE)) void cFSPropCalc::HandleStatProperties( const cFCOPropVector& propsToCheck, const cFSStatArgs& ss, cFSPropSet& propSet)
propSet.SetGrowingFile(ss.size); {
if(propsToCheck.ContainsItem(cFSPropSet::PROP_DEV))
propSet.SetDev(ss.dev);
if(propsToCheck.ContainsItem(cFSPropSet::PROP_FILETYPE)) if(propsToCheck.ContainsItem(cFSPropSet::PROP_RDEV))
propSet.SetRDev(ss.rdev);
if(propsToCheck.ContainsItem(cFSPropSet::PROP_INODE))
propSet.SetInode(ss.ino);
if(propsToCheck.ContainsItem(cFSPropSet::PROP_MODE))
propSet.SetMode(ss.mode);
if(propsToCheck.ContainsItem(cFSPropSet::PROP_NLINK))
propSet.SetNLink(ss.nlink);
if(propsToCheck.ContainsItem(cFSPropSet::PROP_UID))
propSet.SetUID(ss.uid);
if(propsToCheck.ContainsItem(cFSPropSet::PROP_GID))
propSet.SetGID(ss.gid);
if(propsToCheck.ContainsItem(cFSPropSet::PROP_SIZE))
propSet.SetSize(ss.size);
if(propsToCheck.ContainsItem(cFSPropSet::PROP_ATIME))
propSet.SetAccessTime(ss.atime);
if(propsToCheck.ContainsItem(cFSPropSet::PROP_MTIME))
propSet.SetModifyTime(ss.mtime);
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,45 +297,31 @@ 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;
cBidirArchive* pTheArch; cBidirArchive* pTheArch;
hash_success = true; hash_success = true;
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;
}
} }
// //
@ -326,43 +336,29 @@ void cFSPropCalc::VisitFSObject(cFSObject& obj)
propSet.SetDefinedCRC32(true); propSet.SetDefinedCRC32(true);
asg.AddSig( propSet.GetCRC32() ); asg.AddSig( propSet.GetCRC32() );
} }
if(propsToCheck.ContainsItem(cFSPropSet::PROP_MD5)) if(propsToCheck.ContainsItem(cFSPropSet::PROP_MD5))
{ {
propSet.SetDefinedMD5(true); propSet.SetDefinedMD5(true);
asg.AddSig( propSet.GetMD5() ); asg.AddSig( propSet.GetMD5() );
} }
if(propsToCheck.ContainsItem(cFSPropSet::PROP_SHA)) if(propsToCheck.ContainsItem(cFSPropSet::PROP_SHA))
{ {
propSet.SetDefinedSHA(true); propSet.SetDefinedSHA(true);
asg.AddSig( propSet.GetSHA() ); asg.AddSig( propSet.GetSHA() );
} }
if(propsToCheck.ContainsItem(cFSPropSet::PROP_HAVAL)) if(propsToCheck.ContainsItem(cFSPropSet::PROP_HAVAL))
{ {
propSet.SetDefinedHAVAL(true); propSet.SetDefinedHAVAL(true);
asg.AddSig( propSet.GetHAVAL() ); asg.AddSig( propSet.GetHAVAL() );
} }
// //
// 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;

View File

@ -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;