* Finished ProgressReporter

* Integrated ProgressReporter into CopyEngine and UnzipEngine.
* Integrated unzipping to main installer engine. Since there are currently no
  .zip files in the _packages_ folder (and not even a _packages_ folder
  itself), this is completely invisible, but it works.

TODO: Adjust the build system to optionally copy packages into _packages_
instead of extracting them. Like for the CD build profile mode.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@32967 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Stephan Aßmus 2009-09-06 17:23:31 +00:00
parent c12764b812
commit 72586154d7
9 changed files with 185 additions and 152 deletions

View File

@ -22,19 +22,22 @@
#include "InstallerWindow.h" #include "InstallerWindow.h"
// TODO: For PACKAGES_DIRECTORY and VAR_DIRECTORY, not so nice... // TODO: For PACKAGES_DIRECTORY and VAR_DIRECTORY, not so nice...
#include "SemaphoreLocker.h" #include "SemaphoreLocker.h"
#include "ProgressReporter.h"
using std::nothrow; using std::nothrow;
CopyEngine::CopyEngine(const BMessenger& messenger, BMessage* message) CopyEngine::CopyEngine(ProgressReporter* reporter)
: :
fBufferQueue(), fBufferQueue(),
fWriterThread(-1), fWriterThread(-1),
fQuitting(false), fQuitting(false),
fBytesRead(0), fBytesRead(0),
fLastBytesRead(0),
fItemsCopied(0), fItemsCopied(0),
fLastItemsCopied(0),
fTimeRead(0), fTimeRead(0),
fBytesWritten(0), fBytesWritten(0),
@ -46,8 +49,7 @@ CopyEngine::CopyEngine(const BMessenger& messenger, BMessage* message)
fCurrentTargetFolder(NULL), fCurrentTargetFolder(NULL),
fCurrentItem(NULL), fCurrentItem(NULL),
fMessenger(messenger), fProgressReporter(reporter)
fMessage(message)
{ {
fWriterThread = spawn_thread(_WriteThreadEntry, "buffer writer", fWriterThread = spawn_thread(_WriteThreadEntry, "buffer writer",
B_NORMAL_PRIORITY, this); B_NORMAL_PRIORITY, this);
@ -73,16 +75,19 @@ CopyEngine::~CopyEngine()
int32 exitValue; int32 exitValue;
wait_for_thread(fWriterThread, &exitValue); wait_for_thread(fWriterThread, &exitValue);
} }
delete fMessage;
} }
void void
CopyEngine::ResetTargets() CopyEngine::ResetTargets()
{ {
// TODO: One could subtract the bytes/items which were added to the
// ProgressReporter before resetting them...
fBytesRead = 0; fBytesRead = 0;
fLastBytesRead = 0;
fItemsCopied = 0; fItemsCopied = 0;
fLastItemsCopied = 0;
fTimeRead = 0; fTimeRead = 0;
fBytesWritten = 0; fBytesWritten = 0;
@ -93,12 +98,6 @@ CopyEngine::ResetTargets()
fCurrentTargetFolder = NULL; fCurrentTargetFolder = NULL;
fCurrentItem = NULL; fCurrentItem = NULL;
if (fMessage) {
BMessage message(*fMessage);
message.AddString("status", "Collecting copy information.");
fMessenger.SendMessage(&message);
}
} }
@ -106,7 +105,10 @@ status_t
CopyEngine::CollectTargets(const char* source, sem_id cancelSemaphore) CopyEngine::CollectTargets(const char* source, sem_id cancelSemaphore)
{ {
int32 level = 0; int32 level = 0;
return _CollectCopyInfo(source, level, cancelSemaphore); status_t ret = _CollectCopyInfo(source, level, cancelSemaphore);
if (ret == B_OK && fProgressReporter != NULL)
fProgressReporter->AddItems(fItemsToCopy, fBytesToCopy);
return ret;
} }
@ -114,14 +116,6 @@ status_t
CopyEngine::CopyFolder(const char* source, const char* destination, CopyEngine::CopyFolder(const char* source, const char* destination,
sem_id cancelSemaphore) sem_id cancelSemaphore)
{ {
printf("%lld bytes to read in %lld files\n", fBytesToCopy, fItemsToCopy);
if (fMessage) {
BMessage message(*fMessage);
message.AddString("status", "Performing installation.");
fMessenger.SendMessage(&message);
}
int32 level = 0; int32 level = 0;
return _CopyFolder(source, destination, level, cancelSemaphore); return _CopyFolder(source, destination, level, cancelSemaphore);
} }
@ -475,16 +469,23 @@ CopyEngine::_RemoveFolder(BEntry& entry)
void void
CopyEngine::_UpdateProgress() CopyEngine::_UpdateProgress()
{ {
if (fMessage != NULL) { if (fProgressReporter == NULL)
BMessage message(*fMessage); return;
float progress = 100.0 * fBytesRead / fBytesToCopy;
message.AddFloat("progress", progress); uint64 items = 0;
message.AddInt32("current", fItemsCopied); if (fLastItemsCopied < fItemsCopied) {
message.AddInt32("maximum", fItemsToCopy); items = fItemsCopied - fLastItemsCopied;
message.AddString("item", fCurrentItem); fLastItemsCopied = fItemsCopied;
message.AddString("folder", fCurrentTargetFolder);
fMessenger.SendMessage(&message);
} }
off_t bytes = 0;
if (fLastBytesRead < fBytesRead) {
bytes = fBytesRead - fLastBytesRead;
fLastBytesRead = fBytesRead;
}
fProgressReporter->ItemsWritten(items, bytes, fCurrentItem,
fCurrentTargetFolder);
} }

