[haiku-commits] haiku: hrev53996 - src/apps/installer

  • From: Adrien Destugues <pulkomandy@xxxxxxxxx>
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Sun, 22 Mar 2020 16:40:26 -0400 (EDT)

hrev53996 adds 3 changesets to branch 'master'
old head: 18da5c304219abce11add74e2df0e3e05dc5d48b
new head: f1e5a6c914a9341f2b874f43b8f945db7c895d4c
overview: 
https://git.haiku-os.org/haiku/log/?qt=range&q=f1e5a6c914a9+%5E18da5c304219

----------------------------------------------------------------------------

fd09d551e197: installer/CopyEngine: _CollectCopyInfo now works with all file 
types
  
  CollectCopyInfo was designed to process directories only. This commit
  makes it more versatile and works with everything instead.
  
  Change-Id: Ifa74db3815411f7348e3bcc230842710058b1111
  Reviewed-on: https://review.haiku-os.org/c/haiku/+/2398
  Reviewed-by: waddlesplash <waddlesplash@xxxxxxxxx>

bf551d3889bf: installer/CopyEngine: now only exposes a Copy() method
  
  Previously this class exposes two methods:
  - CopyFile(): only copy the file data, nothing else.
  - CopyFolder(): copy files & directories between two folders, while
                  preserving the attributes as well as symlinks.
  
  With this commit, everything is unified into one method: Copy(). This
  method can handle files, directories, symlinks and optionally also copy
  attributes. Since most of the logic was just moved around, we can be
  rather certain that this won't disrupt CopyEngine behaviors by much.
  
  In the future we should look into using BCopyEngine to replace the
  copying part of CopyEngine, as they seems to be compatible.
  
  This change allows the Installer to make use of CopyEngine as a
  general-purpose copier, in preparation for optional .hpkg installation
  support.
  
  Change-Id: Iad5ba2ebc9f34b7822e550b415308fd2b43eed47
  Reviewed-on: https://review.haiku-os.org/c/haiku/+/2399
  Reviewed-by: waddlesplash <waddlesplash@xxxxxxxxx>

