Installer: CopyEngine: Pass relative path to EntryFilter

... instead of the file name.
This commit is contained in:
Ingo Weinhold 2013-06-02 16:16:45 +02:00
parent 348d9eac3b
commit ba6f7c8c42
3 changed files with 56 additions and 32 deletions

View File

@ -16,7 +16,6 @@
#include <fs_attr.h> #include <fs_attr.h>
#include <NodeInfo.h> #include <NodeInfo.h>
#include <Path.h> #include <Path.h>
#include <String.h>
#include <SymLink.h> #include <SymLink.h>
#include "SemaphoreLocker.h" #include "SemaphoreLocker.h"
@ -43,6 +42,8 @@ CopyEngine::CopyEngine(ProgressReporter* reporter, EntryFilter* entryFilter)
fWriterThread(-1), fWriterThread(-1),
fQuitting(false), fQuitting(false),
fAbsoluteSourcePath(),
fBytesRead(0), fBytesRead(0),
fLastBytesRead(0), fLastBytesRead(0),
fItemsCopied(0), fItemsCopied(0),
@ -94,6 +95,8 @@ CopyEngine::ResetTargets(const char* source)
// TODO: One could subtract the bytes/items which were added to the // TODO: One could subtract the bytes/items which were added to the
// ProgressReporter before resetting them... // ProgressReporter before resetting them...
fAbsoluteSourcePath = source;
fBytesRead = 0; fBytesRead = 0;
fLastBytesRead = 0; fLastBytesRead = 0;
fItemsCopied = 0; fItemsCopied = 0;
@ -237,13 +240,14 @@ CopyEngine::_CollectCopyInfo(const char* _source, int32& level,
struct stat statInfo; struct stat statInfo;
entry.GetStat(&statInfo); entry.GetStat(&statInfo);
char name[B_FILE_NAME_LENGTH]; BPath sourceEntryPath;
status_t ret = entry.GetName(name); status_t ret = entry.GetPath(&sourceEntryPath);
if (ret < B_OK) if (ret < B_OK)
return ret; return ret;
if (fEntryFilter != NULL if (fEntryFilter != NULL
&& !fEntryFilter->ShouldCopyEntry(entry, name, statInfo, level)) { && !fEntryFilter->ShouldCopyEntry(entry,
_RelativeEntryPath(sourceEntryPath.Path()), statInfo, level)) {
continue; continue;
} }
@ -307,16 +311,20 @@ CopyEngine::_CopyFolder(const char* _source, const char* _destination,
return B_CANCELED; return B_CANCELED;
} }
char name[B_FILE_NAME_LENGTH]; const char* name = entry.Name();
status_t ret = entry.GetName(name); BPath sourceEntryPath;
if (ret < B_OK) status_t ret = entry.GetPath(&sourceEntryPath);
if (ret != B_OK)
return ret; return ret;
const char* relativeSourceEntryPath
= _RelativeEntryPath(sourceEntryPath.Path());
struct stat statInfo; struct stat statInfo;
entry.GetStat(&statInfo); entry.GetStat(&statInfo);
if (fEntryFilter != NULL if (fEntryFilter != NULL
&& !fEntryFilter->ShouldCopyEntry(entry, name, statInfo, level)) { && !fEntryFilter->ShouldCopyEntry(entry, relativeSourceEntryPath,
statInfo, level)) {
continue; continue;
} }
@ -334,8 +342,8 @@ CopyEngine::_CopyFolder(const char* _source, const char* _destination,
ret = B_OK; ret = B_OK;
if (copy.IsDirectory()) { if (copy.IsDirectory()) {
if (fEntryFilter if (fEntryFilter
&& fEntryFilter->ShouldClobberFolder(entry, name, && fEntryFilter->ShouldClobberFolder(entry,
statInfo, level)) { relativeSourceEntryPath, statInfo, level)) {
ret = _RemoveFolder(copy); ret = _RemoveFolder(copy);
} else { } else {
// Do not overwrite attributes on folders that exist. // 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; BPath dstFolder;
ret = copy.GetPath(&dstFolder); ret = copy.GetPath(&dstFolder);
if (ret < B_OK) if (ret < B_OK)
@ -366,7 +369,7 @@ CopyEngine::_CopyFolder(const char* _source, const char* _destination,
if (cancelSemaphore >= 0) if (cancelSemaphore >= 0)
lock.Unlock(); lock.Unlock();
ret = _CopyFolder(srcFolder.Path(), dstFolder.Path(), level, ret = _CopyFolder(sourceEntryPath.Path(), dstFolder.Path(), level,
cancelSemaphore); cancelSemaphore);
if (ret < B_OK) if (ret < B_OK)
return ret; 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 void
CopyEngine::_UpdateProgress() CopyEngine::_UpdateProgress()
{ {

View File

@ -11,6 +11,7 @@
#include <Entry.h> #include <Entry.h>
#include <File.h> #include <File.h>
#include <Messenger.h> #include <Messenger.h>
#include <String.h>
#include "BlockingQueue.h" #include "BlockingQueue.h"
@ -48,6 +49,9 @@ private:
status_t _RemoveFolder(BEntry& entry); status_t _RemoveFolder(BEntry& entry);
const char* _RelativeEntryPath(
const char* absoluteSourcePath) const;
void _UpdateProgress(); void _UpdateProgress();
static int32 _WriteThreadEntry(void* cookie); static int32 _WriteThreadEntry(void* cookie);
@ -81,11 +85,14 @@ private:
bool deleteFile; bool deleteFile;
}; };
private:
BlockingQueue<Buffer> fBufferQueue; BlockingQueue<Buffer> fBufferQueue;
thread_id fWriterThread; thread_id fWriterThread;
volatile bool fQuitting; volatile bool fQuitting;
BString fAbsoluteSourcePath;
off_t fBytesRead; off_t fBytesRead;
off_t fLastBytesRead; off_t fLastBytesRead;
uint64 fItemsCopied; uint64 fItemsCopied;
@ -111,11 +118,11 @@ public:
virtual ~EntryFilter(); virtual ~EntryFilter();
virtual bool ShouldCopyEntry(const BEntry& entry, virtual bool ShouldCopyEntry(const BEntry& entry,
const char* name, const char* path,
const struct stat& statInfo, const struct stat& statInfo,
int32 level) const = 0; int32 level) const = 0;
virtual bool ShouldClobberFolder(const BEntry& entry, virtual bool ShouldClobberFolder(const BEntry& entry,
const char* name, const char* path,
const struct stat& statInfo, const struct stat& statInfo,
int32 level) const = 0; int32 level) const = 0;
}; };

View File

@ -98,30 +98,30 @@ public:
fSwapFileEntry.Unset(); 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 const struct stat& statInfo, int32 level) const
{ {
if (level == 1 && S_ISDIR(statInfo.st_mode)) { if (level == 1 && S_ISDIR(statInfo.st_mode)) {
if (strcmp(kPackagesDirectoryPath, name) == 0) { if (strcmp(kPackagesDirectoryPath, path) == 0) {
printf("ignoring '%s'.\n", name); printf("ignoring '%s'.\n", path);
return false; return false;
} }
if (strcmp(kSourcesDirectoryPath, name) == 0) { if (strcmp(kSourcesDirectoryPath, path) == 0) {
printf("ignoring '%s'.\n", name); printf("ignoring '%s'.\n", path);
return false; return false;
} }
if (strcmp("rr_moved", name) == 0) { if (strcmp("rr_moved", path) == 0) {
printf("ignoring '%s'.\n", name); printf("ignoring '%s'.\n", path);
return false; return false;
} }
} }
if (level == 1 && S_ISREG(statInfo.st_mode)) { if (level == 1 && S_ISREG(statInfo.st_mode)) {
if (strcmp("boot.catalog", name) == 0) { if (strcmp("boot.catalog", path) == 0) {
printf("ignoring '%s'.\n", name); printf("ignoring '%s'.\n", path);
return false; return false;
} }
if (strcmp("haiku-boot-floppy.image", name) == 0) { if (strcmp("haiku-boot-floppy.image", path) == 0) {
printf("ignoring '%s'.\n", name); printf("ignoring '%s'.\n", path);
return false; return false;
} }
} }
@ -133,12 +133,12 @@ public:
return true; 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 const struct stat& statInfo, int32 level) const
{ {
if (level == 1 && S_ISDIR(statInfo.st_mode)) { if (level == 1 && S_ISDIR(statInfo.st_mode)) {
if (strcmp("system", name) == 0) { if (strcmp("system", path) == 0) {
printf("clobbering '%s'.\n", name); printf("clobbering '%s'.\n", path);
return true; return true;
} }
} }