package daemon: Sever Volume-CommitTransactionHandler friendship
Move quite a bit of transaction related methods from Volume to CommitTransactionHandler.
This commit is contained in:
@@ -9,11 +9,14 @@
|
|||||||
|
|
||||||
#include "CommitTransactionHandler.h"
|
#include "CommitTransactionHandler.h"
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
#include <grp.h>
|
#include <grp.h>
|
||||||
#include <pwd.h>
|
#include <pwd.h>
|
||||||
|
|
||||||
|
#include <File.h>
|
||||||
#include <Path.h>
|
#include <Path.h>
|
||||||
|
|
||||||
|
#include <AutoDeleter.h>
|
||||||
#include <CopyEngine.h>
|
#include <CopyEngine.h>
|
||||||
#include <NotOwningEntryRef.h>
|
#include <NotOwningEntryRef.h>
|
||||||
#include <package/DaemonDefs.h>
|
#include <package/DaemonDefs.h>
|
||||||
@@ -83,7 +86,7 @@ CommitTransactionHandler::HandleRequest(
|
|||||||
const BActivationTransaction& transaction, BMessage* reply)
|
const BActivationTransaction& transaction, BMessage* reply)
|
||||||
{
|
{
|
||||||
// check the change count
|
// check the change count
|
||||||
if (transaction.ChangeCount() != fVolume->fState->ChangeCount())
|
if (transaction.ChangeCount() != fVolume->State()->ChangeCount())
|
||||||
throw Exception(B_DAEMON_CHANGE_COUNT_MISMATCH);
|
throw Exception(B_DAEMON_CHANGE_COUNT_MISMATCH);
|
||||||
|
|
||||||
// collect the packages to deactivate
|
// collect the packages to deactivate
|
||||||
@@ -153,7 +156,7 @@ CommitTransactionHandler::_GetPackagesToDeactivate(
|
|||||||
|
|
||||||
for (int32 i = 0; i < packagesToDeactivateCount; i++) {
|
for (int32 i = 0; i < packagesToDeactivateCount; i++) {
|
||||||
BString packageName = packagesToDeactivate.StringAt(i);
|
BString packageName = packagesToDeactivate.StringAt(i);
|
||||||
Package* package = fVolume->fState->FindPackage(packageName);
|
Package* package = fVolume->State()->FindPackage(packageName);
|
||||||
if (package == NULL) {
|
if (package == NULL) {
|
||||||
throw Exception(B_DAEMON_NO_SUCH_PACKAGE, "no such package",
|
throw Exception(B_DAEMON_NO_SUCH_PACKAGE, "no such package",
|
||||||
packageName);
|
packageName);
|
||||||
@@ -195,8 +198,7 @@ CommitTransactionHandler::_ReadPackagesToActivate(
|
|||||||
RelativePath directoryPath(kAdminDirectoryName,
|
RelativePath directoryPath(kAdminDirectoryName,
|
||||||
transactionDirectoryName);
|
transactionDirectoryName);
|
||||||
BDirectory directory;
|
BDirectory directory;
|
||||||
status_t error = fVolume->_OpenPackagesSubDirectory(directoryPath,
|
status_t error = _OpenPackagesSubDirectory(directoryPath, false, directory);
|
||||||
false, directory);
|
|
||||||
if (error != B_OK)
|
if (error != B_OK)
|
||||||
throw Exception(error, "failed to open transaction directory");
|
throw Exception(error, "failed to open transaction directory");
|
||||||
|
|
||||||
@@ -211,7 +213,7 @@ CommitTransactionHandler::_ReadPackagesToActivate(
|
|||||||
BString packageName = packagesToActivate.StringAt(i);
|
BString packageName = packagesToActivate.StringAt(i);
|
||||||
|
|
||||||
// make sure it doesn't clash with an already existing package
|
// make sure it doesn't clash with an already existing package
|
||||||
Package* package = fVolume->fState->FindPackage(packageName);
|
Package* package = fVolume->State()->FindPackage(packageName);
|
||||||
if (package != NULL) {
|
if (package != NULL) {
|
||||||
if (fPackagesAlreadyAdded.find(package)
|
if (fPackagesAlreadyAdded.find(package)
|
||||||
!= fPackagesAlreadyAdded.end()) {
|
!= fPackagesAlreadyAdded.end()) {
|
||||||
@@ -262,7 +264,7 @@ CommitTransactionHandler::_ApplyChanges(BMessage* reply)
|
|||||||
_AddPackagesToActivate();
|
_AddPackagesToActivate();
|
||||||
|
|
||||||
// activate/deactivate packages
|
// activate/deactivate packages
|
||||||
fVolume->_ChangePackageActivation(fAddedPackages, fRemovedPackages);
|
_ChangePackageActivation(fAddedPackages, fRemovedPackages);
|
||||||
|
|
||||||
// run post-installation scripts
|
// run post-installation scripts
|
||||||
_RunPostInstallScripts();
|
_RunPostInstallScripts();
|
||||||
@@ -294,7 +296,7 @@ CommitTransactionHandler::_CreateOldStateDirectory(BMessage* reply)
|
|||||||
|
|
||||||
// make sure the directory doesn't exist yet
|
// make sure the directory doesn't exist yet
|
||||||
BDirectory adminDirectory;
|
BDirectory adminDirectory;
|
||||||
status_t error = fVolume->_OpenPackagesSubDirectory(
|
status_t error = _OpenPackagesSubDirectory(
|
||||||
RelativePath(kAdminDirectoryName), true, adminDirectory);
|
RelativePath(kAdminDirectoryName), true, adminDirectory);
|
||||||
if (error != B_OK)
|
if (error != B_OK)
|
||||||
throw Exception(error, "failed to open administrative directory");
|
throw Exception(error, "failed to open administrative directory");
|
||||||
@@ -322,7 +324,7 @@ CommitTransactionHandler::_CreateOldStateDirectory(BMessage* reply)
|
|||||||
|
|
||||||
// write the old activation file
|
// write the old activation file
|
||||||
BEntry activationFile;
|
BEntry activationFile;
|
||||||
error = fVolume->_WriteActivationFile(
|
error = _WriteActivationFile(
|
||||||
RelativePath(kAdminDirectoryName, directoryName),
|
RelativePath(kAdminDirectoryName, directoryName),
|
||||||
kActivationFileName, PackageSet(), PackageSet(), activationFile);
|
kActivationFileName, PackageSet(), PackageSet(), activationFile);
|
||||||
if (error != B_OK)
|
if (error != B_OK)
|
||||||
@@ -353,7 +355,7 @@ CommitTransactionHandler::_RemovePackagesToDeactivate()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// get a BEntry for the package
|
// get a BEntry for the package
|
||||||
NotOwningEntryRef entryRef(fVolume->fPackagesDirectoryRef,
|
NotOwningEntryRef entryRef(fVolume->PackagesDirectoryRef(),
|
||||||
package->FileName());
|
package->FileName());
|
||||||
|
|
||||||
BEntry entry;
|
BEntry entry;
|
||||||
@@ -386,7 +388,7 @@ CommitTransactionHandler::_AddPackagesToActivate()
|
|||||||
// open packages directory
|
// open packages directory
|
||||||
BDirectory packagesDirectory;
|
BDirectory packagesDirectory;
|
||||||
status_t error
|
status_t error
|
||||||
= packagesDirectory.SetTo(&fVolume->fPackagesDirectoryRef);
|
= packagesDirectory.SetTo(&fVolume->PackagesDirectoryRef());
|
||||||
if (error != B_OK)
|
if (error != B_OK)
|
||||||
throw Exception(error, "failed to open packages directory");
|
throw Exception(error, "failed to open packages directory");
|
||||||
|
|
||||||
@@ -426,7 +428,7 @@ CommitTransactionHandler::_AddPackagesToActivate()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// also add the package to the volume
|
// also add the package to the volume
|
||||||
fVolume->_AddPackage(package);
|
fVolume->State()->AddPackage(package);
|
||||||
|
|
||||||
_PreparePackageToActivate(package);
|
_PreparePackageToActivate(package);
|
||||||
}
|
}
|
||||||
@@ -567,7 +569,7 @@ CommitTransactionHandler::_AddGlobalWritableFiles(Package* package)
|
|||||||
// Open the root directory of the installation location where we will
|
// Open the root directory of the installation location where we will
|
||||||
// extract the files -- that's the volume's root directory.
|
// extract the files -- that's the volume's root directory.
|
||||||
BDirectory rootDirectory;
|
BDirectory rootDirectory;
|
||||||
status_t error = rootDirectory.SetTo(&fVolume->fRootDirectoryRef);
|
status_t error = rootDirectory.SetTo(&fVolume->RootDirectoryRef());
|
||||||
if (error != B_OK) {
|
if (error != B_OK) {
|
||||||
throw Exception(error,
|
throw Exception(error,
|
||||||
BString().SetToFormat("failed to get the root directory "
|
BString().SetToFormat("failed to get the root directory "
|
||||||
@@ -577,7 +579,7 @@ CommitTransactionHandler::_AddGlobalWritableFiles(Package* package)
|
|||||||
|
|
||||||
// Open writable-files directory in the administrative directory.
|
// Open writable-files directory in the administrative directory.
|
||||||
if (fWritableFilesDirectory.InitCheck() != B_OK) {
|
if (fWritableFilesDirectory.InitCheck() != B_OK) {
|
||||||
error = fVolume->_OpenPackagesSubDirectory(
|
error = _OpenPackagesSubDirectory(
|
||||||
RelativePath(kAdminDirectoryName, kWritableFilesDirectoryName),
|
RelativePath(kAdminDirectoryName, kWritableFilesDirectoryName),
|
||||||
true, fWritableFilesDirectory);
|
true, fWritableFilesDirectory);
|
||||||
|
|
||||||
@@ -612,7 +614,7 @@ CommitTransactionHandler::_AddGlobalWritableFile(Package* package,
|
|||||||
// Map the path name to the actual target location. Currently this only
|
// Map the path name to the actual target location. Currently this only
|
||||||
// concerns "settings/", which is mapped to "settings/global/".
|
// concerns "settings/", which is mapped to "settings/global/".
|
||||||
BString targetPath(file.Path());
|
BString targetPath(file.Path());
|
||||||
if (fVolume->fMountType == PACKAGE_FS_MOUNT_TYPE_HOME) {
|
if (fVolume->MountType() == PACKAGE_FS_MOUNT_TYPE_HOME) {
|
||||||
if (targetPath == "settings"
|
if (targetPath == "settings"
|
||||||
|| targetPath.StartsWith("settings/")) {
|
|| targetPath.StartsWith("settings/")) {
|
||||||
targetPath.Insert("/global", 8);
|
targetPath.Insert("/global", 8);
|
||||||
@@ -944,13 +946,13 @@ CommitTransactionHandler::_RevertAddPackagesToActivate()
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
fVolume->_RemovePackage(package);
|
fVolume->State()->RemovePackage(package);
|
||||||
|
|
||||||
if (transactionDirectory.InitCheck() != B_OK)
|
if (transactionDirectory.InitCheck() != B_OK)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// get BEntry for the package
|
// get BEntry for the package
|
||||||
NotOwningEntryRef entryRef(fVolume->fPackagesDirectoryRef,
|
NotOwningEntryRef entryRef(fVolume->PackagesDirectoryRef(),
|
||||||
package->FileName());
|
package->FileName());
|
||||||
|
|
||||||
BEntry entry;
|
BEntry entry;
|
||||||
@@ -982,7 +984,7 @@ CommitTransactionHandler::_RevertRemovePackagesToDeactivate()
|
|||||||
// open packages directory
|
// open packages directory
|
||||||
BDirectory packagesDirectory;
|
BDirectory packagesDirectory;
|
||||||
status_t error
|
status_t error
|
||||||
= packagesDirectory.SetTo(&fVolume->fPackagesDirectoryRef);
|
= packagesDirectory.SetTo(&fVolume->PackagesDirectoryRef());
|
||||||
if (error != B_OK) {
|
if (error != B_OK) {
|
||||||
throw Exception(error, "failed to open packages directory");
|
throw Exception(error, "failed to open packages directory");
|
||||||
ERROR("failed to open packages directory: %s\n",
|
ERROR("failed to open packages directory: %s\n",
|
||||||
@@ -1061,7 +1063,7 @@ void
|
|||||||
CommitTransactionHandler::_RunPostInstallScript(Package* package,
|
CommitTransactionHandler::_RunPostInstallScript(Package* package,
|
||||||
const BString& script)
|
const BString& script)
|
||||||
{
|
{
|
||||||
BDirectory rootDir(&fVolume->fRootDirectoryRef);
|
BDirectory rootDir(&fVolume->RootDirectoryRef());
|
||||||
BPath scriptPath(&rootDir, script);
|
BPath scriptPath(&rootDir, script);
|
||||||
status_t error = scriptPath.InitCheck();
|
status_t error = scriptPath.InitCheck();
|
||||||
if (error != B_OK) {
|
if (error != B_OK) {
|
||||||
@@ -1083,15 +1085,6 @@ CommitTransactionHandler::_RunPostInstallScript(Package* package,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*static*/ BString
|
|
||||||
CommitTransactionHandler::_GetPath(const FSUtils::Entry& entry,
|
|
||||||
const BString& fallback)
|
|
||||||
{
|
|
||||||
BString path = entry.Path();
|
|
||||||
return path.IsEmpty() ? fallback : path;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
CommitTransactionHandler::_ExtractPackageContent(Package* package,
|
CommitTransactionHandler::_ExtractPackageContent(Package* package,
|
||||||
const BStringList& contentPaths, BDirectory& targetDirectory,
|
const BStringList& contentPaths, BDirectory& targetDirectory,
|
||||||
@@ -1175,7 +1168,7 @@ CommitTransactionHandler::_ExtractPackageContent(Package* package,
|
|||||||
createSubDirectoryOperation.Finished();
|
createSubDirectoryOperation.Finished();
|
||||||
|
|
||||||
// extract
|
// extract
|
||||||
NotOwningEntryRef packageRef(fVolume->fPackagesDirectoryRef,
|
NotOwningEntryRef packageRef(fVolume->PackagesDirectoryRef(),
|
||||||
package->FileName());
|
package->FileName());
|
||||||
|
|
||||||
int32 contentPathCount = contentPaths.CountStrings();
|
int32 contentPathCount = contentPaths.CountStrings();
|
||||||
@@ -1222,6 +1215,266 @@ CommitTransactionHandler::_ExtractPackageContent(Package* package,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
CommitTransactionHandler::_OpenPackagesSubDirectory(const RelativePath& path,
|
||||||
|
bool create, BDirectory& _directory)
|
||||||
|
{
|
||||||
|
// open the packages directory
|
||||||
|
BDirectory directory;
|
||||||
|
status_t error = directory.SetTo(&fVolume->PackagesDirectoryRef());
|
||||||
|
if (error != B_OK) {
|
||||||
|
ERROR("CommitTransactionHandler::_OpenPackagesSubDirectory(): failed "
|
||||||
|
"to open packages directory: %s\n", strerror(error));
|
||||||
|
RETURN_ERROR(error);
|
||||||
|
}
|
||||||
|
|
||||||
|
return FSUtils::OpenSubDirectory(directory, path, create, _directory);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
CommitTransactionHandler::_OpenPackagesFile(
|
||||||
|
const RelativePath& subDirectoryPath, const char* fileName, uint32 openMode,
|
||||||
|
BFile& _file, BEntry* _entry)
|
||||||
|
{
|
||||||
|
BDirectory directory;
|
||||||
|
if (!subDirectoryPath.IsEmpty()) {
|
||||||
|
status_t error = _OpenPackagesSubDirectory(subDirectoryPath,
|
||||||
|
(openMode & B_CREATE_FILE) != 0, directory);
|
||||||
|
if (error != B_OK) {
|
||||||
|
ERROR("CommitTransactionHandler::_OpenPackagesFile(): failed to "
|
||||||
|
"open packages subdirectory \"%s\": %s\n",
|
||||||
|
subDirectoryPath.ToString().String(), strerror(error));
|
||||||
|
RETURN_ERROR(error);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
status_t error = directory.SetTo(&fVolume->PackagesDirectoryRef());
|
||||||
|
if (error != B_OK) {
|
||||||
|
ERROR("CommitTransactionHandler::_OpenPackagesFile(): failed to "
|
||||||
|
"open packages directory: %s\n", strerror(error));
|
||||||
|
RETURN_ERROR(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BEntry stackEntry;
|
||||||
|
BEntry& entry = _entry != NULL ? *_entry : stackEntry;
|
||||||
|
status_t error = entry.SetTo(&directory, fileName);
|
||||||
|
if (error != B_OK) {
|
||||||
|
ERROR("CommitTransactionHandler::_OpenPackagesFile(): failed to get "
|
||||||
|
"entry for file: %s", strerror(error));
|
||||||
|
RETURN_ERROR(error);
|
||||||
|
}
|
||||||
|
|
||||||
|
return _file.SetTo(&entry, openMode);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
CommitTransactionHandler::_WriteActivationFile(
|
||||||
|
const RelativePath& directoryPath, const char* fileName,
|
||||||
|
const PackageSet& toActivate, const PackageSet& toDeactivate,
|
||||||
|
BEntry& _entry)
|
||||||
|
{
|
||||||
|
// create the content
|
||||||
|
BString activationFileContent;
|
||||||
|
status_t error = _CreateActivationFileContent(toActivate, toDeactivate,
|
||||||
|
activationFileContent);
|
||||||
|
if (error != B_OK)
|
||||||
|
return error;
|
||||||
|
|
||||||
|
// write the file
|
||||||
|
error = _WriteTextFile(directoryPath, fileName, activationFileContent,
|
||||||
|
_entry);
|
||||||
|
if (error != B_OK) {
|
||||||
|
ERROR("CommitTransactionHandler::_WriteActivationFile(): failed to "
|
||||||
|
"write activation file \"%s/%s\": %s\n",
|
||||||
|
directoryPath.ToString().String(), fileName, strerror(error));
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
CommitTransactionHandler::_CreateActivationFileContent(
|
||||||
|
const PackageSet& toActivate, const PackageSet& toDeactivate,
|
||||||
|
BString& _content)
|
||||||
|
{
|
||||||
|
BString activationFileContent;
|
||||||
|
for (PackageFileNameHashTable::Iterator it
|
||||||
|
= fVolume->State()->ByFileNameIterator();
|
||||||
|
Package* package = it.Next();) {
|
||||||
|
if (package->IsActive()
|
||||||
|
&& toDeactivate.find(package) == toDeactivate.end()) {
|
||||||
|
int32 length = activationFileContent.Length();
|
||||||
|
activationFileContent << package->FileName() << '\n';
|
||||||
|
if (activationFileContent.Length()
|
||||||
|
< length + package->FileName().Length() + 1) {
|
||||||
|
return B_NO_MEMORY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (PackageSet::const_iterator it = toActivate.begin();
|
||||||
|
it != toActivate.end(); ++it) {
|
||||||
|
Package* package = *it;
|
||||||
|
int32 length = activationFileContent.Length();
|
||||||
|
activationFileContent << package->FileName() << '\n';
|
||||||
|
if (activationFileContent.Length()
|
||||||
|
< length + package->FileName().Length() + 1) {
|
||||||
|
return B_NO_MEMORY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_content = activationFileContent;
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
CommitTransactionHandler::_WriteTextFile(const RelativePath& directoryPath,
|
||||||
|
const char* fileName, const BString& content, BEntry& _entry)
|
||||||
|
{
|
||||||
|
BFile file;
|
||||||
|
status_t error = _OpenPackagesFile(directoryPath,
|
||||||
|
fileName, B_READ_WRITE | B_CREATE_FILE | B_ERASE_FILE, file, &_entry);
|
||||||
|
if (error != B_OK) {
|
||||||
|
ERROR("CommitTransactionHandler::_WriteTextFile(): failed to create "
|
||||||
|
"file \"%s/%s\": %s\n", directoryPath.ToString().String(), fileName,
|
||||||
|
strerror(error));
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
ssize_t bytesWritten = file.Write(content.String(),
|
||||||
|
content.Length());
|
||||||
|
if (bytesWritten < 0) {
|
||||||
|
ERROR("CommitTransactionHandler::_WriteTextFile(): failed to write "
|
||||||
|
"file \"%s/%s\": %s\n", directoryPath.ToString().String(), fileName,
|
||||||
|
strerror(bytesWritten));
|
||||||
|
return bytesWritten;
|
||||||
|
}
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
CommitTransactionHandler::_ChangePackageActivation(
|
||||||
|
const PackageSet& packagesToActivate,
|
||||||
|
const PackageSet& packagesToDeactivate)
|
||||||
|
{
|
||||||
|
INFORM("CommitTransactionHandler::_ChangePackageActivation(): activating "
|
||||||
|
"%zu, deactivating %zu packages\n", packagesToActivate.size(),
|
||||||
|
packagesToDeactivate.size());
|
||||||
|
|
||||||
|
// write the temporary package activation file
|
||||||
|
BEntry activationFileEntry;
|
||||||
|
status_t error = _WriteActivationFile(RelativePath(kAdminDirectoryName),
|
||||||
|
kTemporaryActivationFileName, packagesToActivate, packagesToDeactivate,
|
||||||
|
activationFileEntry);
|
||||||
|
if (error != B_OK)
|
||||||
|
throw Exception(error, "failed to write activation file");
|
||||||
|
|
||||||
|
// compute the size of the allocation we need for the activation change
|
||||||
|
// request
|
||||||
|
int32 itemCount = packagesToActivate.size() + packagesToDeactivate.size();
|
||||||
|
size_t requestSize = sizeof(PackageFSActivationChangeRequest)
|
||||||
|
+ itemCount * sizeof(PackageFSActivationChangeItem);
|
||||||
|
|
||||||
|
for (PackageSet::iterator it = packagesToActivate.begin();
|
||||||
|
it != packagesToActivate.end(); ++it) {
|
||||||
|
requestSize += (*it)->FileName().Length() + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (PackageSet::iterator it = packagesToDeactivate.begin();
|
||||||
|
it != packagesToDeactivate.end(); ++it) {
|
||||||
|
requestSize += (*it)->FileName().Length() + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// allocate and prepare the request
|
||||||
|
PackageFSActivationChangeRequest* request
|
||||||
|
= (PackageFSActivationChangeRequest*)malloc(requestSize);
|
||||||
|
if (request == NULL)
|
||||||
|
throw Exception(B_NO_MEMORY);
|
||||||
|
MemoryDeleter requestDeleter(request);
|
||||||
|
|
||||||
|
request->itemCount = itemCount;
|
||||||
|
|
||||||
|
PackageFSActivationChangeItem* item = &request->items[0];
|
||||||
|
char* nameBuffer = (char*)(item + itemCount);
|
||||||
|
|
||||||
|
for (PackageSet::iterator it = packagesToActivate.begin();
|
||||||
|
it != packagesToActivate.end(); ++it, item++) {
|
||||||
|
_FillInActivationChangeItem(item, PACKAGE_FS_ACTIVATE_PACKAGE, *it,
|
||||||
|
nameBuffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (PackageSet::iterator it = packagesToDeactivate.begin();
|
||||||
|
it != packagesToDeactivate.end(); ++it, item++) {
|
||||||
|
_FillInActivationChangeItem(item, PACKAGE_FS_DEACTIVATE_PACKAGE, *it,
|
||||||
|
nameBuffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
// issue the request
|
||||||
|
int fd = fVolume->OpenRootDirectory();
|
||||||
|
if (fd < 0)
|
||||||
|
throw Exception(fd, "failed to open root directory");
|
||||||
|
FileDescriptorCloser fdCloser(fd);
|
||||||
|
|
||||||
|
if (ioctl(fd, PACKAGE_FS_OPERATION_CHANGE_ACTIVATION, request, requestSize)
|
||||||
|
!= 0) {
|
||||||
|
// TODO: We need more error information and error handling!
|
||||||
|
throw Exception(errno, "ioctl() to de-/activate packages failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
// rename the temporary activation file to the final file
|
||||||
|
error = activationFileEntry.Rename(kActivationFileName, true);
|
||||||
|
if (error != B_OK) {
|
||||||
|
throw Exception(error,
|
||||||
|
"failed to rename temporary activation file to final file");
|
||||||
|
// TODO: We should probably try to reverse the activation changes, though that
|
||||||
|
// will fail, if this method has been called in response to node monitoring
|
||||||
|
// events. Alternatively moving the package activation file could be made part
|
||||||
|
// of the ioctl(), since packagefs should be able to undo package changes until
|
||||||
|
// the very end, unless running out of memory. In the end the situation would be
|
||||||
|
// bad anyway, though, since the activation file may refer to removed packages
|
||||||
|
// and things would be in an inconsistent state after rebooting.
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update our state, i.e. remove deactivated packages and mark activated
|
||||||
|
// packages accordingly.
|
||||||
|
fVolume->State()->ActivationChanged(packagesToActivate,
|
||||||
|
packagesToDeactivate);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
CommitTransactionHandler::_FillInActivationChangeItem(
|
||||||
|
PackageFSActivationChangeItem* item, PackageFSActivationChangeType type,
|
||||||
|
Package* package, char*& nameBuffer)
|
||||||
|
{
|
||||||
|
item->type = type;
|
||||||
|
item->packageDeviceID = package->NodeRef().device;
|
||||||
|
item->packageNodeID = package->NodeRef().node;
|
||||||
|
item->nameLength = package->FileName().Length();
|
||||||
|
item->parentDeviceID = fVolume->PackagesDeviceID();
|
||||||
|
item->parentDirectoryID = fVolume->PackagesDirectoryID();
|
||||||
|
item->name = nameBuffer;
|
||||||
|
strcpy(nameBuffer, package->FileName());
|
||||||
|
nameBuffer += package->FileName().Length() + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*static*/ BString
|
||||||
|
CommitTransactionHandler::_GetPath(const FSUtils::Entry& entry,
|
||||||
|
const BString& fallback)
|
||||||
|
{
|
||||||
|
BString path = entry.Path();
|
||||||
|
return path.IsEmpty() ? fallback : path;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*static*/ status_t
|
/*static*/ status_t
|
||||||
CommitTransactionHandler::_TagPackageEntriesRecursively(BDirectory& directory,
|
CommitTransactionHandler::_TagPackageEntriesRecursively(BDirectory& directory,
|
||||||
const BString& value, bool nonDirectoriesOnly)
|
const BString& value, bool nonDirectoriesOnly)
|
||||||
|
|||||||
@@ -80,14 +80,45 @@ private:
|
|||||||
void _RunPostInstallScript(Package* package,
|
void _RunPostInstallScript(Package* package,
|
||||||
const BString& script);
|
const BString& script);
|
||||||
|
|
||||||
static BString _GetPath(const FSUtils::Entry& entry,
|
|
||||||
const BString& fallback);
|
|
||||||
|
|
||||||
void _ExtractPackageContent(Package* package,
|
void _ExtractPackageContent(Package* package,
|
||||||
const BStringList& contentPaths,
|
const BStringList& contentPaths,
|
||||||
BDirectory& targetDirectory,
|
BDirectory& targetDirectory,
|
||||||
BDirectory& _extractedFilesDirectory);
|
BDirectory& _extractedFilesDirectory);
|
||||||
|
|
||||||
|
status_t _OpenPackagesSubDirectory(
|
||||||
|
const RelativePath& path, bool create,
|
||||||
|
BDirectory& _directory);
|
||||||
|
status_t _OpenPackagesFile(
|
||||||
|
const RelativePath& subDirectoryPath,
|
||||||
|
const char* fileName, uint32 openMode,
|
||||||
|
BFile& _file, BEntry* _entry = NULL);
|
||||||
|
|
||||||
|
status_t _WriteActivationFile(
|
||||||
|
const RelativePath& directoryPath,
|
||||||
|
const char* fileName,
|
||||||
|
const PackageSet& toActivate,
|
||||||
|
const PackageSet& toDeactivate,
|
||||||
|
BEntry& _entry);
|
||||||
|
status_t _CreateActivationFileContent(
|
||||||
|
const PackageSet& toActivate,
|
||||||
|
const PackageSet& toDeactivate,
|
||||||
|
BString& _content);
|
||||||
|
status_t _WriteTextFile(
|
||||||
|
const RelativePath& directoryPath,
|
||||||
|
const char* fileName,
|
||||||
|
const BString& content, BEntry& _entry);
|
||||||
|
void _ChangePackageActivation(
|
||||||
|
const PackageSet& packagesToActivate,
|
||||||
|
const PackageSet& packagesToDeactivate);
|
||||||
|
// throws Exception
|
||||||
|
void _FillInActivationChangeItem(
|
||||||
|
PackageFSActivationChangeItem* item,
|
||||||
|
PackageFSActivationChangeType type,
|
||||||
|
Package* package, char*& nameBuffer);
|
||||||
|
|
||||||
|
static BString _GetPath(const FSUtils::Entry& entry,
|
||||||
|
const BString& fallback);
|
||||||
|
|
||||||
static status_t _TagPackageEntriesRecursively(
|
static status_t _TagPackageEntriesRecursively(
|
||||||
BDirectory& directory, const BString& value,
|
BDirectory& directory, const BString& value,
|
||||||
bool nonDirectoriesOnly);
|
bool nonDirectoriesOnly);
|
||||||
|
|||||||
@@ -793,7 +793,7 @@ INFORM("Volume::_PackagesEntryCreated(\"%s\")\n", name);
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
_AddPackage(package);
|
fState->AddPackage(package);
|
||||||
packageDeleter.Detach();
|
packageDeleter.Detach();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -827,7 +827,7 @@ INFORM("Volume::_PackagesEntryRemoved(\"%s\")\n", name);
|
|||||||
|
|
||||||
// If the package isn't active, just remove it for good.
|
// If the package isn't active, just remove it for good.
|
||||||
if (!package->IsActive()) {
|
if (!package->IsActive()) {
|
||||||
_RemovePackage(package);
|
fState->RemovePackage(package);
|
||||||
delete package;
|
delete package;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -842,35 +842,6 @@ INFORM("Volume::_PackagesEntryRemoved(\"%s\")\n", name);
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
Volume::_FillInActivationChangeItem(PackageFSActivationChangeItem* item,
|
|
||||||
PackageFSActivationChangeType type, Package* package, char*& nameBuffer)
|
|
||||||
{
|
|
||||||
item->type = type;
|
|
||||||
item->packageDeviceID = package->NodeRef().device;
|
|
||||||
item->packageNodeID = package->NodeRef().node;
|
|
||||||
item->nameLength = package->FileName().Length();
|
|
||||||
item->parentDeviceID = fPackagesDirectoryRef.device;
|
|
||||||
item->parentDirectoryID = fPackagesDirectoryRef.node;
|
|
||||||
item->name = nameBuffer;
|
|
||||||
strcpy(nameBuffer, package->FileName());
|
|
||||||
nameBuffer += package->FileName().Length() + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
Volume::_AddPackage(Package* package)
|
|
||||||
{
|
|
||||||
fState->AddPackage(package);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
Volume::_RemovePackage(Package* package)
|
|
||||||
{
|
|
||||||
fState->RemovePackage(package);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
Volume::_ReadPackagesDirectory()
|
Volume::_ReadPackagesDirectory()
|
||||||
{
|
{
|
||||||
@@ -894,7 +865,7 @@ Volume::_ReadPackagesDirectory()
|
|||||||
|
|
||||||
status_t error = package->Init(entry);
|
status_t error = package->Init(entry);
|
||||||
if (error == B_OK) {
|
if (error == B_OK) {
|
||||||
_AddPackage(package);
|
fState->AddPackage(package);
|
||||||
packageDeleter.Detach();
|
packageDeleter.Detach();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -999,42 +970,6 @@ Volume::_AddRepository(BSolver* solver, BSolverRepository& repository,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
|
||||||
Volume::_OpenPackagesFile(const RelativePath& subDirectoryPath,
|
|
||||||
const char* fileName, uint32 openMode, BFile& _file, BEntry* _entry)
|
|
||||||
{
|
|
||||||
BDirectory directory;
|
|
||||||
if (!subDirectoryPath.IsEmpty()) {
|
|
||||||
status_t error = _OpenPackagesSubDirectory(subDirectoryPath,
|
|
||||||
(openMode & B_CREATE_FILE) != 0, directory);
|
|
||||||
if (error != B_OK) {
|
|
||||||
ERROR("Volume::_OpenPackagesFile(): failed to open packages "
|
|
||||||
"subdirectory \"%s\": %s\n",
|
|
||||||
subDirectoryPath.ToString().String(), strerror(error));
|
|
||||||
RETURN_ERROR(error);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
status_t error = directory.SetTo(&fPackagesDirectoryRef);
|
|
||||||
if (error != B_OK) {
|
|
||||||
ERROR("Volume::_OpenPackagesFile(): failed to open packages "
|
|
||||||
"directory: %s\n", strerror(error));
|
|
||||||
RETURN_ERROR(error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
BEntry stackEntry;
|
|
||||||
BEntry& entry = _entry != NULL ? *_entry : stackEntry;
|
|
||||||
status_t error = entry.SetTo(&directory, fileName);
|
|
||||||
if (error != B_OK) {
|
|
||||||
ERROR("Volume::_OpenPackagesFile(): failed to get entry for file: %s",
|
|
||||||
strerror(error));
|
|
||||||
RETURN_ERROR(error);
|
|
||||||
}
|
|
||||||
|
|
||||||
return _file.SetTo(&entry, openMode);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
Volume::_OpenPackagesSubDirectory(const RelativePath& path, bool create,
|
Volume::_OpenPackagesSubDirectory(const RelativePath& path, bool create,
|
||||||
BDirectory& _directory)
|
BDirectory& _directory)
|
||||||
@@ -1050,178 +985,3 @@ Volume::_OpenPackagesSubDirectory(const RelativePath& path, bool create,
|
|||||||
|
|
||||||
return FSUtils::OpenSubDirectory(directory, path, create, _directory);
|
return FSUtils::OpenSubDirectory(directory, path, create, _directory);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
|
||||||
Volume::_CreateActivationFileContent(const PackageSet& toActivate,
|
|
||||||
const PackageSet& toDeactivate, BString& _content)
|
|
||||||
{
|
|
||||||
BString activationFileContent;
|
|
||||||
for (PackageFileNameHashTable::Iterator it = fState->ByFileNameIterator();
|
|
||||||
it.HasNext();) {
|
|
||||||
Package* package = it.Next();
|
|
||||||
if (package->IsActive()
|
|
||||||
&& toDeactivate.find(package) == toDeactivate.end()) {
|
|
||||||
int32 length = activationFileContent.Length();
|
|
||||||
activationFileContent << package->FileName() << '\n';
|
|
||||||
if (activationFileContent.Length()
|
|
||||||
< length + package->FileName().Length() + 1) {
|
|
||||||
return B_NO_MEMORY;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (PackageSet::const_iterator it = toActivate.begin();
|
|
||||||
it != toActivate.end(); ++it) {
|
|
||||||
Package* package = *it;
|
|
||||||
int32 length = activationFileContent.Length();
|
|
||||||
activationFileContent << package->FileName() << '\n';
|
|
||||||
if (activationFileContent.Length()
|
|
||||||
< length + package->FileName().Length() + 1) {
|
|
||||||
return B_NO_MEMORY;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_content = activationFileContent;
|
|
||||||
return B_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
status_t
|
|
||||||
Volume::_WriteActivationFile(const RelativePath& directoryPath,
|
|
||||||
const char* fileName, const PackageSet& toActivate,
|
|
||||||
const PackageSet& toDeactivate,
|
|
||||||
BEntry& _entry)
|
|
||||||
{
|
|
||||||
// create the content
|
|
||||||
BString activationFileContent;
|
|
||||||
status_t error = _CreateActivationFileContent(toActivate, toDeactivate,
|
|
||||||
activationFileContent);
|
|
||||||
if (error != B_OK)
|
|
||||||
return error;
|
|
||||||
|
|
||||||
// write the file
|
|
||||||
error = _WriteTextFile(directoryPath, fileName, activationFileContent,
|
|
||||||
_entry);
|
|
||||||
if (error != B_OK) {
|
|
||||||
ERROR("Volume::_WriteActivationFile(): failed to write activation "
|
|
||||||
"file \"%s/%s\": %s\n", directoryPath.ToString().String(), fileName,
|
|
||||||
strerror(error));
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
return B_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
status_t
|
|
||||||
Volume::_WriteTextFile(const RelativePath& directoryPath, const char* fileName,
|
|
||||||
const BString& content, BEntry& _entry)
|
|
||||||
{
|
|
||||||
BFile file;
|
|
||||||
status_t error = _OpenPackagesFile(directoryPath,
|
|
||||||
fileName, B_READ_WRITE | B_CREATE_FILE | B_ERASE_FILE, file, &_entry);
|
|
||||||
if (error != B_OK) {
|
|
||||||
ERROR("Volume::_WriteTextFile(): failed to create file \"%s/%s\": %s\n",
|
|
||||||
directoryPath.ToString().String(), fileName, strerror(error));
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
ssize_t bytesWritten = file.Write(content.String(),
|
|
||||||
content.Length());
|
|
||||||
if (bytesWritten < 0) {
|
|
||||||
ERROR("Volume::_WriteTextFile(): failed to write file \"%s/%s\": %s\n",
|
|
||||||
directoryPath.ToString().String(), fileName,
|
|
||||||
strerror(bytesWritten));
|
|
||||||
return bytesWritten;
|
|
||||||
}
|
|
||||||
|
|
||||||
return B_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
Volume::_ChangePackageActivation(const PackageSet& packagesToActivate,
|
|
||||||
const PackageSet& packagesToDeactivate)
|
|
||||||
{
|
|
||||||
INFORM("Volume::_ChangePackageActivation(): activating %zu, deactivating %zu packages\n",
|
|
||||||
packagesToActivate.size(), packagesToDeactivate.size());
|
|
||||||
|
|
||||||
// write the temporary package activation file
|
|
||||||
BEntry activationFileEntry;
|
|
||||||
status_t error = _WriteActivationFile(RelativePath(kAdminDirectoryName),
|
|
||||||
kTemporaryActivationFileName, packagesToActivate, packagesToDeactivate,
|
|
||||||
activationFileEntry);
|
|
||||||
if (error != B_OK)
|
|
||||||
throw Exception(error, "failed to write activation file");
|
|
||||||
|
|
||||||
// compute the size of the allocation we need for the activation change
|
|
||||||
// request
|
|
||||||
int32 itemCount = packagesToActivate.size() + packagesToDeactivate.size();
|
|
||||||
size_t requestSize = sizeof(PackageFSActivationChangeRequest)
|
|
||||||
+ itemCount * sizeof(PackageFSActivationChangeItem);
|
|
||||||
|
|
||||||
for (PackageSet::iterator it = packagesToActivate.begin();
|
|
||||||
it != packagesToActivate.end(); ++it) {
|
|
||||||
requestSize += (*it)->FileName().Length() + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (PackageSet::iterator it = packagesToDeactivate.begin();
|
|
||||||
it != packagesToDeactivate.end(); ++it) {
|
|
||||||
requestSize += (*it)->FileName().Length() + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// allocate and prepare the request
|
|
||||||
PackageFSActivationChangeRequest* request
|
|
||||||
= (PackageFSActivationChangeRequest*)malloc(requestSize);
|
|
||||||
if (request == NULL)
|
|
||||||
throw Exception(B_NO_MEMORY);
|
|
||||||
MemoryDeleter requestDeleter(request);
|
|
||||||
|
|
||||||
request->itemCount = itemCount;
|
|
||||||
|
|
||||||
PackageFSActivationChangeItem* item = &request->items[0];
|
|
||||||
char* nameBuffer = (char*)(item + itemCount);
|
|
||||||
|
|
||||||
for (PackageSet::iterator it = packagesToActivate.begin();
|
|
||||||
it != packagesToActivate.end(); ++it, item++) {
|
|
||||||
_FillInActivationChangeItem(item, PACKAGE_FS_ACTIVATE_PACKAGE, *it,
|
|
||||||
nameBuffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (PackageSet::iterator it = packagesToDeactivate.begin();
|
|
||||||
it != packagesToDeactivate.end(); ++it, item++) {
|
|
||||||
_FillInActivationChangeItem(item, PACKAGE_FS_DEACTIVATE_PACKAGE, *it,
|
|
||||||
nameBuffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
// issue the request
|
|
||||||
int fd = OpenRootDirectory();
|
|
||||||
if (fd < 0)
|
|
||||||
throw Exception(fd, "failed to open root directory");
|
|
||||||
FileDescriptorCloser fdCloser(fd);
|
|
||||||
|
|
||||||
if (ioctl(fd, PACKAGE_FS_OPERATION_CHANGE_ACTIVATION, request, requestSize)
|
|
||||||
!= 0) {
|
|
||||||
// TODO: We need more error information and error handling!
|
|
||||||
throw Exception(errno, "ioctl() to de-/activate packages failed");
|
|
||||||
}
|
|
||||||
|
|
||||||
// rename the temporary activation file to the final file
|
|
||||||
error = activationFileEntry.Rename(kActivationFileName, true);
|
|
||||||
if (error != B_OK) {
|
|
||||||
throw Exception(error,
|
|
||||||
"failed to rename temporary activation file to final file");
|
|
||||||
// TODO: We should probably try to reverse the activation changes, though that
|
|
||||||
// will fail, if this method has been called in response to node monitoring
|
|
||||||
// events. Alternatively moving the package activation file could be made part
|
|
||||||
// of the ioctl(), since packagefs should be able to undo package changes until
|
|
||||||
// the very end, unless running out of memory. In the end the situation would be
|
|
||||||
// bad anyway, though, since the activation file may refer to removed packages
|
|
||||||
// and things would be in an inconsistent state after rebooting.
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update our state, i.e. remove deactivated packages and mark activated
|
|
||||||
// packages accordingly.
|
|
||||||
fState->ActivationChanged(packagesToActivate, packagesToDeactivate);
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -111,6 +111,9 @@ public:
|
|||||||
void SetRoot(Root* root)
|
void SetRoot(Root* root)
|
||||||
{ fRoot = root; }
|
{ fRoot = root; }
|
||||||
|
|
||||||
|
VolumeState* State() const
|
||||||
|
{ return fState; }
|
||||||
|
|
||||||
PackageFileNameHashTable::Iterator PackagesByFileNameIterator()
|
PackageFileNameHashTable::Iterator PackagesByFileNameIterator()
|
||||||
const;
|
const;
|
||||||
|
|
||||||
@@ -140,8 +143,6 @@ public:
|
|||||||
private:
|
private:
|
||||||
struct NodeMonitorEvent;
|
struct NodeMonitorEvent;
|
||||||
|
|
||||||
friend class CommitTransactionHandler;
|
|
||||||
|
|
||||||
typedef FSUtils::RelativePath RelativePath;
|
typedef FSUtils::RelativePath RelativePath;
|
||||||
typedef DoublyLinkedList<NodeMonitorEvent> NodeMonitorEventList;
|
typedef DoublyLinkedList<NodeMonitorEvent> NodeMonitorEventList;
|
||||||
|
|
||||||
@@ -155,14 +156,6 @@ private:
|
|||||||
void _PackagesEntryCreated(const char* name);
|
void _PackagesEntryCreated(const char* name);
|
||||||
void _PackagesEntryRemoved(const char* name);
|
void _PackagesEntryRemoved(const char* name);
|
||||||
|
|
||||||
void _FillInActivationChangeItem(
|
|
||||||
PackageFSActivationChangeItem* item,
|
|
||||||
PackageFSActivationChangeType type,
|
|
||||||
Package* package, char*& nameBuffer);
|
|
||||||
|
|
||||||
void _AddPackage(Package* package);
|
|
||||||
void _RemovePackage(Package* package);
|
|
||||||
|
|
||||||
status_t _ReadPackagesDirectory();
|
status_t _ReadPackagesDirectory();
|
||||||
status_t _GetActivePackages(int fd);
|
status_t _GetActivePackages(int fd);
|
||||||
|
|
||||||
@@ -170,10 +163,6 @@ private:
|
|||||||
BSolverRepository& repository,
|
BSolverRepository& repository,
|
||||||
bool activeOnly, bool installed);
|
bool activeOnly, bool installed);
|
||||||
|
|
||||||
status_t _OpenPackagesFile(
|
|
||||||
const RelativePath& subDirectoryPath,
|
|
||||||
const char* fileName, uint32 openMode,
|
|
||||||
BFile& _file, BEntry* _entry = NULL);
|
|
||||||
status_t _OpenPackagesSubDirectory(
|
status_t _OpenPackagesSubDirectory(
|
||||||
const RelativePath& path, bool create,
|
const RelativePath& path, bool create,
|
||||||
BDirectory& _directory);
|
BDirectory& _directory);
|
||||||
@@ -181,32 +170,6 @@ private:
|
|||||||
status_t _OpenSettingsRootDirectory(
|
status_t _OpenSettingsRootDirectory(
|
||||||
BDirectory& _directory);
|
BDirectory& _directory);
|
||||||
|
|
||||||
status_t _CreateActivationFileContent(
|
|
||||||
const PackageSet& toActivate,
|
|
||||||
const PackageSet& toDeactivate,
|
|
||||||
BString& _content);
|
|
||||||
status_t _WriteActivationFile(
|
|
||||||
const RelativePath& directoryPath,
|
|
||||||
const char* fileName,
|
|
||||||
const PackageSet& toActivate,
|
|
||||||
const PackageSet& toDeactivate,
|
|
||||||
BEntry& _entry);
|
|
||||||
|
|
||||||
status_t _WriteTextFile(
|
|
||||||
const RelativePath& directoryPath,
|
|
||||||
const char* fileName,
|
|
||||||
const BString& content, BEntry& _entry);
|
|
||||||
|
|
||||||
void _ChangePackageActivation(
|
|
||||||
const PackageSet& packagesToActivate,
|
|
||||||
const PackageSet& packagesToDeactivate);
|
|
||||||
// throws Exception
|
|
||||||
|
|
||||||
status_t _ExtractPackageContent(Package* package,
|
|
||||||
const char* contentPath,
|
|
||||||
BDirectory& targetDirectory,
|
|
||||||
BDirectory& _extractedFilesDirectory);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
BString fPath;
|
BString fPath;
|
||||||
PackageFSMountType fMountType;
|
PackageFSMountType fMountType;
|
||||||
|
|||||||
Reference in New Issue
Block a user