f1e5a6c914a9: Installer: supports installing .hpkg-based optional packages
  
  Most of Installer was designed for old-style optional packages (files in
  a folder that's copied to the target volume). This commit modifies
  Installer so that it can process and install .hpkg packages.
  
  Change-Id: Ib7d69a04ccb7879b956b5c3f0df1241c56e4987d
  Reviewed-on: https://review.haiku-os.org/c/haiku/+/2400
  Reviewed-by: waddlesplash <waddlesplash@xxxxxxxxx>

                                       [ Leorize <leorize+oss@xxxxxxxxxxx> ]

----------------------------------------------------------------------------

5 files changed, 212 insertions(+), 188 deletions(-)
src/apps/installer/CopyEngine.cpp   | 334 ++++++++++++++++----------------
src/apps/installer/CopyEngine.h     |  19 +-
src/apps/installer/PackageViews.cpp |   6 +-
src/apps/installer/PackageViews.h   |  13 +-
src/apps/installer/WorkerThread.cpp |  28 ++-

############################################################################

Commit:      fd09d551e19791faefd6f91ca824736ebec0d1c6
URL:         https://git.haiku-os.org/haiku/commit/?id=fd09d551e197
Author:      Leorize <leorize+oss@xxxxxxxxxxx>
Date:        Sat Mar 21 15:49:29 2020 UTC
Committer:   Adrien Destugues <pulkomandy@xxxxxxxxx>
Commit-Date: Sun Mar 22 20:40:21 2020 UTC

installer/CopyEngine: _CollectCopyInfo now works with all file types

CollectCopyInfo was designed to process directories only. This commit
makes it more versatile and works with everything instead.

Change-Id: Ifa74db3815411f7348e3bcc230842710058b1111
Reviewed-on: https://review.haiku-os.org/c/haiku/+/2398
Reviewed-by: waddlesplash <waddlesplash@xxxxxxxxx>

----------------------------------------------------------------------------

diff --git a/src/apps/installer/CopyEngine.cpp 
b/src/apps/installer/CopyEngine.cpp
index 37b70c2265..bd798fefae 100644
--- a/src/apps/installer/CopyEngine.cpp
+++ b/src/apps/installer/CopyEngine.cpp
@@ -226,56 +226,56 @@ CopyEngine::_CollectCopyInfo(const char* _source, int32& 
level,
 {
        level++;
 
-       BDirectory source(_source);
+       BEntry source(_source);
        status_t ret = source.InitCheck();
        if (ret < B_OK)
                return ret;
 
-       BEntry entry;
-       while (source.GetNextEntry(&entry) == B_OK) {
-               SemaphoreLocker lock(cancelSemaphore);
-               if (cancelSemaphore >= 0 && !lock.IsLocked()) {
-                       // We are supposed to quit
-                       return B_CANCELED;
-               }
+       struct stat statInfo;
+       ret = source.GetStat(&statInfo);
+       if (ret < B_OK)
+               return ret;
 
-               struct stat statInfo;
-               entry.GetStat(&statInfo);
+       SemaphoreLocker lock(cancelSemaphore);
+       if (cancelSemaphore >= 0 && !lock.IsLocked()) {
+               // We are supposed to quit
+               return B_CANCELED;
+       }
 
-               BPath sourceEntryPath;
-               status_t ret = entry.GetPath(&sourceEntryPath);
+       if (fEntryFilter != NULL
+               && !fEntryFilter->ShouldCopyEntry(source,
+                       _RelativeEntryPath(_source), statInfo, level)) {
+               // Skip this entry
+               return B_OK;
+       }
+
+       if (cancelSemaphore >= 0)
+               lock.Unlock();
+
+       if (S_ISDIR(statInfo.st_mode)) {
+               BDirectory srcFolder(&source);
+               ret = srcFolder.InitCheck();
                if (ret < B_OK)
                        return ret;
 
-               if (fEntryFilter != NULL
-                       && !fEntryFilter->ShouldCopyEntry(entry,
-                               _RelativeEntryPath(sourceEntryPath.Path()), 
statInfo, level)) {
-                       continue;
-               }
-
-               if (S_ISDIR(statInfo.st_mode)) {
-                       // handle recursive directory copy
-                       BPath srcFolder;
-                       ret = entry.GetPath(&srcFolder);
+               BEntry entry;
+               while (srcFolder.GetNextEntry(&entry) == B_OK) {
+                       BPath entryPath;
+                       ret = entry.GetPath(&entryPath);
                        if (ret < B_OK)
                                return ret;
 
-                       if (cancelSemaphore >= 0)
-                               lock.Unlock();
-
-                       ret = _CollectCopyInfo(srcFolder.Path(), level, 
cancelSemaphore);
+                       ret = _CollectCopyInfo(entryPath.Path(), level, 
cancelSemaphore);
                        if (ret < B_OK)
                                return ret;
-               } else if (S_ISLNK(statInfo.st_mode)) {
-                       // link, ignore size
-               } else {
-                       // file data
-                       fBytesToCopy += statInfo.st_size;
                }
-
-               fItemsToCopy++;
+       } else if (S_ISLNK(statInfo.st_mode)) {
+               // link, ignore size
+       } else {
+               fBytesToCopy += statInfo.st_size;
        }
 
+       fItemsToCopy++;
        level--;
        return B_OK;
 }

############################################################################

Commit:      bf551d3889bfdce1e2250df307d505d88fe6c4e1
URL:         https://git.haiku-os.org/haiku/commit/?id=bf551d3889bf
Author:      Leorize <leorize+oss@xxxxxxxxxxx>
Date:        Sat Mar 21 18:38:24 2020 UTC
Committer:   Adrien Destugues <pulkomandy@xxxxxxxxx>
Commit-Date: Sun Mar 22 20:40:21 2020 UTC

installer/CopyEngine: now only exposes a Copy() method

Previously this class exposes two methods:
- CopyFile(): only copy the file data, nothing else.
- CopyFolder(): copy files & directories between two folders, while
                preserving the attributes as well as symlinks.

With this commit, everything is unified into one method: Copy(). This
method can handle files, directories, symlinks and optionally also copy
attributes. Since most of the logic was just moved around, we can be
rather certain that this won't disrupt CopyEngine behaviors by much.

In the future we should look into using BCopyEngine to replace the
copying part of CopyEngine, as they seems to be compatible.

This change allows the Installer to make use of CopyEngine as a
general-purpose copier, in preparation for optional .hpkg installation
support.

Change-Id: Iad5ba2ebc9f34b7822e550b415308fd2b43eed47
Reviewed-on: https://review.haiku-os.org/c/haiku/+/2399
Reviewed-by: waddlesplash <waddlesplash@xxxxxxxxx>

----------------------------------------------------------------------------

diff --git a/src/apps/installer/CopyEngine.cpp 
b/src/apps/installer/CopyEngine.cpp
index bd798fefae..7678facac8 100644
--- a/src/apps/installer/CopyEngine.cpp
+++ b/src/apps/installer/CopyEngine.cpp
@@ -128,16 +128,28 @@ CopyEngine::CollectTargets(const char* source, sem_id 
cancelSemaphore)
 
 
 status_t
-CopyEngine::CopyFolder(const char* source, const char* destination,
-       sem_id cancelSemaphore)
+CopyEngine::Copy(const char* _source, const char* _destination,
+       sem_id cancelSemaphore, bool copyAttributes)
 {
        int32 level = 0;
-       return _CopyFolder(source, destination, level, cancelSemaphore);
+       status_t ret;
+
+       BEntry source(_source);
+       ret = source.InitCheck();
+       if (ret != B_OK)
+               return ret;
+
+       BEntry destination(_destination);
+       ret = destination.InitCheck();
+       if (ret != B_OK)
+               return ret;
+
+       return _Copy(source, destination, level, cancelSemaphore, 
copyAttributes);
 }
 
 
 status_t
-CopyEngine::CopyFile(const BEntry& _source, const BEntry& _destination,
+CopyEngine::_CopyData(const BEntry& _source, const BEntry& _destination,
        sem_id cancelSemaphore)
 {
        SemaphoreLocker lock(cancelSemaphore);
@@ -282,157 +294,153 @@ CopyEngine::_CollectCopyInfo(const char* _source, 
int32& level,
 
 
 status_t
-CopyEngine::_CopyFolder(const char* _source, const char* _destination,
-       int32& level, sem_id cancelSemaphore)
+CopyEngine::_Copy(BEntry &source, BEntry &destination,
+       int32& level, sem_id cancelSemaphore, bool copyAttributes)
 {
        level++;
 
-       BDirectory source(_source);
-       status_t ret = source.InitCheck();
-       if (ret < B_OK)
+       struct stat sourceInfo;
+       status_t ret = source.GetStat(&sourceInfo);
+       if (ret != B_OK)
                return ret;
 
-       ret = create_directory(_destination, 0777);
-       if (ret < B_OK && ret != B_FILE_EXISTS) {
-               fprintf(stderr, "Could not create '%s': %s\n", _destination,
-                       strerror(ret));
-               return ret;
+       SemaphoreLocker lock(cancelSemaphore);
+       if (cancelSemaphore >= 0 && !lock.IsLocked()) {
+               // We are supposed to quit
+               return B_CANCELED;
        }
 
-       BDirectory destination(_destination);
-       ret = destination.InitCheck();
-       if (ret < B_OK)
+       BPath sourcePath(&source);
+       ret = sourcePath.InitCheck();
+       if (ret != B_OK)
                return ret;
 
-       BEntry entry;
-       while (source.GetNextEntry(&entry) == B_OK) {
-               SemaphoreLocker lock(cancelSemaphore);
-               if (cancelSemaphore >= 0 && !lock.IsLocked()) {
-                       // We are supposed to quit
-                       return B_CANCELED;
-               }
-
-               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());
+       BPath destPath(&destination);
+       ret = destPath.InitCheck();
+       if (ret != B_OK)
+               return ret;
 
-               struct stat statInfo;
-               entry.GetStat(&statInfo);
+       const char *relativeSourcePath = _RelativeEntryPath(sourcePath.Path());
+       if (fEntryFilter != NULL
+               && !fEntryFilter->ShouldCopyEntry(source, relativeSourcePath,
+                       sourceInfo, level)) {
+               // Silently skip the filtered entry.
+               return B_OK;
+       }
 
-               if (fEntryFilter != NULL
-                       && !fEntryFilter->ShouldCopyEntry(entry, 
relativeSourceEntryPath,
-                               statInfo, level)) {
-                       continue;
-               }
+       if (cancelSemaphore >= 0)
+               lock.Unlock();
 
-               fItemsCopied++;
-               fCurrentItem = name;
-               fCurrentTargetFolder = _destination;
-               _UpdateProgress();
+       if (S_ISDIR(sourceInfo.st_mode)) {
+               BDirectory sourceDirectory(&source);
+               ret = sourceDirectory.InitCheck();
+               if (ret != B_OK)
+                       return ret;
 
-               BEntry copy(&destination, name);
-               bool copyAttributes = true;
-
-               if (S_ISDIR(statInfo.st_mode)) {
-                       // handle recursive directory copy
-
-                       if (copy.Exists()) {
-                               ret = B_OK;
-                               if (copy.IsDirectory()) {
-                                       if (fEntryFilter
-                                               && 
fEntryFilter->ShouldClobberFolder(entry,
-                                                       
relativeSourceEntryPath, statInfo, level)) {
-                                               ret = _RemoveFolder(copy);
-                                       } else {
-                                               // Do not overwrite attributes 
on folders that exist.
-                                               // This should work better when 
the install target
-                                               // already contains a Haiku 
installation.
-                                               copyAttributes = false;
-                                       }
-                               } else
-                                       ret = copy.Remove();
-
-                               if (ret != B_OK) {
-                                       fprintf(stderr, "Failed to make room 
for folder '%s': "
-                                               "%s\n", name, strerror(ret));
-                                       return ret;
+               if (destination.Exists()) {
+                       if (destination.IsDirectory()) {
+                               if (fEntryFilter
+                                       && 
fEntryFilter->ShouldClobberFolder(source,
+                                               relativeSourcePath, sourceInfo, 
level)) {
+                                       ret = _RemoveFolder(destination);
+                               } else {
+                                       // Do not overwrite attributes on 
folders that exist.
+                                       // This should work better when the 
install target
+                                       // already contains a Haiku 
installation.
+                                       copyAttributes = false;
                                }
+                       } else {
+                               ret = destination.Remove();
                        }
 
-                       BPath dstFolder;
-                       ret = copy.GetPath(&dstFolder);
-                       if (ret < B_OK)
+                       if (ret != B_OK) {
+                               fprintf(stderr, "Failed to make room for folder 
'%s': "
+                                       "%s\n", sourcePath.Path(), 
strerror(ret));
                                return ret;
-
-                       if (cancelSemaphore >= 0)
-                               lock.Unlock();
-
-                       ret = _CopyFolder(sourceEntryPath.Path(), 
dstFolder.Path(), level,
-                               cancelSemaphore);
-                       if (ret < B_OK)
-                               return ret;
-
-                       if (cancelSemaphore >= 0 && !lock.Lock()) {
-                               // We are supposed to quit
-                               return B_CANCELED;
                        }
                } else {
-                       if (copy.Exists()) {
-                               if (copy.IsDirectory())
-                                       ret = _RemoveFolder(copy);
-                               else
-                                       ret = copy.Remove();
-                               if (ret != B_OK) {
-                                       fprintf(stderr, "Failed to make room 
for entry '%s': "
-                                               "%s\n", name, strerror(ret));
-                                       return ret;
-                               }
-                       }
-                       if (S_ISLNK(statInfo.st_mode)) {
-                               // copy symbolic links
-                               BSymLink srcLink(&entry);
-                               if (ret < B_OK)
-                                       return ret;
-
-                               char linkPath[B_PATH_NAME_LENGTH];
-                               ssize_t read = srcLink.ReadLink(linkPath, 
B_PATH_NAME_LENGTH - 1);
-                               if (read < 0)
-                                       return (status_t)read;
-
-                               // just in case it already exists...
-                               copy.Remove();
-
-                               BSymLink dstLink;
-                               ret = destination.CreateSymLink(name, linkPath, 
&dstLink);
-                               if (ret < B_OK)
-                                       return ret;
-                       } else {
-                               // copy file data
-                               // NOTE: Do not pass the locker, we simply keep 
holding the lock!
-                               ret = CopyFile(entry, copy);
-                               if (ret < B_OK)
-                                       return ret;
+                       ret = create_directory(destPath.Path(), 0777);
+                       if (ret != B_OK && ret != B_FILE_EXISTS) {
+                               fprintf(stderr, "Could not create '%s': %s\n", 
destPath.Path(),
+                                       strerror(ret));
+                               return ret;
                        }
                }
 
-               if (!copyAttributes)
-                       continue;
+               BDirectory destDirectory(&destination);
+               ret = destDirectory.InitCheck();
+               if (ret != B_OK)
+                       return ret;
 
-               ret = copy.SetTo(&destination, name);
+               BEntry entry;
+               while (sourceDirectory.GetNextEntry(&entry) == B_OK) {
+                       BEntry dest(&destDirectory, entry.Name());
+                       ret = dest.InitCheck();
+                       if (ret != B_OK)
+                               return ret;
+                       ret = _Copy(entry, dest, level,
+                                       cancelSemaphore, copyAttributes);
+                       if (ret != B_OK)
+                               return ret;
+               }
+       } else {
+               if (destination.Exists()) {
+                       if (destination.IsDirectory())
+                               ret = _RemoveFolder(destination);
+                       else
+                               ret = destination.Remove();
+                       if (ret != B_OK) {
+                               fprintf(stderr, "Failed to make room for entry 
'%s': "
+                                       "%s\n", sourcePath.Path(), 
strerror(ret));
+                               return ret;
+                       }
+               }
+
+               fItemsCopied++;
+               BPath destDirectory;
+               ret = destPath.GetParent(&destDirectory);
                if (ret != B_OK)
                        return ret;
+               fCurrentTargetFolder = destDirectory.Path();
+               fCurrentItem = sourcePath.Leaf();
+               _UpdateProgress();
+
+               if (S_ISLNK(sourceInfo.st_mode)) {
+                       // copy symbolic links
+                       BSymLink srcLink(&source);
+                       ret = srcLink.InitCheck();
+                       if (ret != B_OK)
+                               return ret;
+
+                       char linkPath[B_PATH_NAME_LENGTH];
+                       ssize_t read = srcLink.ReadLink(linkPath, 
B_PATH_NAME_LENGTH - 1);
+                       if (read < 0)
+                               return (status_t)read;
+
+                       BDirectory dstFolder;
+                       ret = destination.GetParent(&dstFolder);
+                       if (ret != B_OK)
+                               return ret;
+                       ret = dstFolder.CreateSymLink(sourcePath.Leaf(), 
linkPath, NULL);
+                       if (ret != B_OK)
+                               return ret;
+               } else {
+                       // copy file data
+                       // NOTE: Do not pass the locker, we simply keep holding 
the lock!
+                       ret = _CopyData(source, destination);
+                       if (ret != B_OK)
+                               return ret;
+               }
+       }
 
+       if (copyAttributes) {
                // copy attributes
-               BNode sourceNode(&entry);
-               BNode targetNode(&copy);
+               BNode sourceNode(&source);
+               BNode targetNode(&destination);
                char attrName[B_ATTR_NAME_LENGTH];
                while (sourceNode.GetNextAttrName(attrName) == B_OK) {
                        attr_info info;
-                       if (sourceNode.GetAttrInfo(attrName, &info) < B_OK)
+                       if (sourceNode.GetAttrInfo(attrName, &info) != B_OK)
                                continue;
                        size_t size = 4096;
                        uint8 buffer[size];
@@ -452,11 +460,11 @@ CopyEngine::_CopyFolder(const char* _source, const char* 
_destination,
                }
 
                // copy basic attributes
-               copy.SetPermissions(statInfo.st_mode);
-               copy.SetOwner(statInfo.st_uid);
-               copy.SetGroup(statInfo.st_gid);
-               copy.SetModificationTime(statInfo.st_mtime);
-               copy.SetCreationTime(statInfo.st_crtime);
+               destination.SetPermissions(sourceInfo.st_mode);
+               destination.SetOwner(sourceInfo.st_uid);
+               destination.SetGroup(sourceInfo.st_gid);
+               destination.SetModificationTime(sourceInfo.st_mtime);
+               destination.SetCreationTime(sourceInfo.st_crtime);
        }
 
        level--;
diff --git a/src/apps/installer/CopyEngine.h b/src/apps/installer/CopyEngine.h
index 298977225b..f988577cd5 100644
--- a/src/apps/installer/CopyEngine.h
+++ b/src/apps/installer/CopyEngine.h
@@ -32,20 +32,21 @@ public:
                        status_t                        CollectTargets(const 
char* source,
                                                                        sem_id 
cancelSemaphore = -1);
 
-                       status_t                        CopyFolder(const char* 
source,
+                       status_t                        Copy(const char* source,
                                                                        const 
char* destination,
-                                                                       sem_id 
cancelSemaphore = -1);
-
-                       status_t                        CopyFile(const BEntry& 
entry,
-                                                                       const 
BEntry& destination,
-                                                                       sem_id 
cancelSemaphore = -1);
+                                                                       sem_id 
cancelSemaphore = -1,
+                                                                       bool 
copyAttributes = true);
 
 private:
                        status_t                        _CollectCopyInfo(const 
char* source,
                                                                        int32& 
level, sem_id cancelSemaphore);
-                       status_t                        _CopyFolder(const char* 
source,
-                                                                       const 
char* destination,
-                                                                       int32& 
level, sem_id cancelSemaphore);
+                       status_t                        _Copy(BEntry& source,
+                                                                       BEntry& 
destination,
+                                                                       int32& 
level, sem_id cancelSemaphore,
+                                                                       bool 
copyAttributes);
+                       status_t                        _CopyData(const BEntry& 
entry,
+                                                                       const 
BEntry& destination,
+                                                                       sem_id 
cancelSemaphore = -1);
 
                        status_t                        _RemoveFolder(BEntry& 
entry);
 
diff --git a/src/apps/installer/WorkerThread.cpp 
b/src/apps/installer/WorkerThread.cpp
index f289f5bb4e..9cb87e0010 100644
--- a/src/apps/installer/WorkerThread.cpp
+++ b/src/apps/installer/WorkerThread.cpp
@@ -534,7 +534,7 @@ WorkerThread::_PerformInstall(partition_id 
sourcePartitionID,
        reporter.StartTimer();
 
        // copy source volume
-       err = engine.CopyFolder(srcDirectory.Path(), targetDirectory.Path(),
+       err = engine.Copy(srcDirectory.Path(), targetDirectory.Path(),
                fCancelSemaphore);
        if (err != B_OK)
                return _InstallationError(err);
@@ -546,7 +546,7 @@ WorkerThread::_PerformInstall(partition_id 
sourcePartitionID,
                for (int32 i = 0; i < count; i++) {
                        Package *p = 
static_cast<Package*>(fPackages->ItemAt(i));
                        BPath packageDir(pkgRootDir.Path(), p->Folder());
-                       err = engine.CopyFolder(packageDir.Path(), 
targetDirectory.Path(),
+                       err = engine.Copy(packageDir.Path(), 
targetDirectory.Path(),
                                fCancelSemaphore);
                        if (err != B_OK)
                                return _InstallationError(err);

############################################################################

Revision:    hrev53996
Commit:      f1e5a6c914a9341f2b874f43b8f945db7c895d4c
URL:         https://git.haiku-os.org/haiku/commit/?id=f1e5a6c914a9
Author:      Leorize <leorize+oss@xxxxxxxxxxx>
Date:        Sun Mar 22 17:28:48 2020 UTC
Committer:   Adrien Destugues <pulkomandy@xxxxxxxxx>
Commit-Date: Sun Mar 22 20:40:21 2020 UTC

Installer: supports installing .hpkg-based optional packages

Most of Installer was designed for old-style optional packages (files in
a folder that's copied to the target volume). This commit modifies
Installer so that it can process and install .hpkg packages.

Change-Id: Ib7d69a04ccb7879b956b5c3f0df1241c56e4987d
Reviewed-on: https://review.haiku-os.org/c/haiku/+/2400
Reviewed-by: waddlesplash <waddlesplash@xxxxxxxxx>

----------------------------------------------------------------------------

diff --git a/src/apps/installer/PackageViews.cpp 
b/src/apps/installer/PackageViews.cpp
index af39586ed0..25c2b827b6 100644
--- a/src/apps/installer/PackageViews.cpp
+++ b/src/apps/installer/PackageViews.cpp
@@ -34,13 +34,13 @@
 #define ICON_ATTRIBUTE "INSTALLER PACKAGE: ICON"
 
 
-Package::Package(const char *folder)
+Package::Package(const BPath &path)
        :
        Group(),
        fSize(0),
        fIcon(NULL)
 {
-       SetFolder(folder);
+       SetPath(path);
 }
 
 
@@ -62,7 +62,7 @@ Package::PackageFromEntry(BEntry &entry)
        if (info.InitCheck() != B_OK)
                return NULL;
 
-       Package *package = new Package(path.Path());
+       Package *package = new Package(path);
        package->fName = info.Name();
        package->fDescription = info.Summary();
 
diff --git a/src/apps/installer/PackageViews.h 
b/src/apps/installer/PackageViews.h
index 26c3f22736..6709b87b52 100644
--- a/src/apps/installer/PackageViews.h
+++ b/src/apps/installer/PackageViews.h
@@ -12,6 +12,7 @@
 #include <CheckBox.h>
 #include <Entry.h>
 #include <List.h>
+#include <Path.h>
 #include <String.h>
 #include <StringView.h>
 
@@ -31,11 +32,11 @@ private:
 
 class Package : public Group {
 public:
-                                                               Package(const 
char* folder);
+                                                               Package(const 
BPath &path);
        virtual                                         ~Package();
 
-                       void                            SetFolder(BString 
folder)
-                                                                       { 
fFolder = folder; }
+                       void                            SetPath(const BPath 
&path)
+                                                                       { fPath 
= path; }
                        void                            SetName(const BString 
name)
                                                                        { fName 
= name; }
                        void                            SetDescription(const 
BString description)
@@ -48,8 +49,8 @@ public:
                                                                        { 
fOnByDefault = onByDefault; }
                        void                            SetAlwaysOn(bool 
alwaysOn)
                                                                        { 
fAlwaysOn = alwaysOn; }
-                       BString                         Folder() const
-                                                                       { 
return fFolder; }
+                       BPath                           Path() const
+                                                                       { 
return fPath; }
                        BString                         Name() const
                                                                        { 
return fName; }
                        BString                         Description() const
@@ -68,7 +69,7 @@ public:
        static  Package*                        PackageFromEntry(BEntry &dir);
 
 private:
-                       BString                         fFolder;
+                       BPath                           fPath;
                        BString                         fName;
                        BString                         fDescription;
                        int32                           fSize;
diff --git a/src/apps/installer/WorkerThread.cpp 
b/src/apps/installer/WorkerThread.cpp
index 9cb87e0010..07d92d9c22 100644
--- a/src/apps/installer/WorkerThread.cpp
+++ b/src/apps/installer/WorkerThread.cpp
@@ -514,12 +514,14 @@ WorkerThread::_PerformInstall(partition_id 
sourcePartitionID,
 
        // Collect selected packages also
        if (fPackages) {
-               BPath pkgRootDir(srcDirectory.Path(), kPackagesDirectoryPath);
                int32 count = fPackages->CountItems();
                for (int32 i = 0; i < count; i++) {
                        Package *p = 
static_cast<Package*>(fPackages->ItemAt(i));
-                       BPath packageDir(pkgRootDir.Path(), p->Folder());
-                       err = engine.CollectTargets(packageDir.Path(), 
fCancelSemaphore);
+                       const BPath& pkgPath = p->Path();
+                       err = pkgPath.InitCheck();
+                       if (err != B_OK)
+                               return _InstallationError(err);
+                       err = engine.CollectTargets(pkgPath.Path(), 
fCancelSemaphore);
                        if (err != B_OK)
                                return _InstallationError(err);
                }
@@ -541,12 +543,24 @@ WorkerThread::_PerformInstall(partition_id 
sourcePartitionID,
 
        // copy selected packages
        if (fPackages) {
-               BPath pkgRootDir(srcDirectory.Path(), kPackagesDirectoryPath);
                int32 count = fPackages->CountItems();
+               // FIXME: find_directory doesn't return the folder in the 
target volume,
+               // so we are hard coding this for now.
+               BPath targetPkgDir(targetDirectory.Path(), "system/packages");
+               err = targetPkgDir.InitCheck();
+               if (err != B_OK)
+                       return _InstallationError(err);
                for (int32 i = 0; i < count; i++) {
                        Package *p = 
static_cast<Package*>(fPackages->ItemAt(i));
-                       BPath packageDir(pkgRootDir.Path(), p->Folder());
-                       err = engine.Copy(packageDir.Path(), 
targetDirectory.Path(),
+                       const BPath& pkgPath = p->Path();
+                       err = pkgPath.InitCheck();
+                       if (err != B_OK)
+                               return _InstallationError(err);
+                       BPath targetPath(targetPkgDir.Path(), pkgPath.Leaf());
+                       err = targetPath.InitCheck();
+                       if (err != B_OK)
+                               return _InstallationError(err);
+                       err = engine.Copy(pkgPath.Path(), targetPath.Path(),
                                fCancelSemaphore);
                        if (err != B_OK)
                                return _InstallationError(err);


Other related posts:

  • » [haiku-commits] haiku: hrev53996 - src/apps/installer - Adrien Destugues