added 9 changesets to branch 'refs/remotes/HaikuPM-github/package-management' old head: b23d504796788536d66b523a2b5a3359691b3b2b new head: 6c36ad168e98c010774f57970c7deb03e9b98403 overview: https://github.com/haiku/HaikuPM/compare/b23d504...6c36ad1 ---------------------------------------------------------------------------- 28fd71c: Installer: CopyEngine: Remove some debug/uncommented code fb5f0bb: Installer: Move path string constants to new InstallerDefs.h/cpp a601eaa: Installer: Remove "/boot/var" directory check The PM Haiku Installer doesn't need support installing ancient Haiku versions. c2be967: Installer: CopyEngine: Externalize decision making * Add interface EntryFilter, an instance of which can be passed to the CopyEngine. The object is asked whether to copy entries/clobber directories. * Move the _ShouldCopyEntry()/_ShouldClobberFolder() code to new WorkerThread::EntryFilter. e8eb6ae: Installer: WorkerThread::_PerformInstall(): get rid of goto 348d9ea: Installer: WorkerThread: Remove InstallerWindow dependency * Move message constants to InstallerDefs.h. * Determine the source and target partition ID already in InstallerWindow and pass those to WorkerThread instead of fiddling with menu items in _PerformInstall(). And instead of the window object pass a messenger to the constructor. ba6f7c8: Installer: CopyEngine: Pass relative path to EntryFilter ... instead of the file name. f4953ba: Installer: WorkerThread::EntryFilter: Use path map ... instead of implicit comparisons. 6c36ad1: Installer: Restrict entry filter to files from the BFS volume We generally want to skip the contents of the packagefs volumes (save for the shine-through directories). That makes Installer usable again. In what direction we want to develop it (e.g. integrate some PM support, so that a subset of packages can be selected) needs further discussion. [ Ingo Weinhold <ingo_weinhold@xxxxxx> ] ---------------------------------------------------------------------------- 10 files changed, 274 insertions(+), 185 deletions(-) src/apps/installer/CopyEngine.cpp | 149 ++++++++-------------- src/apps/installer/CopyEngine.h | 40 ++++-- src/apps/installer/InstallerDefs.cpp | 11 ++ src/apps/installer/InstallerDefs.h | 21 ++++ src/apps/installer/InstallerWindow.cpp | 14 ++- src/apps/installer/InstallerWindow.h | 11 -- src/apps/installer/Jamfile | 2 +- src/apps/installer/PackageViews.cpp | 3 +- src/apps/installer/WorkerThread.cpp | 191 ++++++++++++++++++++--------- src/apps/installer/WorkerThread.h | 17 ++- ############################################################################ Commit: 28fd71c58667bdf69bfd211dfaabb0fca945eb71 Author: Ingo Weinhold <ingo_weinhold@xxxxxx> Date: Sat Jun 1 20:18:53 2013 UTC Installer: CopyEngine: Remove some debug/uncommented code ---------------------------------------------------------------------------- diff --git a/src/apps/installer/CopyEngine.cpp b/src/apps/installer/CopyEngine.cpp index 144a85d..a9fb1de 100644 --- a/src/apps/installer/CopyEngine.cpp +++ b/src/apps/installer/CopyEngine.cpp @@ -141,7 +141,6 @@ CopyEngine::CopyFile(const BEntry& _source, const BEntry& _destination, SemaphoreLocker lock(cancelSemaphore); if (cancelSemaphore >= 0 && !lock.IsLocked()) { // We are supposed to quit -printf("CopyFile - cancled\n"); return B_CANCELED; } @@ -555,10 +554,6 @@ CopyEngine::_ShouldClobberFolder(const char* name, const struct stat& statInfo, printf("clobbering '%s'.\n", name); return true; } -// if (strcmp("develop", name) == 0) { -// printf("clobbering '%s'.\n", name); -// return true; -// } } return false; } @@ -621,5 +616,3 @@ CopyEngine::_WriteThread() megaBytes / seconds); } } - - ############################################################################ Commit: fb5f0bb1c75c2a7a41f8936d028ebaa7eb7e84d0 Author: Ingo Weinhold <ingo_weinhold@xxxxxx> Date: Sun Jun 2 12:37:31 2013 UTC Installer: Move path string constants to new InstallerDefs.h/cpp ---------------------------------------------------------------------------- diff --git a/src/apps/installer/CopyEngine.cpp b/src/apps/installer/CopyEngine.cpp index a9fb1de..3b58eb9 100644 --- a/src/apps/installer/CopyEngine.cpp +++ b/src/apps/installer/CopyEngine.cpp @@ -19,8 +19,7 @@ #include <String.h> #include <SymLink.h> -#include "InstallerWindow.h" - // TODO: For PACKAGES_DIRECTORY and VAR_DIRECTORY, not so nice... +#include "InstallerDefs.h" #include "SemaphoreLocker.h" #include "ProgressReporter.h" @@ -107,7 +106,7 @@ CopyEngine::ResetTargets(const char* source) // makes sense, since passing a volume is meant to folders that are // volume specific, like "trash". BPath path(source); - if (path.Append("common/var/swap") == B_OK) + if (path.Append(kSwapFilePath) == B_OK) fSwapFileEntry.SetTo(path.Path()); else fSwapFileEntry.Unset(); @@ -508,16 +507,16 @@ CopyEngine::_ShouldCopyEntry(const BEntry& entry, const char* name, const struct stat& statInfo, int32 level) const { if (level == 1 && S_ISDIR(statInfo.st_mode)) { - if (strcmp(VAR_DIRECTORY, name) == 0) { + if (strcmp(kVarDirectoryPath, name) == 0) { // old location of /boot/var printf("ignoring '%s'.\n", name); return false; } - if (strcmp(PACKAGES_DIRECTORY, name) == 0) { + if (strcmp(kPackagesDirectoryPath, name) == 0) { printf("ignoring '%s'.\n", name); return false; } - if (strcmp(SOURCES_DIRECTORY, name) == 0) { + if (strcmp(kSourcesDirectoryPath, name) == 0) { printf("ignoring '%s'.\n", name); return false; } diff --git a/src/apps/installer/InstallerDefs.cpp b/src/apps/installer/InstallerDefs.cpp new file mode 100644 index 0000000..ae4a55f --- /dev/null +++ b/src/apps/installer/InstallerDefs.cpp @@ -0,0 +1,13 @@ +/* + * Copyright 2013, Haiku, Inc. + * Distributed under the terms of the MIT License. + */ + + +#include "InstallerDefs.h" + + +const char* const kPackagesDirectoryPath = "_packages_"; +const char* const kSourcesDirectoryPath = "_sources_"; +const char* const kVarDirectoryPath = "var"; +const char* const kSwapFilePath = "common/var/swap"; diff --git a/src/apps/installer/InstallerDefs.h b/src/apps/installer/InstallerDefs.h new file mode 100644 index 0000000..3a16dfa --- /dev/null +++ b/src/apps/installer/InstallerDefs.h @@ -0,0 +1,15 @@ +/* + * Copyright 2013, Haiku, Inc. + * Distributed under the terms of the MIT License. + */ +#ifndef INSTALLER_DEFS_H +#define INSTALLER_DEFS_H + + +extern const char* const kPackagesDirectoryPath; +extern const char* const kSourcesDirectoryPath; +extern const char* const kVarDirectoryPath; +extern const char* const kSwapFilePath; + + +#endif // INSTALLER_DEFS_H diff --git a/src/apps/installer/InstallerWindow.cpp b/src/apps/installer/InstallerWindow.cpp index 251f4f5..5a681d5 100644 --- a/src/apps/installer/InstallerWindow.cpp +++ b/src/apps/installer/InstallerWindow.cpp @@ -40,6 +40,7 @@ #include "tracker_private.h" #include "DialogPane.h" +#include "InstallerDefs.h" #include "PackageViews.h" #include "PartitionMenuItem.h" #include "WorkerThread.h" @@ -838,7 +839,7 @@ InstallerWindow::_PublishPackages() } else return; // shouldn't happen - directory.Append(PACKAGES_DIRECTORY); + directory.Append(kPackagesDirectoryPath); BDirectory dir(directory.Path()); if (dir.InitCheck() != B_OK) return; diff --git a/src/apps/installer/InstallerWindow.h b/src/apps/installer/InstallerWindow.h index 4ef3138..14c2977 100644 --- a/src/apps/installer/InstallerWindow.h +++ b/src/apps/installer/InstallerWindow.h @@ -39,10 +39,6 @@ const uint32 MSG_INSTALL_FINISHED = 'iIFN'; const uint32 MSG_RESET = 'iRSI'; const uint32 MSG_WRITE_BOOT_SECTOR = 'iWBS'; -const char PACKAGES_DIRECTORY[] = "_packages_"; -const char SOURCES_DIRECTORY[] = "_sources_"; -const char VAR_DIRECTORY[] = "var"; - class InstallerWindow : public BWindow { public: diff --git a/src/apps/installer/Jamfile b/src/apps/installer/Jamfile index ff7553f..884a93e 100644 --- a/src/apps/installer/Jamfile +++ b/src/apps/installer/Jamfile @@ -6,6 +6,7 @@ SubDirHdrs [ FDirName $(HAIKU_TOP) src kits tracker ] ; Application Installer : CopyEngine.cpp InstallerApp.cpp + InstallerDefs.cpp InstallerWindow.cpp PackageViews.cpp PartitionMenuItem.cpp @@ -26,4 +27,3 @@ DoCatalogs Installer : ProgressReporter.cpp WorkerThread.cpp ; - diff --git a/src/apps/installer/WorkerThread.cpp b/src/apps/installer/WorkerThread.cpp index fbb4727..064375a 100644 --- a/src/apps/installer/WorkerThread.cpp +++ b/src/apps/installer/WorkerThread.cpp @@ -28,6 +28,7 @@ #include "AutoLocker.h" #include "CopyEngine.h" +#include "InstallerDefs.h" #include "InstallerWindow.h" #include "PackageViews.h" #include "PartitionMenuItem.h" @@ -423,7 +424,7 @@ WorkerThread::_PerformInstall(BMenu* srcMenu, BMenu* targetMenu) // Collect selected packages also if (fPackages) { - BPath pkgRootDir(srcDirectory.Path(), PACKAGES_DIRECTORY); + BPath pkgRootDir(srcDirectory.Path(), kPackagesDirectoryPath); int32 count = fPackages->CountItems(); for (int32 i = 0; i < count; i++) { Package *p = static_cast<Package*>(fPackages->ItemAt(i)); @@ -450,7 +451,7 @@ WorkerThread::_PerformInstall(BMenu* srcMenu, BMenu* targetMenu) // copy selected packages if (fPackages) { - BPath pkgRootDir(srcDirectory.Path(), PACKAGES_DIRECTORY); + BPath pkgRootDir(srcDirectory.Path(), kPackagesDirectoryPath); int32 count = fPackages->CountItems(); for (int32 i = 0; i < count; i++) { Package *p = static_cast<Package*>(fPackages->ItemAt(i)); @@ -586,7 +587,7 @@ WorkerThread::_ProcessZipPackages(const char* sourcePath, // TODO: Put those in the optional packages list view // TODO: Implement mechanism to handle dependencies between these // packages. (Selecting one will auto-select others.) - BPath pkgRootDir(sourcePath, PACKAGES_DIRECTORY); + BPath pkgRootDir(sourcePath, kPackagesDirectoryPath); BDirectory directory(pkgRootDir.Path()); BEntry entry; while (directory.GetNextEntry(&entry) == B_OK) { ############################################################################ Commit: a601eaa9e12f36ea05aeea5f2997c76bb591e2ad Author: Ingo Weinhold <ingo_weinhold@xxxxxx> Date: Sun Jun 2 12:43:02 2013 UTC Installer: Remove "/boot/var" directory check The PM Haiku Installer doesn't need support installing ancient Haiku versions. ---------------------------------------------------------------------------- diff --git a/src/apps/installer/CopyEngine.cpp b/src/apps/installer/CopyEngine.cpp index 3b58eb9..8b14883 100644 --- a/src/apps/installer/CopyEngine.cpp +++ b/src/apps/installer/CopyEngine.cpp @@ -507,11 +507,6 @@ CopyEngine::_ShouldCopyEntry(const BEntry& entry, const char* name, const struct stat& statInfo, int32 level) const { if (level == 1 && S_ISDIR(statInfo.st_mode)) { - if (strcmp(kVarDirectoryPath, name) == 0) { - // old location of /boot/var - printf("ignoring '%s'.\n", name); - return false; - } if (strcmp(kPackagesDirectoryPath, name) == 0) { printf("ignoring '%s'.\n", name); return false; diff --git a/src/apps/installer/InstallerDefs.cpp b/src/apps/installer/InstallerDefs.cpp index ae4a55f..4e99387 100644 --- a/src/apps/installer/InstallerDefs.cpp +++ b/src/apps/installer/InstallerDefs.cpp @@ -9,5 +9,4 @@ const char* const kPackagesDirectoryPath = "_packages_"; const char* const kSourcesDirectoryPath = "_sources_"; -const char* const kVarDirectoryPath = "var"; const char* const kSwapFilePath = "common/var/swap"; diff --git a/src/apps/installer/InstallerDefs.h b/src/apps/installer/InstallerDefs.h index 3a16dfa..bbc28c5 100644 --- a/src/apps/installer/InstallerDefs.h +++ b/src/apps/installer/InstallerDefs.h @@ -8,7 +8,6 @@ extern const char* const kPackagesDirectoryPath; extern const char* const kSourcesDirectoryPath; -extern const char* const kVarDirectoryPath; extern const char* const kSwapFilePath; ############################################################################ Commit: c2be967eb9044dd6a57f8ce0f0fde28c3e2e8ab9 Author: Ingo Weinhold <ingo_weinhold@xxxxxx> Date: Sun Jun 2 13:16:26 2013 UTC Installer: CopyEngine: Externalize decision making * Add interface EntryFilter, an instance of which can be passed to the CopyEngine. The object is asked whether to copy entries/clobber directories. * Move the _ShouldCopyEntry()/_ShouldClobberFolder() code to new WorkerThread::EntryFilter. ---------------------------------------------------------------------------- diff --git a/src/apps/installer/CopyEngine.cpp b/src/apps/installer/CopyEngine.cpp index 8b14883..38dadb4 100644 --- a/src/apps/installer/CopyEngine.cpp +++ b/src/apps/installer/CopyEngine.cpp @@ -19,7 +19,6 @@ #include <String.h> #include <SymLink.h> -#include "InstallerDefs.h" #include "SemaphoreLocker.h" #include "ProgressReporter.h" @@ -27,7 +26,18 @@ using std::nothrow; -CopyEngine::CopyEngine(ProgressReporter* reporter) +// #pragma mark - EntryFilter + + +CopyEngine::EntryFilter::~EntryFilter() +{ +} + + +// #pragma mark - CopyEngine + + +CopyEngine::CopyEngine(ProgressReporter* reporter, EntryFilter* entryFilter) : fBufferQueue(), fWriterThread(-1), @@ -48,7 +58,8 @@ CopyEngine::CopyEngine(ProgressReporter* reporter) fCurrentTargetFolder(NULL), fCurrentItem(NULL), - fProgressReporter(reporter) + fProgressReporter(reporter), + fEntryFilter(entryFilter) { fWriterThread = spawn_thread(_WriteThreadEntry, "buffer writer", B_NORMAL_PRIORITY, this); @@ -97,19 +108,6 @@ CopyEngine::ResetTargets(const char* source) fCurrentTargetFolder = NULL; fCurrentItem = NULL; - - // init BEntry pointing to /var - // There is no other way to retrieve the path to the var folder - // on the source volume. Using find_directory() with - // B_COMMON_VAR_DIRECTORY will only ever get the var folder on the - // current /boot volume regardless of the volume of "source", which - // makes sense, since passing a volume is meant to folders that are - // volume specific, like "trash". - BPath path(source); - if (path.Append(kSwapFilePath) == B_OK) - fSwapFileEntry.SetTo(path.Path()); - else - fSwapFileEntry.Unset(); } @@ -244,8 +242,10 @@ CopyEngine::_CollectCopyInfo(const char* _source, int32& level, if (ret < B_OK) return ret; - if (!_ShouldCopyEntry(entry, name, statInfo, level)) + if (fEntryFilter != NULL + && !fEntryFilter->ShouldCopyEntry(entry, name, statInfo, level)) { continue; + } if (S_ISDIR(statInfo.st_mode)) { // handle recursive directory copy @@ -315,8 +315,10 @@ CopyEngine::_CopyFolder(const char* _source, const char* _destination, struct stat statInfo; entry.GetStat(&statInfo); - if (!_ShouldCopyEntry(entry, name, statInfo, level)) + if (fEntryFilter != NULL + && !fEntryFilter->ShouldCopyEntry(entry, name, statInfo, level)) { continue; + } fItemsCopied++; fCurrentItem = name; @@ -331,9 +333,11 @@ CopyEngine::_CopyFolder(const char* _source, const char* _destination, if (copy.Exists()) { ret = B_OK; if (copy.IsDirectory()) { - if (_ShouldClobberFolder(name, statInfo, level)) + if (fEntryFilter + && fEntryFilter->ShouldClobberFolder(entry, name, + statInfo, level)) { ret = _RemoveFolder(copy); - else { + } else { // Do not overwrite attributes on folders that exist. // This should work better when the install target // already contains a Haiku installation. @@ -502,57 +506,6 @@ CopyEngine::_UpdateProgress() } -bool -CopyEngine::_ShouldCopyEntry(const BEntry& entry, const char* name, - 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); - return false; - } - if (strcmp(kSourcesDirectoryPath, name) == 0) { - printf("ignoring '%s'.\n", name); - return false; - } - if (strcmp("rr_moved", name) == 0) { - printf("ignoring '%s'.\n", name); - return false; - } - } - if (level == 1 && S_ISREG(statInfo.st_mode)) { - if (strcmp("boot.catalog", name) == 0) { - printf("ignoring '%s'.\n", name); - return false; - } - if (strcmp("haiku-boot-floppy.image", name) == 0) { - printf("ignoring '%s'.\n", name); - return false; - } - } - if (fSwapFileEntry == entry) { - // current location of var - printf("ignoring swap file\n"); - return false; - } - return true; -} - - -bool -CopyEngine::_ShouldClobberFolder(const char* name, 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); - return true; - } - } - return false; -} - - int32 CopyEngine::_WriteThreadEntry(void* cookie) { diff --git a/src/apps/installer/CopyEngine.h b/src/apps/installer/CopyEngine.h index 61558e7..855f1dc 100644 --- a/src/apps/installer/CopyEngine.h +++ b/src/apps/installer/CopyEngine.h @@ -20,7 +20,11 @@ class ProgressReporter; class CopyEngine { public: - CopyEngine(ProgressReporter* reporter); + class EntryFilter; + +public: + CopyEngine(ProgressReporter* reporter, + EntryFilter* entryFilter); virtual ~CopyEngine(); void ResetTargets(const char* source); @@ -42,15 +46,6 @@ private: const char* destination, int32& level, sem_id cancelSemaphore); - bool _ShouldCopyEntry(const BEntry& entry, - const char* name, - const struct stat& statInfo, - int32 level) const; - - bool _ShouldClobberFolder(const char* name, - const struct stat& statInfo, - int32 level) const; - status_t _RemoveFolder(BEntry& entry); void _UpdateProgress(); @@ -107,10 +102,22 @@ private: const char* fCurrentItem; ProgressReporter* fProgressReporter; + EntryFilter* fEntryFilter; +}; - // TODO: Should be made into a list of BEntris to be ignored, perhaps. - // settable by method... - BEntry fSwapFileEntry; + +class CopyEngine::EntryFilter { +public: + virtual ~EntryFilter(); + + virtual bool ShouldCopyEntry(const BEntry& entry, + const char* name, + const struct stat& statInfo, + int32 level) const = 0; + virtual bool ShouldClobberFolder(const BEntry& entry, + const char* name, + const struct stat& statInfo, + int32 level) const = 0; }; diff --git a/src/apps/installer/WorkerThread.cpp b/src/apps/installer/WorkerThread.cpp index 064375a..3de1f40 100644 --- a/src/apps/installer/WorkerThread.cpp +++ b/src/apps/installer/WorkerThread.cpp @@ -81,6 +81,81 @@ private: // #pragma mark - WorkerThread +class WorkerThread::EntryFilter : public CopyEngine::EntryFilter { +public: + EntryFilter(const char* sourceDirectory) + { + // init BEntry pointing to /var + // There is no other way to retrieve the path to the var folder + // on the source volume. Using find_directory() with + // B_COMMON_VAR_DIRECTORY will only ever get the var folder on the + // current /boot volume regardless of the volume of "source", which + // makes sense, since passing a volume is meant to folders that are + // volume specific, like "trash". + BPath path(sourceDirectory); + if (path.Append(kSwapFilePath) == B_OK) + fSwapFileEntry.SetTo(path.Path()); + else + fSwapFileEntry.Unset(); + } + + virtual bool ShouldCopyEntry(const BEntry& entry, const char* name, + 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); + return false; + } + if (strcmp(kSourcesDirectoryPath, name) == 0) { + printf("ignoring '%s'.\n", name); + return false; + } + if (strcmp("rr_moved", name) == 0) { + printf("ignoring '%s'.\n", name); + return false; + } + } + if (level == 1 && S_ISREG(statInfo.st_mode)) { + if (strcmp("boot.catalog", name) == 0) { + printf("ignoring '%s'.\n", name); + return false; + } + if (strcmp("haiku-boot-floppy.image", name) == 0) { + printf("ignoring '%s'.\n", name); + return false; + } + } + if (fSwapFileEntry == entry) { + // current location of var + printf("ignoring swap file\n"); + return false; + } + return true; + } + + virtual bool ShouldClobberFolder(const BEntry& entry, const char* name, + 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); + return true; + } + } + return false; + } + +private: + // TODO: Should be made into a list of BEntris to be ignored, perhaps. + // settable by method... + BEntry fSwapFileEntry; +}; + + +// #pragma mark - WorkerThread + + WorkerThread::WorkerThread(InstallerWindow *window) : BLooper("copy_engine"), @@ -266,11 +341,6 @@ WorkerThread::_PerformInstall(BMenu* srcMenu, BMenu* targetMenu) const char* mountError = B_TRANSLATE("The disk can't be mounted. Please " "choose a different disk."); - BMessenger messenger(fWindow); - ProgressReporter reporter(messenger, new BMessage(MSG_STATUS_MESSAGE)); - CopyEngine engine(&reporter); - BList unzipEngines; - PartitionMenuItem* targetItem = (PartitionMenuItem*)targetMenu->FindMarked(); PartitionMenuItem* srcItem = (PartitionMenuItem*)srcMenu->FindMarked(); if (!srcItem || !targetItem) { @@ -401,6 +471,13 @@ WorkerThread::_PerformInstall(BMenu* srcMenu, BMenu* targetMenu) // Begin actual installation + { + BMessenger messenger(fWindow); + ProgressReporter reporter(messenger, new BMessage(MSG_STATUS_MESSAGE)); + EntryFilter entryFilter(srcDirectory.Path()); + CopyEngine engine(&reporter, &entryFilter); + BList unzipEngines; + _LaunchInitScript(targetDirectory); // Create the default indices which should always be present on a proper @@ -480,6 +557,8 @@ WorkerThread::_PerformInstall(BMenu* srcMenu, BMenu* targetMenu) BMessenger(fWindow).SendMessage(MSG_INSTALL_FINISHED); return; + } + error: BMessage statusMessage(MSG_RESET); if (err == B_CANCELED) diff --git a/src/apps/installer/WorkerThread.h b/src/apps/installer/WorkerThread.h index e5103b7..6ab6330 100644 --- a/src/apps/installer/WorkerThread.h +++ b/src/apps/installer/WorkerThread.h @@ -55,6 +55,10 @@ private: void _SetStatusMessage(const char* status); +private: + class EntryFilter; + +private: InstallerWindow* fWindow; BDiskDeviceRoster fDDRoster; BList* fPackages; ############################################################################ Commit: e8eb6ae212738836c9a16c463c8aed3cdf23f72e Author: Ingo Weinhold <ingo_weinhold@xxxxxx> Date: Sun Jun 2 13:22:20 2013 UTC Installer: WorkerThread::_PerformInstall(): get rid of goto ---------------------------------------------------------------------------- diff --git a/src/apps/installer/WorkerThread.cpp b/src/apps/installer/WorkerThread.cpp index 3de1f40..0c19670 100644 --- a/src/apps/installer/WorkerThread.cpp +++ b/src/apps/installer/WorkerThread.cpp @@ -322,7 +322,7 @@ WorkerThread::_LaunchFinishScript(BPath &path) } -void +status_t WorkerThread::_PerformInstall(BMenu* srcMenu, BMenu* targetMenu) { CALLED(); @@ -345,7 +345,7 @@ WorkerThread::_PerformInstall(BMenu* srcMenu, BMenu* targetMenu) PartitionMenuItem* srcItem = (PartitionMenuItem*)srcMenu->FindMarked(); if (!srcItem || !targetItem) { ERR("bad menu items\n"); - goto error; + return _InstallationError(err); } // check if target is initialized @@ -356,35 +356,35 @@ WorkerThread::_PerformInstall(BMenu* srcMenu, BMenu* targetMenu) if ((err = partition->Mount()) < B_OK) { _SetStatusMessage(mountError); ERR("BPartition::Mount"); - goto error; + return _InstallationError(err); } } if ((err = partition->GetVolume(&targetVolume)) != B_OK) { ERR("BPartition::GetVolume"); - goto error; + return _InstallationError(err); } if ((err = partition->GetMountPoint(&targetDirectory)) != B_OK) { ERR("BPartition::GetMountPoint"); - goto error; + return _InstallationError(err); } } else if (fDDRoster.GetDeviceWithID(targetItem->ID(), &device) == B_OK) { if (!device.IsMounted()) { if ((err = device.Mount()) < B_OK) { _SetStatusMessage(mountError); ERR("BDiskDevice::Mount"); - goto error; + return _InstallationError(err); } } if ((err = device.GetVolume(&targetVolume)) != B_OK) { ERR("BDiskDevice::GetVolume"); - goto error; + return _InstallationError(err); } if ((err = device.GetMountPoint(&targetDirectory)) != B_OK) { ERR("BDiskDevice::GetMountPoint"); - goto error; + return _InstallationError(err); } } else - goto error; // shouldn't happen + return _InstallationError(err); // shouldn't happen // check if target has enough space if (fSpaceRequired > 0 && targetVolume.FreeBytes() < fSpaceRequired) { @@ -395,27 +395,27 @@ WorkerThread::_PerformInstall(BMenu* srcMenu, BMenu* targetMenu) B_WIDTH_AS_USUAL, B_STOP_ALERT); alert->SetShortcut(1, B_ESCAPE); if (alert->Go() != 0) - goto error; + return _InstallationError(err); } if (fDDRoster.GetPartitionWithID(srcItem->ID(), &device, &partition) == B_OK) { if ((err = partition->GetMountPoint(&srcDirectory)) != B_OK) { ERR("BPartition::GetMountPoint"); - goto error; + return _InstallationError(err); } } else if (fDDRoster.GetDeviceWithID(srcItem->ID(), &device) == B_OK) { if ((err = device.GetMountPoint(&srcDirectory)) != B_OK) { ERR("BDiskDevice::GetMountPoint"); - goto error; + return _InstallationError(err); } } else - goto error; // shouldn't happen + return _InstallationError(err); // shouldn't happen // check not installing on itself if (strcmp(srcDirectory.Path(), targetDirectory.Path()) == 0) { _SetStatusMessage(B_TRANSLATE("You can't install the contents of a " "disk onto itself. Please choose a different disk.")); - goto error; + return _InstallationError(err); } // check not installing on boot volume @@ -427,7 +427,7 @@ WorkerThread::_PerformInstall(BMenu* srcMenu, BMenu* targetMenu) alert->SetShortcut(1, B_ESCAPE); if (alert->Go() != 0) { _SetStatusMessage("Installation stopped."); - goto error; + return _InstallationError(err); } } @@ -464,14 +464,12 @@ WorkerThread::_PerformInstall(BMenu* srcMenu, BMenu* targetMenu) if (alert->Go() != 0) { // TODO: Would be cool to offer the option here to clean additional // folders at the user's choice (like /boot/common and /boot/develop). - err = B_CANCELED; - goto error; + return _InstallationError(B_CANCELED); } } // Begin actual installation - { BMessenger messenger(fWindow); ProgressReporter reporter(messenger, new BMessage(MSG_STATUS_MESSAGE)); EntryFilter entryFilter(srcDirectory.Path()); @@ -486,18 +484,18 @@ WorkerThread::_PerformInstall(BMenu* srcMenu, BMenu* targetMenu) // want problems fixed along the way... err = _CreateDefaultIndices(targetDirectory); if (err != B_OK) - goto error; + return _InstallationError(err); // Mirror all the indices which are present on the source volume onto // the target volume. err = _MirrorIndices(srcDirectory, targetDirectory); if (err != B_OK) - goto error; + return _InstallationError(err); // Let the engine collect information for the progress bar later on engine.ResetTargets(srcDirectory.Path()); err = engine.CollectTargets(srcDirectory.Path(), fCancelSemaphore); if (err != B_OK) - goto error; + return _InstallationError(err); // Collect selected packages also if (fPackages) { @@ -508,7 +506,7 @@ WorkerThread::_PerformInstall(BMenu* srcMenu, BMenu* targetMenu) BPath packageDir(pkgRootDir.Path(), p->Folder()); err = engine.CollectTargets(packageDir.Path(), fCancelSemaphore); if (err != B_OK) - goto error; + return _InstallationError(err); } } @@ -516,7 +514,7 @@ WorkerThread::_PerformInstall(BMenu* srcMenu, BMenu* targetMenu) err = _ProcessZipPackages(srcDirectory.Path(), targetDirectory.Path(), &reporter, unzipEngines); if (err != B_OK) - goto error; + return _InstallationError(err); reporter.StartTimer(); @@ -524,7 +522,7 @@ WorkerThread::_PerformInstall(BMenu* srcMenu, BMenu* targetMenu) err = engine.CopyFolder(srcDirectory.Path(), targetDirectory.Path(), fCancelSemaphore); if (err != B_OK) - goto error; + return _InstallationError(err); // copy selected packages if (fPackages) { @@ -536,7 +534,7 @@ WorkerThread::_PerformInstall(BMenu* srcMenu, BMenu* targetMenu) err = engine.CopyFolder(packageDir.Path(), targetDirectory.Path(), fCancelSemaphore); if (err != B_OK) - goto error; + return _InstallationError(err); } } @@ -550,23 +548,26 @@ WorkerThread::_PerformInstall(BMenu* srcMenu, BMenu* targetMenu) delete engine; } if (err != B_OK) - goto error; + return _InstallationError(err); _LaunchFinishScript(targetDirectory); BMessenger(fWindow).SendMessage(MSG_INSTALL_FINISHED); + return B_OK; +} - return; - } -error: +status_t +WorkerThread::_InstallationError(status_t error) +{ BMessage statusMessage(MSG_RESET); - if (err == B_CANCELED) + if (error == B_CANCELED) _SetStatusMessage(B_TRANSLATE("Installation canceled.")); else - statusMessage.AddInt32("error", err); + statusMessage.AddInt32("error", error); ERR("_PerformInstall failed"); BMessenger(fWindow).SendMessage(&statusMessage); + return error; } diff --git a/src/apps/installer/WorkerThread.h b/src/apps/installer/WorkerThread.h index 6ab6330..d48c3ea 100644 --- a/src/apps/installer/WorkerThread.h +++ b/src/apps/installer/WorkerThread.h @@ -42,8 +42,9 @@ private: void _LaunchInitScript(BPath& path); void _LaunchFinishScript(BPath& path); - void _PerformInstall(BMenu* srcMenu, + status_t _PerformInstall(BMenu* srcMenu, BMenu* dstMenu); + status_t _InstallationError(status_t error); status_t _MirrorIndices(const BPath& srcDirectory, const BPath& targetDirectory) const; status_t _CreateDefaultIndices( ############################################################################ Commit: 348d9eac3b8a59123dcfa04848a42e304a15929d Author: Ingo Weinhold <ingo_weinhold@xxxxxx> Date: Sun Jun 2 13:42:29 2013 UTC Installer: WorkerThread: Remove InstallerWindow dependency * Move message constants to InstallerDefs.h. * Determine the source and target partition ID already in InstallerWindow and pass those to WorkerThread instead of fiddling with menu items in _PerformInstall(). And instead of the window object pass a messenger to the constructor. ---------------------------------------------------------------------------- diff --git a/src/apps/installer/InstallerDefs.h b/src/apps/installer/InstallerDefs.h index bbc28c5..56470a3 100644 --- a/src/apps/installer/InstallerDefs.h +++ b/src/apps/installer/InstallerDefs.h @@ -6,6 +6,14 @@ #define INSTALLER_DEFS_H +#include <SupportDefs.h> + + +static const uint32 MSG_STATUS_MESSAGE = 'iSTM'; +static const uint32 MSG_INSTALL_FINISHED = 'iIFN'; +static const uint32 MSG_RESET = 'iRSI'; +static const uint32 MSG_WRITE_BOOT_SECTOR = 'iWBS'; + extern const char* const kPackagesDirectoryPath; extern const char* const kSourcesDirectoryPath; extern const char* const kSwapFilePath; diff --git a/src/apps/installer/InstallerWindow.cpp b/src/apps/installer/InstallerWindow.cpp index 5a681d5..a80a1d6 100644 --- a/src/apps/installer/InstallerWindow.cpp +++ b/src/apps/installer/InstallerWindow.cpp @@ -370,6 +370,14 @@ InstallerWindow::MessageReceived(BMessage *msg) switch (fInstallStatus) { case kReadyForInstall: { + // get source and target + PartitionMenuItem* targetItem + = (PartitionMenuItem*)fDestMenu->FindMarked(); + PartitionMenuItem* srcItem + = (PartitionMenuItem*)fSrcMenu->FindMarked(); + if (srcItem == NULL || targetItem == NULL) + break; + _SetCopyEngineCancelSemaphore(create_sem(1, "copy engine cancel")); @@ -380,7 +388,8 @@ InstallerWindow::MessageReceived(BMessage *msg) fWorkerThread->SetPackagesList(list); fWorkerThread->SetSpaceRequired(size); fInstallStatus = kInstalling; - fWorkerThread->StartInstall(); + fWorkerThread->StartInstall(srcItem->ID(), + targetItem->ID()); fBeginButton->SetLabel(B_TRANSLATE("Stop")); _DisableInterface(true); diff --git a/src/apps/installer/InstallerWindow.h b/src/apps/installer/InstallerWindow.h index 14c2977..d6be378 100644 --- a/src/apps/installer/InstallerWindow.h +++ b/src/apps/installer/InstallerWindow.h @@ -34,11 +34,6 @@ enum InstallStatus { kCancelled }; -const uint32 MSG_STATUS_MESSAGE = 'iSTM'; -const uint32 MSG_INSTALL_FINISHED = 'iIFN'; -const uint32 MSG_RESET = 'iRSI'; -const uint32 MSG_WRITE_BOOT_SECTOR = 'iWBS'; - class InstallerWindow : public BWindow { public: @@ -48,8 +43,6 @@ public: virtual void MessageReceived(BMessage* message); virtual bool QuitRequested(); - BMenu* GetSourceMenu() { return fSrcMenu; }; - BMenu* GetTargetMenu() { return fDestMenu; }; private: void _ShowOptionalPackages(); void _LaunchDriveSetup(); diff --git a/src/apps/installer/PackageViews.cpp b/src/apps/installer/PackageViews.cpp index 364d675..3987afd 100644 --- a/src/apps/installer/PackageViews.cpp +++ b/src/apps/installer/PackageViews.cpp @@ -19,8 +19,9 @@ #include <ScrollBar.h> #include <String.h> #include <View.h> +#include <Window.h> -#include "InstallerWindow.h" +#include "InstallerDefs.h" #include "StringForSize.h" diff --git a/src/apps/installer/WorkerThread.cpp b/src/apps/installer/WorkerThread.cpp index 0c19670..7587073 100644 --- a/src/apps/installer/WorkerThread.cpp +++ b/src/apps/installer/WorkerThread.cpp @@ -29,7 +29,6 @@ #include "AutoLocker.h" #include "CopyEngine.h" #include "InstallerDefs.h" -#include "InstallerWindow.h" #include "PackageViews.h" #include "PartitionMenuItem.h" #include "ProgressReporter.h" @@ -156,10 +155,10 @@ private: // #pragma mark - WorkerThread -WorkerThread::WorkerThread(InstallerWindow *window) +WorkerThread::WorkerThread(const BMessenger& owner) : BLooper("copy_engine"), - fWindow(window), + fOwner(owner), fPackages(NULL), fSpaceRequired(0), fCancelSemaphore(-1) @@ -175,7 +174,8 @@ WorkerThread::MessageReceived(BMessage* message) switch (message->what) { case MSG_START_INSTALLING: - _PerformInstall(fWindow->GetSourceMenu(), fWindow->GetTargetMenu()); + _PerformInstall(message->GetInt32("source", -1), + message->GetInt32("target", -1)); break; case MSG_WRITE_BOOT_SECTOR: @@ -262,10 +262,15 @@ WorkerThread::SetPackagesList(BList *list) void -WorkerThread::StartInstall() +WorkerThread::StartInstall(partition_id sourcePartitionID, + partition_id targetPartitionID) { // Executed in window thread. - PostMessage(MSG_START_INSTALLING, this); + BMessage message(MSG_START_INSTALLING); + message.AddInt32("source", sourcePartitionID); + message.AddInt32("target", targetPartitionID); + + PostMessage(&message, this); } @@ -323,7 +328,8 @@ WorkerThread::_LaunchFinishScript(BPath &path) status_t -WorkerThread::_PerformInstall(BMenu* srcMenu, BMenu* targetMenu) +WorkerThread::_PerformInstall(partition_id sourcePartitionID, + partition_id targetPartitionID) { CALLED(); @@ -341,16 +347,14 @@ WorkerThread::_PerformInstall(BMenu* srcMenu, BMenu* targetMenu) const char* mountError = B_TRANSLATE("The disk can't be mounted. Please " "choose a different disk."); - PartitionMenuItem* targetItem = (PartitionMenuItem*)targetMenu->FindMarked(); - PartitionMenuItem* srcItem = (PartitionMenuItem*)srcMenu->FindMarked(); - if (!srcItem || !targetItem) { - ERR("bad menu items\n"); + if (sourcePartitionID < 0 || targetPartitionID < 0) { + ERR("bad source or target partition ID\n"); return _InstallationError(err); } // check if target is initialized // ask if init or mount as is - if (fDDRoster.GetPartitionWithID(targetItem->ID(), &device, + if (fDDRoster.GetPartitionWithID(targetPartitionID, &device, &partition) == B_OK) { if (!partition->IsMounted()) { if ((err = partition->Mount()) < B_OK) { @@ -367,7 +371,7 @@ WorkerThread::_PerformInstall(BMenu* srcMenu, BMenu* targetMenu) ERR("BPartition::GetMountPoint"); return _InstallationError(err); } - } else if (fDDRoster.GetDeviceWithID(targetItem->ID(), &device) == B_OK) { + } else if (fDDRoster.GetDeviceWithID(targetPartitionID, &device) == B_OK) { if (!device.IsMounted()) { if ((err = device.Mount()) < B_OK) { _SetStatusMessage(mountError); @@ -398,12 +402,13 @@ WorkerThread::_PerformInstall(BMenu* srcMenu, BMenu* targetMenu) return _InstallationError(err); } - if (fDDRoster.GetPartitionWithID(srcItem->ID(), &device, &partition) == B_OK) { + if (fDDRoster.GetPartitionWithID(sourcePartitionID, &device, &partition) + == B_OK) { if ((err = partition->GetMountPoint(&srcDirectory)) != B_OK) { ERR("BPartition::GetMountPoint"); return _InstallationError(err); } - } else if (fDDRoster.GetDeviceWithID(srcItem->ID(), &device) == B_OK) { + } else if (fDDRoster.GetDeviceWithID(sourcePartitionID, &device) == B_OK) { if ((err = device.GetMountPoint(&srcDirectory)) != B_OK) { ERR("BDiskDevice::GetMountPoint"); return _InstallationError(err); @@ -470,8 +475,7 @@ WorkerThread::_PerformInstall(BMenu* srcMenu, BMenu* targetMenu) // Begin actual installation - BMessenger messenger(fWindow); - ProgressReporter reporter(messenger, new BMessage(MSG_STATUS_MESSAGE)); + ProgressReporter reporter(fOwner, new BMessage(MSG_STATUS_MESSAGE)); EntryFilter entryFilter(srcDirectory.Path()); CopyEngine engine(&reporter, &entryFilter); BList unzipEngines; @@ -552,7 +556,7 @@ WorkerThread::_PerformInstall(BMenu* srcMenu, BMenu* targetMenu) _LaunchFinishScript(targetDirectory); - BMessenger(fWindow).SendMessage(MSG_INSTALL_FINISHED); + fOwner.SendMessage(MSG_INSTALL_FINISHED); return B_OK; } @@ -566,7 +570,7 @@ WorkerThread::_InstallationError(status_t error) else statusMessage.AddInt32("error", error); ERR("_PerformInstall failed"); - BMessenger(fWindow).SendMessage(&statusMessage); + fOwner.SendMessage(&statusMessage); return error; } @@ -707,7 +711,7 @@ WorkerThread::_SetStatusMessage(const char *status) { BMessage msg(MSG_STATUS_MESSAGE); msg.AddString("status", status); - BMessenger(fWindow).SendMessage(&msg); + fOwner.SendMessage(&msg); } diff --git a/src/apps/installer/WorkerThread.h b/src/apps/installer/WorkerThread.h index d48c3ea..80233ef 100644 --- a/src/apps/installer/WorkerThread.h +++ b/src/apps/installer/WorkerThread.h @@ -15,12 +15,11 @@ class BList; class BMenu; -class InstallerWindow; class ProgressReporter; class WorkerThread : public BLooper { public: - WorkerThread(InstallerWindow* window); + WorkerThread(const BMessenger& owner); virtual void MessageReceived(BMessage* message); @@ -35,15 +34,16 @@ public: void SetLock(sem_id cancelSemaphore) { fCancelSemaphore = cancelSemaphore; } - void StartInstall(); + void StartInstall(partition_id sourcePartitionID, + partition_id targetPartitionID); void WriteBootSector(BMenu* dstMenu); private: void _LaunchInitScript(BPath& path); void _LaunchFinishScript(BPath& path); - status_t _PerformInstall(BMenu* srcMenu, - BMenu* dstMenu); + status_t _PerformInstall(partition_id sourcePartitionID, + partition_id targetPartitionID); status_t _InstallationError(status_t error); status_t _MirrorIndices(const BPath& srcDirectory, const BPath& targetDirectory) const; @@ -60,7 +60,7 @@ private: class EntryFilter; private: - InstallerWindow* fWindow; + BMessenger fOwner; BDiskDeviceRoster fDDRoster; BList* fPackages; off_t fSpaceRequired; ############################################################################ Commit: ba6f7c8c42038755c9017ae014859d016b072580 Author: Ingo Weinhold <ingo_weinhold@xxxxxx> Date: Sun Jun 2 14:16:45 2013 UTC Installer: CopyEngine: Pass relative path to EntryFilter ... instead of the file name. ---------------------------------------------------------------------------- diff --git a/src/apps/installer/CopyEngine.cpp b/src/apps/installer/CopyEngine.cpp index 38dadb4..82b63bc 100644 --- a/src/apps/installer/CopyEngine.cpp +++ b/src/apps/installer/CopyEngine.cpp @@ -16,7 +16,6 @@ #include <fs_attr.h> #include <NodeInfo.h> #include <Path.h> -#include <String.h> #include <SymLink.h> #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 855f1dc..2989772 100644 --- a/src/apps/installer/CopyEngine.h +++ b/src/apps/installer/CopyEngine.h @@ -11,6 +11,7 @@ #include <Entry.h> #include <File.h> #include <Messenger.h> +#include <String.h> #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<Buffer> 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 7587073..0661f09 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; } } ############################################################################ Commit: f4953ba541417f59c4310ea6b6ccf68cb86a3258 Author: Ingo Weinhold <ingo_weinhold@xxxxxx> Date: Sun Jun 2 14:30:25 2013 UTC Installer: WorkerThread::EntryFilter: Use path map ... instead of implicit comparisons. ---------------------------------------------------------------------------- diff --git a/src/apps/installer/WorkerThread.cpp b/src/apps/installer/WorkerThread.cpp index 0661f09..e22790f 100644 --- a/src/apps/installer/WorkerThread.cpp +++ b/src/apps/installer/WorkerThread.cpp @@ -9,6 +9,9 @@ #include <errno.h> #include <stdio.h> +#include <set> +#include <string> + #include <Alert.h> #include <Autolock.h> #include <Catalog.h> @@ -84,50 +87,23 @@ class WorkerThread::EntryFilter : public CopyEngine::EntryFilter { public: EntryFilter(const char* sourceDirectory) { - // init BEntry pointing to /var - // There is no other way to retrieve the path to the var folder - // on the source volume. Using find_directory() with - // B_COMMON_VAR_DIRECTORY will only ever get the var folder on the - // current /boot volume regardless of the volume of "source", which - // makes sense, since passing a volume is meant to folders that are - // volume specific, like "trash". - BPath path(sourceDirectory); - if (path.Append(kSwapFilePath) == B_OK) - fSwapFileEntry.SetTo(path.Path()); - else - fSwapFileEntry.Unset(); + try { + fIgnorePaths.insert(kPackagesDirectoryPath); + fIgnorePaths.insert(kSourcesDirectoryPath); + fIgnorePaths.insert("rr_moved"); + fIgnorePaths.insert("boot.catalog"); + fIgnorePaths.insert("haiku-boot-floppy.image"); + fIgnorePaths.insert(kSwapFilePath); + } catch (std::bad_alloc&) { + } + } 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, path) == 0) { - printf("ignoring '%s'.\n", path); - return false; - } - if (strcmp(kSourcesDirectoryPath, path) == 0) { - printf("ignoring '%s'.\n", path); - return false; - } - 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", path) == 0) { - printf("ignoring '%s'.\n", path); - return false; - } - if (strcmp("haiku-boot-floppy.image", path) == 0) { - printf("ignoring '%s'.\n", path); - return false; - } - } - if (fSwapFileEntry == entry) { - // current location of var - printf("ignoring swap file\n"); + if (fIgnorePaths.find(path) != fIgnorePaths.end()) { + printf("ignoring '%s'.\n", path); return false; } return true; @@ -146,9 +122,7 @@ public: } private: - // TODO: Should be made into a list of BEntris to be ignored, perhaps. - // settable by method... - BEntry fSwapFileEntry; + std::set<std::string> fIgnorePaths; }; ############################################################################ Commit: 6c36ad168e98c010774f57970c7deb03e9b98403 Author: Ingo Weinhold <ingo_weinhold@xxxxxx> Date: Sun Jun 2 17:11:39 2013 UTC Installer: Restrict entry filter to files from the BFS volume We generally want to skip the contents of the packagefs volumes (save for the shine-through directories). That makes Installer usable again. In what direction we want to develop it (e.g. integrate some PM support, so that a subset of packages can be selected) needs further discussion. ---------------------------------------------------------------------------- diff --git a/src/apps/installer/InstallerDefs.cpp b/src/apps/installer/InstallerDefs.cpp index 4e99387..a389547 100644 --- a/src/apps/installer/InstallerDefs.cpp +++ b/src/apps/installer/InstallerDefs.cpp @@ -9,4 +9,3 @@ const char* const kPackagesDirectoryPath = "_packages_"; const char* const kSourcesDirectoryPath = "_sources_"; -const char* const kSwapFilePath = "common/var/swap"; diff --git a/src/apps/installer/InstallerDefs.h b/src/apps/installer/InstallerDefs.h index 56470a3..b8075c9 100644 --- a/src/apps/installer/InstallerDefs.h +++ b/src/apps/installer/InstallerDefs.h @@ -16,7 +16,6 @@ static const uint32 MSG_WRITE_BOOT_SECTOR = 'iWBS'; extern const char* const kPackagesDirectoryPath; extern const char* const kSourcesDirectoryPath; -extern const char* const kSwapFilePath; #endif // INSTALLER_DEFS_H diff --git a/src/apps/installer/WorkerThread.cpp b/src/apps/installer/WorkerThread.cpp index e22790f..d2d1550 100644 --- a/src/apps/installer/WorkerThread.cpp +++ b/src/apps/installer/WorkerThread.cpp @@ -86,6 +86,9 @@ private: class WorkerThread::EntryFilter : public CopyEngine::EntryFilter { public: EntryFilter(const char* sourceDirectory) + : + fIgnorePaths(), + fSourceDevice(-1) { try { fIgnorePaths.insert(kPackagesDirectoryPath); @@ -93,10 +96,18 @@ public: fIgnorePaths.insert("rr_moved"); fIgnorePaths.insert("boot.catalog"); fIgnorePaths.insert("haiku-boot-floppy.image"); - fIgnorePaths.insert(kSwapFilePath); + fIgnorePaths.insert("common/var/swap"); + fIgnorePaths.insert("common/var/shared_memory"); + + fPackageFSRootPaths.insert("system"); + fPackageFSRootPaths.insert("common"); + fPackageFSRootPaths.insert("home/config"); } catch (std::bad_alloc&) { } + struct stat st; + if (stat(sourceDirectory, &st) == 0) + fSourceDevice = st.st_dev; } virtual bool ShouldCopyEntry(const BEntry& entry, const char* path, @@ -106,6 +117,15 @@ public: printf("ignoring '%s'.\n", path); return false; } + + if (statInfo.st_dev != fSourceDevice) { + // Allow that only for the root of the packagefs mounts, since + // those contain directories that shine through from the + // underlying volume. + if (fPackageFSRootPaths.find(path) == fPackageFSRootPaths.end()) + return false; + } + return true; } @@ -123,6 +143,8 @@ public: private: std::set<std::string> fIgnorePaths; + std::set<std::string> fPackageFSRootPaths; + dev_t fSourceDevice; };