Skip to content

Commit

Permalink
package daemon: Fix handling of multiple writable files
Browse files Browse the repository at this point in the history
When attempting to extract the second writable file from the package,
we noticed that the root directory already existed and assumed
everything had been already extracted. Now we first extract all files
and process them one by one afterwards. Fixes #10131.
  • Loading branch information
weinhold committed Oct 24, 2013
1 parent 0fea5e9 commit 080ef2e
Showing 1 changed file with 48 additions and 25 deletions.
73 changes: 48 additions & 25 deletions src/servers/package/Volume.cpp
Expand Up @@ -512,12 +512,7 @@ struct Volume::CommitTransactionHandler {
_AddUser(package, *user);

// handle global writable files
const BObjectList<BGlobalWritableFileInfo>& files
= package->Info().GlobalWritableFileInfos();
for (int32 i = 0; const BGlobalWritableFileInfo* file = files.ItemAt(i);
i++) {
_AddGlobalWritableFile(package, *file);
}
_AddGlobalWritableFiles(package);
}

void _AddGroup(Package* package, const BString& groupName)
Expand Down Expand Up @@ -612,10 +607,19 @@ struct Volume::CommitTransactionHandler {
}
}

void _AddGlobalWritableFile(Package* package,
const BGlobalWritableFileInfo& file)
void _AddGlobalWritableFiles(Package* package)
{
if (!file.IsIncluded())
// get the list of included files
const BObjectList<BGlobalWritableFileInfo>& files
= package->Info().GlobalWritableFileInfos();
BStringList contentPaths;
for (int32 i = 0; const BGlobalWritableFileInfo* file = files.ItemAt(i);
i++) {
if (file->IsIncluded() && !contentPaths.Add(file->Path()))
throw std::bad_alloc();
}

if (contentPaths.IsEmpty())
return;

// Open the root directory of the installation location where we will
Expand Down Expand Up @@ -645,9 +649,22 @@ struct Volume::CommitTransactionHandler {

// extract files into a subdir of the writable-files directory
BDirectory extractedFilesDirectory;
_ExtractPackageContent(package, file.Path(),
_ExtractPackageContent(package, contentPaths,
fWritableFilesDirectory, extractedFilesDirectory);

for (int32 i = 0; const BGlobalWritableFileInfo* file = files.ItemAt(i);
i++) {
if (file->IsIncluded()) {
_AddGlobalWritableFile(package, *file, rootDirectory,
extractedFilesDirectory);
}
}
}

void _AddGlobalWritableFile(Package* package,
const BGlobalWritableFileInfo& file, const BDirectory& rootDirectory,
const BDirectory& extractedFilesDirectory)
{
// Map the path name to the actual target location. Currently this only
// concerns "settings/", which is mapped to "settings/global/".
BString targetPath(file.Path());
Expand All @@ -662,7 +679,7 @@ struct Volume::CommitTransactionHandler {

// open parent directory of the source entry
const char* lastSlash = strrchr(file.Path(), '/');
BDirectory* sourceDirectory;
const BDirectory* sourceDirectory;
BDirectory stackSourceDirectory;
if (lastSlash != NULL) {
sourceDirectory = &stackSourceDirectory;
Expand All @@ -671,8 +688,8 @@ struct Volume::CommitTransactionHandler {
if (sourceParentPath.Length() == 0)
throw std::bad_alloc();

error = stackSourceDirectory.SetTo(&extractedFilesDirectory,
sourceParentPath);
status_t error = stackSourceDirectory.SetTo(
&extractedFilesDirectory, sourceParentPath);
if (error != B_OK) {
throw Exception(error,
BString().SetToFormat("failed to open directory \"%s\"",
Expand All @@ -696,7 +713,7 @@ struct Volume::CommitTransactionHandler {
throw std::bad_alloc();

BDirectory targetDirectory;
error = FSUtils::OpenSubDirectory(rootDirectory,
status_t error = FSUtils::OpenSubDirectory(rootDirectory,
RelativePath(targetParentPath), true, targetDirectory);
if (error != B_OK) {
throw Exception(error,
Expand All @@ -718,8 +735,8 @@ struct Volume::CommitTransactionHandler {
}

void _AddGlobalWritableFileRecurse(Package* package,
BDirectory& sourceDirectory, FSUtils::Path& relativeSourcePath,
BDirectory& targetDirectory, const char* targetName,
const BDirectory& sourceDirectory, FSUtils::Path& relativeSourcePath,
const BDirectory& targetDirectory, const char* targetName,
BWritableFileUpdateType updateType)
{
// * If the file doesn't exist, just copy the extracted one.
Expand Down Expand Up @@ -1115,8 +1132,9 @@ struct Volume::CommitTransactionHandler {
return path.IsEmpty() ? fallback : path;
}

void _ExtractPackageContent(Package* package, const char* contentPath,
BDirectory& targetDirectory, BDirectory& _extractedFilesDirectory)
void _ExtractPackageContent(Package* package,
const BStringList& contentPaths, BDirectory& targetDirectory,
BDirectory& _extractedFilesDirectory)
{
// check whether the subdirectory already exists
BString targetName(package->RevisionedNameThrows());
Expand Down Expand Up @@ -1199,13 +1217,18 @@ struct Volume::CommitTransactionHandler {
NotOwningEntryRef packageRef(fVolume->fPackagesDirectoryRef,
package->FileName());

error = FSUtils::ExtractPackageContent(FSUtils::Entry(packageRef),
contentPath, FSUtils::Entry(subDirectory));
if (error != B_OK) {
throw Exception(error,
BString().SetToFormat("failed to extract \"%s\" from package",
contentPath),
package->FileName());
int32 contentPathCount = contentPaths.CountStrings();
for (int32 i = 0; i < contentPathCount; i++) {
const char* contentPath = contentPaths.StringAt(i);

error = FSUtils::ExtractPackageContent(FSUtils::Entry(packageRef),
contentPath, FSUtils::Entry(subDirectory));
if (error != B_OK) {
throw Exception(error,
BString().SetToFormat(
"failed to extract \"%s\" from package", contentPath),
package->FileName());
}
}

// tag all entries with the package attribute
Expand Down

0 comments on commit 080ef2e

Please sign in to comment.