View File

@ -15,14 +15,12 @@
#include "BlockingQueue.h" #include "BlockingQueue.h"
class BFile; class BFile;
class BMessage; class ProgressReporter;
class BMessenger;
class CopyEngine { class CopyEngine {
public: public:
CopyEngine(const BMessenger& messenger, CopyEngine(ProgressReporter* reporter);
BMessage* message);
virtual ~CopyEngine(); virtual ~CopyEngine();
void ResetTargets(); void ResetTargets();
@ -93,7 +91,9 @@ private:
volatile bool fQuitting; volatile bool fQuitting;
off_t fBytesRead; off_t fBytesRead;
uint64 fLastBytesRead;
uint64 fItemsCopied; uint64 fItemsCopied;
uint64 fLastItemsCopied;
bigtime_t fTimeRead; bigtime_t fTimeRead;
off_t fBytesWritten; off_t fBytesWritten;
@ -105,8 +105,7 @@ private:
const char* fCurrentTargetFolder; const char* fCurrentTargetFolder;
const char* fCurrentItem; const char* fCurrentItem;
BMessenger fMessenger; ProgressReporter* fProgressReporter;
BMessage* fMessage;
}; };

View File

@ -9,6 +9,7 @@ Application Installer :
InstallerWindow.cpp InstallerWindow.cpp
PackageViews.cpp PackageViews.cpp
PartitionMenuItem.cpp PartitionMenuItem.cpp
ProgressReporter.cpp
UnzipEngine.cpp UnzipEngine.cpp
WorkerThread.cpp WorkerThread.cpp
: be tracker translation libshared.a $(TARGET_LIBSTDC++) : be tracker translation libshared.a $(TARGET_LIBSTDC++)

View File

