diff --git a/src/apps/installer/CopyEngine.cpp b/src/apps/installer/CopyEngine.cpp index 38dadb4ae6..82b63bc59c 100644 --- a/src/apps/installer/CopyEngine.cpp +++ b/src/apps/installer/CopyEngine.cpp @@ -16,7 +16,6 @@ #include #include #include -#include #include #include "SemaphoreLocker.h" @@ -43,6 +42,8 @@ CopyEngine::CopyEngine(ProgressReporter* reporter, EntryFilter* entryFilter) fWriterThread(-1), fQuitting(false), + fAbsoluteSourcePath(), + fBytesRead(0), fLastBytesRead(0), fItemsCopied(0), @@ -94,6 +95,8 @@ CopyEngine::ResetTargets(const char* source) // TODO: One could subtract the bytes/items which were added to the // ProgressReporter before resetting them... + fAbsoluteSourcePath = source; + fBytesRead = 0; fLastBytesRead = 0; fItemsCopied = 0; @@ -237,13 +240,14 @@ CopyEngine::_CollectCopyInfo(const char* _source, int32& level, struct stat statInfo; entry.GetStat(&statInfo); - char name[B_FILE_NAME_LENGTH]; - status_t ret = entry.GetName(name); + BPath sourceEntryPath; + status_t ret = entry.GetPath(&sourceEntryPath); if (ret < B_OK) return ret; if (fEntryFilter != NULL - && !fEntryFilter->ShouldCopyEntry(entry, name, statInfo, level)) { + && !fEntryFilter->ShouldCopyEntry(entry, + _RelativeEntryPath(sourceEntryPath.Path()), statInfo, level)) { continue; } @@ -307,16 +311,20 @@ CopyEngine::_CopyFolder(const char* _source, const char* _destination, return B_CANCELED; } - char name[B_FILE_NAME_LENGTH]; - status_t ret = entry.GetName(name); - if (ret < B_OK) + const char* name = entry.Name(); + BPath sourceEntryPath; + status_t ret = entry.GetPath(&sourceEntryPath); + if (ret != B_OK) return ret; + const char* relativeSourceEntryPath + = _RelativeEntryPath(sourceEntryPath.Path()); struct stat statInfo; entry.GetStat(&statInfo); if (fEntryFilter != NULL - && !fEntryFilter->ShouldCopyEntry(entry, name, statInfo, level)) { + && !fEntryFilter->ShouldCopyEntry(entry, relativeSourceEntryPath, + statInfo, level)) { continue; } @@ -334,8 +342,8 @@ CopyEngine::_CopyFolder(const char* _source, const char* _destination, ret = B_OK; if (copy.IsDirectory()) { if (fEntryFilter - && fEntryFilter->ShouldClobberFolder(entry, name, - statInfo, level)) { + && fEntryFilter->ShouldClobberFolder(entry, + relativeSourceEntryPath, statInfo, level)) { ret = _RemoveFolder(copy); } else { // Do not overwrite attributes on folders that exist. @@ -353,11 +361,6 @@ CopyEngine::_CopyFolder(const char* _source, const char* _destination, } } - BPath srcFolder; - ret = entry.GetPath(&srcFolder); - if (ret < B_OK) - return ret; - BPath dstFolder; ret = copy.GetPath(&dstFolder); if (ret < B_OK) @@ -366,7 +369,7 @@ CopyEngine::_CopyFolder(const char* _source, const char* _destination, if (cancelSemaphore >= 0) lock.Unlock(); - ret = _CopyFolder(srcFolder.Path(), dstFolder.Path(), level, + ret = _CopyFolder(sourceEntryPath.Path(), dstFolder.Path(), level, cancelSemaphore); if (ret < B_OK) return ret; @@ -483,6 +486,20 @@ CopyEngine::_RemoveFolder(BEntry& entry) } +const char* +CopyEngine::_RelativeEntryPath(const char* absoluteSourcePath) const +{ + if (strncmp(absoluteSourcePath, fAbsoluteSourcePath, + fAbsoluteSourcePath.Length()) != 0) { + return absoluteSourcePath; + } + + const char* relativePath + = absoluteSourcePath + fAbsoluteSourcePath.Length(); + return relativePath[0] == '/' ? relativePath + 1 : relativePath; +} + + void CopyEngine::_UpdateProgress() { diff --git a/src/apps/installer/CopyEngine.h b/src/apps/installer/CopyEngine.h index 855f1dc7a8..298977225b 100644 --- a/src/apps/installer/CopyEngine.h +++ b/src/apps/installer/CopyEngine.h @@ -11,6 +11,7 @@ #include #include #include +#include #include "BlockingQueue.h" @@ -48,6 +49,9 @@ private: status_t _RemoveFolder(BEntry& entry); + const char* _RelativeEntryPath( + const char* absoluteSourcePath) const; + void _UpdateProgress(); static int32 _WriteThreadEntry(void* cookie); @@ -81,11 +85,14 @@ private: bool deleteFile; }; +private: BlockingQueue fBufferQueue; thread_id fWriterThread; volatile bool fQuitting; + BString fAbsoluteSourcePath; + off_t fBytesRead; off_t fLastBytesRead; uint64 fItemsCopied; @@ -111,11 +118,11 @@ public: virtual ~EntryFilter(); virtual bool ShouldCopyEntry(const BEntry& entry, - const char* name, + const char* path, const struct stat& statInfo, int32 level) const = 0; virtual bool ShouldClobberFolder(const BEntry& entry, - const char* name, + const char* path, const struct stat& statInfo, int32 level) const = 0; }; diff --git a/src/apps/installer/WorkerThread.cpp b/src/apps/installer/WorkerThread.cpp index 7587073c59..0661f092c4 100644 --- a/src/apps/installer/WorkerThread.cpp +++ b/src/apps/installer/WorkerThread.cpp @@ -98,30 +98,30 @@ public: fSwapFileEntry.Unset(); } - virtual bool ShouldCopyEntry(const BEntry& entry, const char* name, + virtual bool ShouldCopyEntry(const BEntry& entry, const char* path, const struct stat& statInfo, int32 level) const { if (level == 1 && S_ISDIR(statInfo.st_mode)) { - if (strcmp(kPackagesDirectoryPath, name) == 0) { - printf("ignoring '%s'.\n", name); + if (strcmp(kPackagesDirectoryPath, path) == 0) { + printf("ignoring '%s'.\n", path); return false; } - if (strcmp(kSourcesDirectoryPath, name) == 0) { - printf("ignoring '%s'.\n", name); + if (strcmp(kSourcesDirectoryPath, path) == 0) { + printf("ignoring '%s'.\n", path); return false; } - if (strcmp("rr_moved", name) == 0) { - printf("ignoring '%s'.\n", name); + if (strcmp("rr_moved", path) == 0) { + printf("ignoring '%s'.\n", path); return false; } } if (level == 1 && S_ISREG(statInfo.st_mode)) { - if (strcmp("boot.catalog", name) == 0) { - printf("ignoring '%s'.\n", name); + if (strcmp("boot.catalog", path) == 0) { + printf("ignoring '%s'.\n", path); return false; } - if (strcmp("haiku-boot-floppy.image", name) == 0) { - printf("ignoring '%s'.\n", name); + if (strcmp("haiku-boot-floppy.image", path) == 0) { + printf("ignoring '%s'.\n", path); return false; } } @@ -133,12 +133,12 @@ public: return true; } - virtual bool ShouldClobberFolder(const BEntry& entry, const char* name, + virtual bool ShouldClobberFolder(const BEntry& entry, const char* path, const struct stat& statInfo, int32 level) const { if (level == 1 && S_ISDIR(statInfo.st_mode)) { - if (strcmp("system", name) == 0) { - printf("clobbering '%s'.\n", name); + if (strcmp("system", path) == 0) { + printf("clobbering '%s'.\n", path); return true; } }