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 "fco/fcodatasourceiter.h"
|
||||
#include "fsobject.h"
|
||||
#include "core/fsservices.h"
|
||||
#include "core/errorbucket.h"
|
||||
#include "core/corestrings.h"
|
||||
#include "core/usernotify.h"
|
||||
|
@ -99,6 +98,12 @@ static bool gCrossFileSystems = false;
|
|||
gCrossFileSystems = crossFS;
|
||||
}
|
||||
|
||||
void cFSDataSourceIter::AddIterationError(const eError& e)
|
||||
{
|
||||
if(mpErrorBucket)
|
||||
mpErrorBucket->AddError(e);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// CreateCopy
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -151,15 +156,42 @@ void cFSDataSourceIter::GetChildrenNames( const TSTRING& strParentName, std::vec
|
|||
}
|
||||
catch( eError& e )
|
||||
{
|
||||
cDebug d("cFSDataSourceIter::GeneratePeers");
|
||||
d.TraceError("**** ReadDir failed for %s\n", strParentName.c_str() );
|
||||
|
||||
if( mpErrorBucket )
|
||||
{
|
||||
eFSDataSourceIterReadDir eReadDir(e.GetMsg(), eError::NON_FATAL);
|
||||
mpErrorBucket->AddError( eReadDir );
|
||||
}
|
||||
AddIterationError( eFSDataSourceIterReadDir( strParentName, e.GetMsg(), eError::NON_FATAL) );
|
||||
}
|
||||
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) )
|
||||
return true;
|
||||
|
||||
//
|
||||
// assume invalid by default...
|
||||
//
|
||||
cFSPropSet& propSet = pObj->GetFSPropSet();
|
||||
propSet.SetFileType(cFSPropSet::FT_INVALID);
|
||||
|
||||
cFSStatArgs statArgs;
|
||||
try
|
||||
{
|
||||
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 );
|
||||
}
|
||||
if( !DoStat( pObj->GetName().AsString(), statArgs ))
|
||||
return false;
|
||||
}
|
||||
|
||||
//
|
||||
// don't create the object if it is on a different file system...
|
||||
//
|
||||
if( gCrossFileSystems == false && (mDev != 0) && (statArgs.dev != mDev) )
|
||||
|
|
|
@ -39,9 +39,11 @@
|
|||
// INCLUDES
|
||||
//=========================================================================
|
||||
#include "fco/fcodatasourceiterimpl.h"
|
||||
#include "core/fileerror.h"
|
||||
#include "core/fsservices.h"
|
||||
|
||||
TSS_EXCEPTION( eFSDataSourceIter, eError )
|
||||
TSS_EXCEPTION( eFSDataSourceIterReadDir, eFSDataSourceIter )
|
||||
TSS_FILE_EXCEPTION( eFSDataSourceIter, eFileError )
|
||||
TSS_FILE_EXCEPTION( eFSDataSourceIterReadDir, eFSDataSourceIter )
|
||||
|
||||
|
||||
//=========================================================================
|
||||
|
@ -83,6 +85,9 @@ private:
|
|||
|
||||
virtual iFCO* CreateObject(const cFCOName& name, bool bCreatingPeers );
|
||||
virtual bool InitializeTypeInfo(iFCO* pFCO) ;
|
||||
|
||||
void AddIterationError(const eError& e);
|
||||
bool DoStat(const TSTRING& name, cFSStatArgs& statArgs);
|
||||
};
|
||||
|
||||
#endif //__FSDATASOURCEITER_H
|
||||
|
|
|
@ -43,7 +43,7 @@
|
|||
|
||||
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( eFSDataSourceIter(), _T("Data source iterator error.") )
|
||||
TSS_REGISTER_ERROR( eFSDataSourceIterReadDir(), _T("Could not access directory contents.") )
|
||||
|
|
|
@ -35,13 +35,10 @@
|
|||
#include "stdfs.h"
|
||||
#include "core/debug.h"
|
||||
#include "core/errorbucket.h"
|
||||
#include "core/fsservices.h"
|
||||
#include "core/errorbucket.h"
|
||||
#include "fco/fconame.h"
|
||||
#include "fco/fconametranslator.h"
|
||||
#include "fco/twfactory.h"
|
||||
#include "core/archive.h"
|
||||
|
||||
#include "fspropcalc.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)
|
||||
int fd = open(iTWFactory::GetInstance()->GetNameTranslator()->ToStringAPI( fileName ).c_str(),
|
||||
(O_PATH | O_NOFOLLOW | O_NOATIME));
|
||||
int fd = open(strName.c_str(), (O_PATH | O_NOFOLLOW | O_NOATIME));
|
||||
int rtn = readlinkat(fd, 0, buf, 1024);
|
||||
close(fd);
|
||||
#else
|
||||
int rtn = readlink( iTWFactory::GetInstance()->GetNameTranslator()->ToStringAPI( fileName ).c_str(),
|
||||
buf, 1024 );
|
||||
int rtn = readlink( strName.c_str(), buf, 1024 );
|
||||
#endif
|
||||
|
||||
if(rtn == -1)
|
||||
|
@ -110,127 +105,154 @@ static bool GetSymLinkStr(const cFCOName& fileName, cArchive& arch)
|
|||
return true;
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// VisitFSObject -- this is the workhorse method that actually fills out the
|
||||
// passed in FSObject' properties
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
void cFSPropCalc::VisitFSObject(cFSObject& obj)
|
||||
void cFSPropCalc::AddPropCalcError(const eError& e)
|
||||
{
|
||||
cDebug d("cFSPropCalc::VisitFSObject");
|
||||
d.TraceDetail(_T("Visiting %s\n"), obj.GetName().AsString().c_str());
|
||||
if(mpErrorBucket)
|
||||
mpErrorBucket->AddError(e);
|
||||
}
|
||||
|
||||
// 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
|
||||
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();
|
||||
bool cFSPropCalc::DoStat( const TSTRING& strName, cFSStatArgs& statArgs )
|
||||
{
|
||||
cDebug d("cFSPropCalc::DoStat");
|
||||
|
||||
//
|
||||
// just return if this object is invalid
|
||||
//
|
||||
if( propSet.GetFileType() == cFSPropSet::FT_INVALID )
|
||||
return;
|
||||
|
||||
try
|
||||
{
|
||||
if( NeedsStat(propsToCheck) )
|
||||
{
|
||||
d.TraceDetail("---Performing Stat()\n");
|
||||
pFSServices->Stat(strName, ss);
|
||||
bDidStat = true;
|
||||
}
|
||||
d.TraceDetail("---Performing Stat()\n");
|
||||
iFSServices::GetInstance()->Stat(strName, statArgs);
|
||||
}
|
||||
catch(eError& e)
|
||||
{
|
||||
d.TraceError("Error getting stat info for %s : %s\n", strName.c_str(), e.GetMsg().c_str());
|
||||
|
||||
// add this fco to the error set...
|
||||
// it is assumed that the file name that the error is associated with is in the exception's
|
||||
// GetMsg()
|
||||
e.SetFatality( false );
|
||||
if(mpErrorBucket)
|
||||
mpErrorBucket->AddError( e );
|
||||
return;
|
||||
e.SetFatality(false);
|
||||
AddPropCalcError(e);
|
||||
return false;
|
||||
}
|
||||
catch(std::exception& e)
|
||||
{
|
||||
d.TraceError("Error getting stat info for %s : %s\n", strName.c_str(), e.what());
|
||||
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,
|
||||
// but in reality, there is no reason not to fill out everything, since we have the
|
||||
// extra information for free!
|
||||
if(bDidStat)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool cFSPropCalc::DoOpen( const TSTRING& strName, cFileArchive& arch )
|
||||
{
|
||||
try
|
||||
{
|
||||
if(propsToCheck.ContainsItem(cFSPropSet::PROP_DEV))
|
||||
propSet.SetDev(ss.dev);
|
||||
|
||||
if(propsToCheck.ContainsItem(cFSPropSet::PROP_RDEV))
|
||||
propSet.SetRDev(ss.rdev);
|
||||
arch.OpenRead(strName.c_str(), ((mCalcFlags & iFCOPropCalc::DIRECT_IO) ?
|
||||
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_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);
|
||||
return true;
|
||||
}
|
||||
|
||||
if(propsToCheck.ContainsItem(cFSPropSet::PROP_BLOCK_SIZE))
|
||||
propSet.SetBlockSize(ss.blksize);
|
||||
|
||||
if(propsToCheck.ContainsItem(cFSPropSet::PROP_BLOCKS))
|
||||
propSet.SetBlocks(ss.blocks);
|
||||
bool cFSPropCalc::DoHash( const TSTRING& strName, cBidirArchive* pTheArch, cArchiveSigGen& asg, cFileArchive& arch )
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
if(propsToCheck.ContainsItem(cFSPropSet::PROP_GROWING_FILE))
|
||||
propSet.SetGrowingFile(ss.size);
|
||||
void cFSPropCalc::HandleStatProperties( const cFCOPropVector& propsToCheck, const cFSStatArgs& ss, cFSPropSet& propSet)
|
||||
{
|
||||
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:
|
||||
propSet.SetFileType(cFSPropSet::FT_FILE);
|
||||
break;
|
||||
|
@ -261,10 +283,12 @@ void cFSPropCalc::VisitFSObject(cFSObject& obj)
|
|||
default:
|
||||
// set it to invalid
|
||||
propSet.SetFileType(cFSPropSet::FT_INVALID);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void cFSPropCalc::HandleHashes( const cFCOPropVector& propsToCheck, const TSTRING& strName, cFSPropSet& propSet)
|
||||
{
|
||||
bool hash_success = false;
|
||||
|
||||
// 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( // if we need to open the file
|
||||
propsToCheck.ContainsItem(cFSPropSet::PROP_CRC32) ||
|
||||
propsToCheck.ContainsItem(cFSPropSet::PROP_MD5) ||
|
||||
propsToCheck.ContainsItem(cFSPropSet::PROP_SHA) ||
|
||||
propsToCheck.ContainsItem(cFSPropSet::PROP_HAVAL)
|
||||
)
|
||||
propsToCheck.ContainsItem(cFSPropSet::PROP_CRC32) ||
|
||||
propsToCheck.ContainsItem(cFSPropSet::PROP_MD5) ||
|
||||
propsToCheck.ContainsItem(cFSPropSet::PROP_SHA) ||
|
||||
propsToCheck.ContainsItem(cFSPropSet::PROP_HAVAL)
|
||||
)
|
||||
{
|
||||
cFileArchive arch;
|
||||
cMemoryArchive memArch;
|
||||
cBidirArchive* pTheArch;
|
||||
cBidirArchive* pTheArch;
|
||||
hash_success = true;
|
||||
|
||||
if(propSet.GetFileType() == cFSPropSet::FT_SYMLINK)
|
||||
{
|
||||
pTheArch = &memArch;
|
||||
if(! GetSymLinkStr(obj.GetName(), memArch))
|
||||
if(! GetSymLinkStr(strName, memArch))
|
||||
{
|
||||
// add it to the bucket...
|
||||
if(mpErrorBucket)
|
||||
mpErrorBucket->AddError( eArchiveOpen( strName, iFSServices::GetInstance()->GetErrString(), eError::NON_FATAL ) );
|
||||
AddPropCalcError( eArchiveOpen( strName, iFSServices::GetInstance()->GetErrString(), eError::NON_FATAL ) );
|
||||
hash_success = false;
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
pTheArch = &arch;
|
||||
try
|
||||
{
|
||||
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;
|
||||
}
|
||||
hash_success = DoOpen(strName, arch);
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -326,43 +336,29 @@ void cFSPropCalc::VisitFSObject(cFSObject& obj)
|
|||
propSet.SetDefinedCRC32(true);
|
||||
asg.AddSig( propSet.GetCRC32() );
|
||||
}
|
||||
|
||||
|
||||
if(propsToCheck.ContainsItem(cFSPropSet::PROP_MD5))
|
||||
{
|
||||
propSet.SetDefinedMD5(true);
|
||||
asg.AddSig( propSet.GetMD5() );
|
||||
}
|
||||
|
||||
|
||||
if(propsToCheck.ContainsItem(cFSPropSet::PROP_SHA))
|
||||
{
|
||||
propSet.SetDefinedSHA(true);
|
||||
asg.AddSig( propSet.GetSHA() );
|
||||
}
|
||||
|
||||
|
||||
if(propsToCheck.ContainsItem(cFSPropSet::PROP_HAVAL))
|
||||
{
|
||||
propSet.SetDefinedHAVAL(true);
|
||||
asg.AddSig( propSet.GetHAVAL() );
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// calculate the signatures
|
||||
//
|
||||
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);
|
||||
if(mpErrorBucket)
|
||||
mpErrorBucket->AddError(e);
|
||||
hash_success = false;
|
||||
}
|
||||
hash_success = DoHash(strName, pTheArch, asg, arch);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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)
|
||||
{
|
||||
mPropVector = pv;
|
||||
|
|
|
@ -47,7 +47,13 @@
|
|||
#include "fco/fcopropvector.h"
|
||||
#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
|
||||
|
||||
class cFSPropCalc : public iFCOPropCalc, public iFSVisitor
|
||||
|
@ -78,6 +84,14 @@ private:
|
|||
cFSPropCalc( 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;
|
||||
iFCOPropCalc::CollisionAction mCollAction;
|
||||
int mCalcFlags;
|
||||
|
|
Loading…
Reference in New Issue