123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277 |
- //---------------------------------------------------------------------------
- #include <WinPCH.h>
- #pragma hdrstop
- #include <RemoteFiles.h>
- #include <Terminal.h>
- #include <DiscMon.hpp>
- #include "SynchronizeController.h"
- //---------------------------------------------------------------------------
- __fastcall TSynchronizeController::TSynchronizeController(
- TSynchronizeEvent AOnSynchronize, TSynchronizeInvalidEvent AOnSynchronizeInvalid,
- TSynchronizeTooManyDirectories AOnTooManyDirectories)
- {
- FOnSynchronize = AOnSynchronize;
- FOnSynchronizeInvalid = AOnSynchronizeInvalid;
- FOnTooManyDirectories = AOnTooManyDirectories;
- FSynchronizeMonitor = NULL;
- FSynchronizeAbort = NULL;
- FSynchronizeLog = NULL;
- FOptions = NULL;
- }
- //---------------------------------------------------------------------------
- __fastcall TSynchronizeController::~TSynchronizeController()
- {
- DebugAssert(FSynchronizeMonitor == NULL);
- }
- //---------------------------------------------------------------------------
- void __fastcall TSynchronizeController::StartStop(TObject * Sender,
- bool Start, const TSynchronizeParamType & Params, const TCopyParamType & CopyParam,
- TSynchronizeOptions * Options,
- TSynchronizeAbortEvent OnAbort, TSynchronizeThreadsEvent OnSynchronizeThreads,
- TSynchronizeLog OnSynchronizeLog)
- {
- if (Start)
- {
- Configuration->Usage->Inc(L"KeepUpToDates");
- try
- {
- DebugAssert(OnSynchronizeLog != NULL);
- FSynchronizeLog = OnSynchronizeLog;
- FOptions = Options;
- if (FLAGSET(Params.Options, soSynchronize) &&
- (FOnSynchronize != NULL))
- {
- FOnSynchronize(this, Params.LocalDirectory,
- Params.RemoteDirectory, CopyParam,
- Params, NULL, FOptions, true);
- }
- FCopyParam = CopyParam;
- FCopyParam.IncludeFileMask.SetRoots(Params.LocalDirectory, Params.RemoteDirectory);
- FSynchronizeParams = Params;
- DebugAssert(OnAbort);
- FSynchronizeAbort = OnAbort;
- if (FLAGSET(FSynchronizeParams.Options, soRecurse))
- {
- SynchronizeLog(slScan,
- FMTLOAD(SYNCHRONIZE_SCAN, (FSynchronizeParams.LocalDirectory)));
- }
- FSynchronizeMonitor = new TDiscMonitor(dynamic_cast<TComponent*>(Sender));
- FSynchronizeMonitor->SubTree = false;
- TMonitorFilters Filters;
- Filters << moFilename << moLastWrite;
- if (FLAGSET(FSynchronizeParams.Options, soRecurse))
- {
- Filters << moDirName;
- }
- FSynchronizeMonitor->Filters = Filters;
- FSynchronizeMonitor->MaxDirectories = 0;
- FSynchronizeMonitor->ChangeDelay = GUIConfiguration->KeepUpToDateChangeDelay;
- FSynchronizeMonitor->OnTooManyDirectories = SynchronizeTooManyDirectories;
- FSynchronizeMonitor->OnDirectoriesChange = SynchronizeDirectoriesChange;
- FSynchronizeMonitor->OnFilter = SynchronizeFilter;
- FSynchronizeMonitor->AddDirectory(FSynchronizeParams.LocalDirectory,
- FLAGSET(FSynchronizeParams.Options, soRecurse));
- FSynchronizeMonitor->OnChange = SynchronizeChange;
- FSynchronizeMonitor->OnInvalid = SynchronizeInvalid;
- FSynchronizeMonitor->OnSynchronize = OnSynchronizeThreads;
- // get count before open to avoid thread issues
- int Directories = FSynchronizeMonitor->Directories->Count;
- FSynchronizeMonitor->Open();
- SynchronizeLog(slStart, FMTLOAD(SYNCHRONIZE_START, (Directories)));
- }
- catch(...)
- {
- SAFE_DESTROY(FSynchronizeMonitor);
- throw;
- }
- }
- else
- {
- FOptions = NULL;
- SAFE_DESTROY(FSynchronizeMonitor);
- }
- }
- //---------------------------------------------------------------------------
- void __fastcall TSynchronizeController::SynchronizeChange(
- TObject * /*Sender*/, const UnicodeString Directory, bool & SubdirsChanged)
- {
- try
- {
- UnicodeString RemoteDirectory;
- UnicodeString RootLocalDirectory;
- RootLocalDirectory = IncludeTrailingBackslash(FSynchronizeParams.LocalDirectory);
- RemoteDirectory = UnixIncludeTrailingBackslash(FSynchronizeParams.RemoteDirectory);
- UnicodeString LocalDirectory = IncludeTrailingBackslash(Directory);
- DebugAssert(LocalDirectory.SubString(1, RootLocalDirectory.Length()) ==
- RootLocalDirectory);
- RemoteDirectory = RemoteDirectory +
- ToUnixPath(LocalDirectory.SubString(RootLocalDirectory.Length() + 1,
- LocalDirectory.Length() - RootLocalDirectory.Length()));
- SynchronizeLog(slChange, FMTLOAD(SYNCHRONIZE_CHANGE,
- (ExcludeTrailingBackslash(LocalDirectory))));
- if (FOnSynchronize != NULL)
- {
- TSynchronizeOptions DefaultOptions; // Just as a container for the Files field
- // this is completely wrong as the options structure
- // can contain non-root specific options in future
- TSynchronizeOptions * Options =
- ((LocalDirectory == RootLocalDirectory) ? FOptions : &DefaultOptions);
- TSynchronizeChecklist * Checklist = NULL;
- FOnSynchronize(this, LocalDirectory, RemoteDirectory, FCopyParam,
- FSynchronizeParams, &Checklist, Options, false);
- if (Checklist != NULL)
- {
- try
- {
- if (FLAGSET(FSynchronizeParams.Options, soRecurse))
- {
- SubdirsChanged = false;
- DebugAssert(Checklist != NULL);
- for (int Index = 0; Index < Checklist->Count; Index++)
- {
- const TSynchronizeChecklist::TItem * Item = Checklist->Item[Index];
- // note that there may be action saDeleteRemote even if nothing has changed
- // so this is sub-optimal
- if (Item->IsDirectory)
- {
- if ((Item->Action == TSynchronizeChecklist::saUploadNew) ||
- (Item->Action == TSynchronizeChecklist::saDeleteRemote))
- {
- SubdirsChanged = true;
- break;
- }
- else
- {
- DebugFail();
- }
- }
- }
- }
- else
- {
- SubdirsChanged = false;
- }
- }
- __finally
- {
- delete Checklist;
- }
- }
- }
- }
- catch(Exception & E)
- {
- SynchronizeAbort(dynamic_cast<EFatal*>(&E) != NULL);
- }
- }
- //---------------------------------------------------------------------------
- void __fastcall TSynchronizeController::SynchronizeAbort(bool Close)
- {
- if (FSynchronizeMonitor != NULL)
- {
- FSynchronizeMonitor->Close();
- }
- DebugAssert(FSynchronizeAbort);
- FSynchronizeAbort(NULL, Close);
- }
- //---------------------------------------------------------------------------
- void __fastcall TSynchronizeController::LogOperation(TSynchronizeOperation Operation,
- const UnicodeString FileName)
- {
- TSynchronizeLogEntry Entry;
- UnicodeString Message;
- switch (Operation)
- {
- case soDelete:
- Entry = slDelete;
- Message = FMTLOAD(SYNCHRONIZE_DELETED, (FileName));
- break;
- default:
- DebugFail();
- // fallthru
- case soUpload:
- Entry = slUpload;
- Message = FMTLOAD(SYNCHRONIZE_UPLOADED, (FileName));
- break;
- }
- SynchronizeLog(Entry, Message);
- }
- //---------------------------------------------------------------------------
- void __fastcall TSynchronizeController::SynchronizeLog(TSynchronizeLogEntry Entry,
- const UnicodeString Message)
- {
- if (FSynchronizeLog != NULL)
- {
- FSynchronizeLog(this, Entry, Message);
- }
- }
- //---------------------------------------------------------------------------
- void __fastcall TSynchronizeController::SynchronizeFilter(TObject * /*Sender*/,
- const UnicodeString DirectoryName, bool & Add)
- {
- if ((FOptions != NULL) && (FOptions->Filter != NULL))
- {
- if (IncludeTrailingBackslash(ExtractFilePath(DirectoryName)) ==
- IncludeTrailingBackslash(FSynchronizeParams.LocalDirectory))
- {
- int FoundIndex;
- Add = FOptions->Filter->Find(ExtractFileName(DirectoryName), FoundIndex);
- }
- }
- if (Add && !FCopyParam.AllowAnyTransfer()) // optimization
- {
- TFileMasks::TParams MaskParams; // size/time does not matter for directories
- bool Hidden = FLAGSET(FileGetAttrFix(DirectoryName), faHidden);
- // Missing call to GetBaseFileName
- Add = FCopyParam.AllowTransfer(DirectoryName, osLocal, true, MaskParams, Hidden);
- }
- }
- //---------------------------------------------------------------------------
- void __fastcall TSynchronizeController::SynchronizeInvalid(
- TObject * /*Sender*/, const UnicodeString Directory, const UnicodeString ErrorStr)
- {
- if (FOnSynchronizeInvalid != NULL)
- {
- FOnSynchronizeInvalid(this, Directory, ErrorStr);
- }
- SynchronizeAbort(false);
- }
- //---------------------------------------------------------------------------
- void __fastcall TSynchronizeController::SynchronizeTooManyDirectories(
- TObject * /*Sender*/, int & MaxDirectories)
- {
- if (FOnTooManyDirectories != NULL)
- {
- FOnTooManyDirectories(this, MaxDirectories);
- }
- }
- //---------------------------------------------------------------------------
- void __fastcall TSynchronizeController::SynchronizeDirectoriesChange(
- TObject * /*Sender*/, int Directories)
- {
- SynchronizeLog(slDirChange, FMTLOAD(SYNCHRONIZE_START, (Directories)));
- }
- //---------------------------------------------------------------------------
- void __fastcall LogSynchronizeEvent(TTerminal * Terminal, const UnicodeString & Message)
- {
- if (Terminal != NULL)
- {
- Terminal->LogEvent(FORMAT("Keep up to date: %s", (Message)));
- }
- }
|