@ -5,28 +5,19 @@
#include "ProgressReporter.h" #include "ProgressReporter.h"
#include <new>
#include <math.h>
#include <stdio.h> #include <stdio.h>
#include <string.h>
using std::nothrow;
ProgressReporter::ProgressReporter(const BMessenger& messenger, ProgressReporter::ProgressReporter(const BMessenger& messenger,
BMessage* message) BMessage* message)
: :
fBytesRead(0), fStartTime(0),
fItemsCopied(0),
fTimeRead(0),
fBytesToWrite(0),
fBytesWritten(0), fBytesWritten(0),
fTimeWritten(0),
fBytesToCopy(0), fItemsToWrite(0),
fItemsToCopy(0), fItemsWritten(0),
fMessenger(messenger), fMessenger(messenger),
fMessage(message) fMessage(message)
@ -43,15 +34,11 @@ ProgressReporter::~ProgressReporter()
void void
ProgressReporter::Reset() ProgressReporter::Reset()
{ {
fBytesRead = 0; fBytesToWrite = 0;
fItemsCopied = 0;
fTimeRead = 0;
fBytesWritten = 0; fBytesWritten = 0;
fTimeWritten = 0;
fBytesToCopy = 0; fItemsToWrite = 0;
fItemsToCopy = 0; fItemsWritten = 0;
if (fMessage) { if (fMessage) {
BMessage message(*fMessage); BMessage message(*fMessage);
@ -64,22 +51,35 @@ ProgressReporter::Reset()
void void
ProgressReporter::AddItems(uint64 count, off_t bytes) ProgressReporter::AddItems(uint64 count, off_t bytes)
{ {
// TODO ... fBytesToWrite += bytes;
fItemsToWrite += count;
} }
void void
ProgressReporter::StartTimer() ProgressReporter::StartTimer()
{ {
// TODO ... fStartTime = system_time();
printf("%lld bytes to write in %lld files\n", fBytesToWrite,
fItemsToWrite);
if (fMessage) {
BMessage message(*fMessage);
message.AddString("status", "Performing installation.");
fMessenger.SendMessage(&message);
}
} }
void void
ProgressReporter::ItemsCopied(uint64 items, off_t bytes, const char* itemName, ProgressReporter::ItemsWritten(uint64 items, off_t bytes,
const char* targetFolder) const char* itemName, const char* targetFolder)
{ {
// TODO ... fItemsWritten += items;
fBytesWritten += bytes;
_UpdateProgress(itemName, targetFolder);
} }
@ -87,14 +87,17 @@ void
ProgressReporter::_UpdateProgress(const char* itemName, ProgressReporter::_UpdateProgress(const char* itemName,
const char* targetFolder) const char* targetFolder)
{ {
if (fMessage != NULL) { if (fMessage == NULL)
BMessage message(*fMessage); return;
float progress = 100.0 * fBytesRead / fBytesToCopy;
message.AddFloat("progress", progress); // TODO: Could add time to finish calculation here...
message.AddInt32("current", fItemsCopied);
message.AddInt32("maximum", fItemsToCopy); BMessage message(*fMessage);
message.AddString("item", itemName); float progress = 100.0 * fBytesWritten / fBytesToWrite;
message.AddString("folder", targetFolder); message.AddFloat("progress", progress);
fMessenger.SendMessage(&message); message.AddInt32("current", fItemsWritten);
} message.AddInt32("maximum", fItemsToWrite);
message.AddString("item", itemName);
message.AddString("folder", targetFolder);
fMessenger.SendMessage(&message);
} }

View File

@ -21,24 +21,24 @@ public:
void StartTimer(); void StartTimer();
void ItemsCopied(uint64 items, off_t bytes, void ItemsWritten(uint64 items, off_t bytes,
const char* itemName, const char* itemName,
const char* targetFolder); const char* targetFolder);
// TODO: Perhaps move cancelling here as well...
private: private:
void _UpdateProgress(const char* itemName, void _UpdateProgress(const char* itemName,
const char* targetFolder); const char* targetFolder);
private: private:
off_t fBytesRead; bigtime_t fStartTime;
uint64 fItemsCopied;
bigtime_t fTimeRead;
off_t fBytesToWrite;
off_t fBytesWritten; off_t fBytesWritten;
bigtime_t fTimeWritten;
off_t fBytesToCopy; uint64 fItemsToWrite;
uint64 fItemsToCopy; uint64 fItemsWritten;
BMessenger fMessenger; BMessenger fMessenger;
BMessage* fMessage; BMessage* fMessage;

View File

@ -21,12 +21,13 @@
#include "CommandPipe.h" #include "CommandPipe.h"
#include "SemaphoreLocker.h" #include "SemaphoreLocker.h"
#include "ProgressReporter.h"
using std::nothrow; using std::nothrow;
UnzipEngine::UnzipEngine(const BMessenger& messenger, BMessage* message, UnzipEngine::UnzipEngine(ProgressReporter* reporter,
sem_id cancelSemaphore) sem_id cancelSemaphore)
: :
fPackage(""), fPackage(""),
@ -34,11 +35,12 @@ UnzipEngine::UnzipEngine(const BMessenger& messenger, BMessage* message,
fBytesToUncompress(0), fBytesToUncompress(0),
fBytesUncompressed(0), fBytesUncompressed(0),
fLastBytesUncompressed(0),
fItemsToUncompress(0), fItemsToUncompress(0),
fItemsUncompressed(0), fItemsUncompressed(0),
fLastItemsUncompressed(0),
fMessenger(messenger), fProgressReporter(reporter),
fMessage(message),
fCancelSemaphore(cancelSemaphore) fCancelSemaphore(cancelSemaphore)
{ {
} }
@ -46,7 +48,6 @@ UnzipEngine::UnzipEngine(const BMessenger& messenger, BMessage* message,
UnzipEngine::~UnzipEngine() UnzipEngine::~UnzipEngine()
{ {
delete fMessage;
} }
@ -60,8 +61,10 @@ UnzipEngine::SetTo(const char* pathToPackage, const char* destinationFolder)
fBytesToUncompress = 0; fBytesToUncompress = 0;
fBytesUncompressed = 0; fBytesUncompressed = 0;
fLastBytesUncompressed = 0;
fItemsToUncompress = 0; fItemsToUncompress = 0;
fItemsUncompressed = 0; fItemsUncompressed = 0;
fLastItemsUncompressed = 0;
BPrivate::BCommandPipe commandPipe; BPrivate::BCommandPipe commandPipe;
status_t ret = commandPipe.AddArg("unzip"); status_t ret = commandPipe.AddArg("unzip");
@ -95,12 +98,6 @@ UnzipEngine::UnzipPackage()
if (fItemsToUncompress == 0) if (fItemsToUncompress == 0)
return B_NO_INIT; return B_NO_INIT;
if (fMessage) {
BMessage message(*fMessage);
message.AddString("status", "Extracting package.");
fMessenger.SendMessage(&message);
}
BPrivate::BCommandPipe commandPipe; BPrivate::BCommandPipe commandPipe;
status_t ret = commandPipe.AddArg("unzip"); status_t ret = commandPipe.AddArg("unzip");
if (ret == B_OK) if (ret == B_OK)
@ -155,19 +152,6 @@ UnzipEngine::ReadLine(const BString& line)
status_t status_t
UnzipEngine::_ReadLineListing(const BString& line) UnzipEngine::_ReadLineListing(const BString& line)
{ {
// static const char* kListingFormat = "%llu files, %llu bytes uncompressed, "
// "%llu bytes compressed: %f%%";
//
// uint64 bytesCompressed;
// float compresssionRatio;
// if (sscanf(line.String(), kListingFormat, &fItemsToUncompress,
// &fBytesToUncompress, &bytesCompressed, &compresssionRatio) != 4) {
// fBytesToUncompress = 0;
// fItemsToUncompress = 0;
// fprintf(stderr, "error reading command output: %s\n", line.String());
// return B_ERROR;
// }
static const char* kListingFormat = "%llu %s %s %s\n"; static const char* kListingFormat = "%llu %s %s %s\n";
const char* string = line.String(); const char* string = line.String();
@ -197,7 +181,7 @@ UnzipEngine::_ReadLineListing(const BString& line)
if (destination.Append(itemPath.String()) == B_OK) { if (destination.Append(itemPath.String()) == B_OK) {
BEntry test(destination.Path()); BEntry test(destination.Path());
if (test.Exists() && test.IsDirectory()) { if (test.Exists() && test.IsDirectory()) {
printf("ignoring %s\n", itemPath.String()); // printf("ignoring %s\n", itemPath.String());
itemCount = 0; itemCount = 0;
} }
} }
@ -205,8 +189,8 @@ UnzipEngine::_ReadLineListing(const BString& line)
fItemsToUncompress += itemCount; fItemsToUncompress += itemCount;
printf("item %s with %llu bytes to %s\n", itemName.String(), // printf("item %s with %llu bytes to %s\n", itemName.String(),
bytes, itemPath.String()); // bytes, itemPath.String());
fEntrySizeMap.Put(itemName.String(), bytes); fEntrySizeMap.Put(itemName.String(), bytes);
} else { } else {
@ -243,8 +227,8 @@ UnzipEngine::_ReadLineExtract(const BString& line)
fBytesUncompressed += bytes; fBytesUncompressed += bytes;
} }
printf("%llu extracted %s to %s (%llu)\n", fItemsUncompressed, // printf("%llu extracted %s to %s (%llu)\n", fItemsUncompressed,
itemName.String(), itemPath.String(), bytes); // itemName.String(), itemPath.String(), bytes);
_UpdateProgress(itemName.String(), itemPath.String()); _UpdateProgress(itemName.String(), itemPath.String());
} else { } else {
@ -258,14 +242,20 @@ UnzipEngine::_ReadLineExtract(const BString& line)
void void
UnzipEngine::_UpdateProgress(const char* item, const char* targetFolder) UnzipEngine::_UpdateProgress(const char* item, const char* targetFolder)
{ {
if (fMessage != NULL) { if (fProgressReporter == NULL)
BMessage message(*fMessage); return;
float progress = 100.0 * fBytesUncompressed / fBytesToUncompress;
message.AddFloat("progress", progress); uint64 items = 0;
message.AddInt32("current", fItemsUncompressed); if (fLastItemsUncompressed < fItemsUncompressed) {
message.AddInt32("maximum", fItemsToUncompress); items = fItemsUncompressed - fLastItemsUncompressed;
message.AddString("item", item); fLastItemsUncompressed = fItemsUncompressed;
message.AddString("folder", targetFolder);
fMessenger.SendMessage(&message);
} }
off_t bytes = 0;
if (fLastBytesUncompressed < fBytesUncompressed) {
bytes = fBytesUncompressed - fLastBytesUncompressed;
fLastBytesUncompressed = fBytesUncompressed;
}
fProgressReporter->ItemsWritten(items, bytes, item, targetFolder);
} }

View File

@ -15,14 +15,12 @@
#include "HashMap.h" #include "HashMap.h"
#include "HashString.h" #include "HashString.h"
class BMessage; class ProgressReporter;
class BMessenger;
class UnzipEngine : private BCommandPipe::LineReader { class UnzipEngine : private BCommandPipe::LineReader {
public: public:
UnzipEngine(const BMessenger& messenger, UnzipEngine(ProgressReporter* reporter,
BMessage* message,
sem_id cancelSemaphore = -1); sem_id cancelSemaphore = -1);
virtual ~UnzipEngine(); virtual ~UnzipEngine();
@ -59,11 +57,12 @@ private:
off_t fBytesToUncompress; off_t fBytesToUncompress;
off_t fBytesUncompressed; off_t fBytesUncompressed;
off_t fLastBytesUncompressed;
uint64 fItemsToUncompress; uint64 fItemsToUncompress;
uint64 fItemsUncompressed; uint64 fItemsUncompressed;
uint64 fLastItemsUncompressed;
BMessenger fMessenger; ProgressReporter* fProgressReporter;
BMessage* fMessage;
sem_id fCancelSemaphore; sem_id fCancelSemaphore;
}; };

View File

@ -27,6 +27,7 @@
#include "InstallerWindow.h" #include "InstallerWindow.h"
#include "PackageViews.h" #include "PackageViews.h"
#include "PartitionMenuItem.h" #include "PartitionMenuItem.h"
#include "ProgressReporter.h"
#include "UnzipEngine.h" #include "UnzipEngine.h"
@ -251,7 +252,9 @@ WorkerThread::_PerformInstall(BMenu* srcMenu, BMenu* targetMenu)
entry_ref testRef; entry_ref testRef;
BMessenger messenger(fWindow); BMessenger messenger(fWindow);
CopyEngine engine(messenger, new BMessage(MSG_STATUS_MESSAGE)); ProgressReporter reporter(messenger, new BMessage(MSG_STATUS_MESSAGE));
CopyEngine engine(&reporter);
BList unzipEngines;
PartitionMenuItem* targetItem = (PartitionMenuItem*)targetMenu->FindMarked(); PartitionMenuItem* targetItem = (PartitionMenuItem*)targetMenu->FindMarked();
PartitionMenuItem* srcItem = (PartitionMenuItem*)srcMenu->FindMarked(); PartitionMenuItem* srcItem = (PartitionMenuItem*)srcMenu->FindMarked();
@ -397,6 +400,7 @@ WorkerThread::_PerformInstall(BMenu* srcMenu, BMenu* targetMenu)
goto error; goto error;
} }
// Begin actuall installation
_LaunchInitScript(targetDirectory); _LaunchInitScript(targetDirectory);
@ -419,6 +423,14 @@ WorkerThread::_PerformInstall(BMenu* srcMenu, BMenu* targetMenu)
} }
} }
// collect information about all zip packages
err = _ProcessZipPackages(srcDirectory.Path(), targetDirectory.Path(),
&reporter, unzipEngines);
if (err != B_OK)
goto error;
reporter.StartTimer();
// copy source volume // copy source volume
err = engine.CopyFolder(srcDirectory.Path(), targetDirectory.Path(), err = engine.CopyFolder(srcDirectory.Path(), targetDirectory.Path(),
fCancelSemaphore); fCancelSemaphore);
@ -439,37 +451,17 @@ WorkerThread::_PerformInstall(BMenu* srcMenu, BMenu* targetMenu)
} }
} }
#if 0 // Extract all zip packages. If an error occured, delete the rest of
// extract zip packages // the engines, but stop extracting.
// TODO: Put those in the optional packages list view for (int32 i = 0; i < unzipEngines.CountItems(); i++) {
// TODO: Implement mechanism to handle dependencies between these UnzipEngine* engine = reinterpret_cast<UnzipEngine*>(
// packages. (Selecting one will auto-select others.) unzipEngines.ItemAtFast(i));
{ if (err == B_OK)
BPath pkgRootDir(srcDirectory.Path(), PACKAGES_DIRECTORY); err = engine->UnzipPackage();
BDirectory directory(pkgRootDir.Path()); delete engine;
BEntry entry;
while (directory.GetNextEntry(&entry) == B_OK) {
char name[B_FILE_NAME_LENGTH];
if (entry.GetName(name) != B_OK)
continue;
int nameLength = strlen(name);
if (nameLength <= 0)
continue;
char* nameExtension = name + nameLength - 4;
printf("inspecting %s (%s)\n", name, nameExtension);
if (strcasecmp(nameExtension, ".zip") != 0)
continue;
printf("found .zip package: %s\n", name);
UnzipEngine unzipEngine(messenger, new BMessage(MSG_STATUS_MESSAGE),
fCancelSemaphore);
BPath path;
entry.GetPath(&path);
unzipEngine.SetTo(path.Path(), targetDirectory.Path());
unzipEngine.UnzipPackage();
}
} }
#endif if (err != B_OK)
goto error;
_LaunchFinishScript(targetDirectory); _LaunchFinishScript(targetDirectory);
@ -487,6 +479,48 @@ error:
} }
status_t
WorkerThread::_ProcessZipPackages(const char* sourcePath,
const char* targetPath, ProgressReporter* reporter, BList& unzipEngines)
{
// 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);
BDirectory directory(pkgRootDir.Path());
BEntry entry;
while (directory.GetNextEntry(&entry) == B_OK) {
char name[B_FILE_NAME_LENGTH];
if (entry.GetName(name) != B_OK)
continue;
int nameLength = strlen(name);
if (nameLength <= 0)
continue;
char* nameExtension = name + nameLength - 4;
if (strcasecmp(nameExtension, ".zip") != 0)
continue;
printf("found .zip package: %s\n", name);
UnzipEngine* unzipEngine = new(std::nothrow) UnzipEngine(reporter,
fCancelSemaphore);
if (unzipEngine == NULL || !unzipEngines.AddItem(unzipEngine)) {
delete unzipEngine;
return B_NO_MEMORY;
}
BPath path;
entry.GetPath(&path);
status_t ret = unzipEngine->SetTo(path.Path(), targetPath);
if (ret != B_OK)
return ret;
reporter->AddItems(unzipEngine->ItemsToUncompress(),
unzipEngine->BytesToUncompress());
}
return B_OK;
}
void void
WorkerThread::_SetStatusMessage(const char *status) WorkerThread::_SetStatusMessage(const char *status)
{ {

View File

@ -16,6 +16,7 @@
class BList; class BList;
class BMenu; class BMenu;
class InstallerWindow; class InstallerWindow;
class ProgressReporter;
class WorkerThread : public BLooper { class WorkerThread : public BLooper {
public: public:
@ -41,7 +42,12 @@ private:
void _LaunchInitScript(BPath& path); void _LaunchInitScript(BPath& path);
void _LaunchFinishScript(BPath& path); void _LaunchFinishScript(BPath& path);
void _PerformInstall(BMenu* srcMenu, BMenu* dstMenu); void _PerformInstall(BMenu* srcMenu,
BMenu* dstMenu);
status_t _ProcessZipPackages(const char* sourcePath,
const char* targetPath,
ProgressReporter* reporter,
BList& unzipEngines);
void _SetStatusMessage(const char* status); void _SetStatusMessage(const char* status);