First round of cleanup:

* Renamed CopyEngine to WorkerThread, since it's used for other things than
  just copying.
* Removed the code borrowed from Tracker.
* Removed the InstallerCopyLoopControl, since the CopyEngine handles
  notifications and cancelling by itself now.
* Renamed a few message constants.
* Since we only support BFS partitions as install targets, I removed the
  FS type from the target menu item label. However, I am going to solve this
  differently. I guess all partitions should be seen in the target list, just
  disabled if they are not a valid target, and with a reason given too.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@30600 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Stephan Aßmus
2009-05-03 09:32:24 +00:00
parent b037500155
commit b4afa66367
12 changed files with 210 additions and 4863 deletions
-49
View File
@@ -1,49 +0,0 @@
/*
* Copyright 2005, Jérôme DUVAL. All rights reserved.
* Distributed under the terms of the MIT License.
*/
#ifndef _CopyEngine_h
#define _CopyEngine_h
#include "InstallerCopyLoopControl.h"
#include <DiskDevice.h>
#include <DiskDeviceRoster.h>
#include <Looper.h>
#include <Messenger.h>
#include <Partition.h>
#include <Volume.h>
class BLocker;
class InstallerWindow;
const uint32 ENGINE_START = 'eSRT';
class CopyEngine : public BLooper {
public:
CopyEngine(InstallerWindow *window);
void MessageReceived(BMessage *msg);
void ScanDisksPartitions(BMenu *srcMenu, BMenu *targetMenu);
void SetPackagesList(BList *list);
void SetSpaceRequired(off_t bytes) { fSpaceRequired = bytes; };
bool Cancel();
void SetLock(BLocker* lock) { fCancelLock = lock; }
void WriteBootSector(BMenu *targetMenu);
private:
void LaunchInitScript(BPath &path);
void LaunchFinishScript(BPath &path);
void SetStatusMessage(const char *status);
void Start(BMenu *srcMenu, BMenu *targetMenu);
status_t CopyFolder(BDirectory &srcDir, BDirectory &targetDir);
InstallerWindow *fWindow;
BDiskDeviceRoster fDDRoster;
InstallerCopyLoopControl *fControl;
BList *fPackages;
off_t fSpaceRequired;
BLocker* fCancelLock;
};
#endif /* _CopyEngine_h */
File diff suppressed because it is too large Load Diff
-312
View File
@@ -1,312 +0,0 @@
/*
Open Tracker License
Terms and Conditions
Copyright (c) 1991-2000, Be Incorporated. All rights reserved.
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice applies to all licensees
and shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF TITLE, MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
BE INCORPORATED BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF, OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of Be Incorporated shall not be
used in advertising or otherwise to promote the sale, use or other dealings in
this Software without prior written authorization from Be Incorporated.
Tracker(TM), Be(R), BeOS(R), and BeIA(TM) are trademarks or registered trademarks
of Be Incorporated in the United States and other countries. Other brand product
names are registered trademarks or trademarks of their respective holders.
All rights reserved.
*/
#ifndef FS_UTILS_H
#define FS_UTILS_H
#include <FindDirectory.h>
#include <List.h>
#include <Point.h>
#include <StorageDefs.h>
#include <vector>
#include "Model.h"
#include "ObjectList.h"
// Note - APIs/code in FSUtils.h and FSUtils.cpp is slated for a major cleanup
// -- in other words, you will find a lot of ugly cruft in here
class BDirectory;
class BEntry;
class BList;
class BFile;
namespace BPrivate {
class BInfoWindow;
class CopyLoopControl {
// controls the copy engine; may be overriden to specify how conflicts are
// handled, etc.
// Installer has it's own subclass
public:
virtual ~CopyLoopControl();
virtual bool FileError(const char *message, const char *name, status_t error,
bool allowContinue) = 0;
// inform that a file error occurred while copying <name>
// returns true if user decided to continue
virtual void UpdateStatus(const char *name, entry_ref ref, int32 count,
bool optional = false) = 0;
virtual bool CheckUserCanceled() = 0;
// returns true if canceled
enum OverwriteMode {
kSkip, // do not replace, go to next entry
kReplace, // remove entry before copying new one
kMerge // for folders: leave existing folder, update contents leaving
// nonconflicting items
// for files: save original attributes on file.
};
virtual OverwriteMode OverwriteOnConflict(const BEntry *srcEntry,
const char *destName, const BDirectory *destDir, bool srcIsDir,
bool dstIsDir) = 0;
// override to always overwrite, never overwrite, let user decide,
// compare dates, etc.
virtual bool SkipEntry(const BEntry *, bool file) = 0;
// override to prevent copying of a given file or directory
virtual void ChecksumChunk(const char *block, size_t size);
// during a file copy, this is called every time a chunk of data
// is copied. Users may override to keep a running checksum.
virtual bool ChecksumFile(const entry_ref *);
// This is called when a file is finished copying. Users of this
// class may override to verify that the checksum they've been
// computing in ChecksumChunk matches. If this returns true,
// the copy will continue. If false, if will abort.
virtual bool SkipAttribute(const char *attributeName);
virtual bool PreserveAttribute(const char *attributeName);
};
class TrackerCopyLoopControl : public CopyLoopControl {
// this is the Tracker copy - specific version of CopyLoopControl
public:
TrackerCopyLoopControl(thread_id);
virtual ~TrackerCopyLoopControl() {}
virtual bool FileError(const char *message, const char *name, status_t error,
bool allowContinue);
// inform that a file error occurred while copying <name>
// returns true if user decided to continue
virtual void UpdateStatus(const char *name, entry_ref ref, int32 count,
bool optional = false);
virtual bool CheckUserCanceled();
// returns true if canceled
virtual OverwriteMode OverwriteOnConflict(const BEntry *srcEntry,
const char *destName, const BDirectory *destDir, bool srcIsDir,
bool dstIsDir);
virtual bool SkipEntry(const BEntry *, bool file);
// override to prevent copying of a given file or directory
virtual bool SkipAttribute(const char *attributeName);
private:
thread_id fThread;
};
inline
TrackerCopyLoopControl::TrackerCopyLoopControl(thread_id thread)
: fThread(thread)
{
}
#define B_DESKTOP_DIR_NAME "Desktop"
status_t FSCopyAttributesAndStats(BNode *, BNode *);
status_t FSCopyFile(BEntry* srcFile, StatStruct *srcStat, BDirectory* destDir,
CopyLoopControl *loopControl, BPoint *loc, bool makeOriginalName, Undo &undo);
status_t FSCopyFolder(BEntry *srcEntry, BDirectory *destDir, CopyLoopControl *loopControl,
BPoint *loc, bool makeOriginalName, Undo &undo);
void FSDuplicate(BObjectList<entry_ref> *srcList, BList *pointList);
void FSMoveToFolder(BObjectList<entry_ref> *srcList, BEntry *, uint32 moveMode,
BList *pointList = NULL);
void FSMakeOriginalName(char *name, BDirectory *destDir, const char *suffix);
bool FSIsTrashDir(const BEntry *);
bool FSIsPrintersDir(const BEntry *);
bool FSIsDeskDir(const BEntry *);
bool FSIsSystemDir(const BEntry *);
bool FSIsBeOSDir(const BEntry *);
bool FSIsHomeDir(const BEntry *);
void FSMoveToTrash(BObjectList<entry_ref> *srcList, BList *pointList = NULL,
bool async = true);
// Deprecated
void FSDeleteRefList(BObjectList<entry_ref> *, bool, bool confirm = true);
void FSDelete(entry_ref *, bool, bool confirm = true);
void FSRestoreRefList(BObjectList<entry_ref> *list, bool async);
status_t FSLaunchItem(const entry_ref *application, const BMessage *refsReceived,
bool async, bool openWithOK);
// Preferred way of launching; only pass an actual application in <application>, not
// a document; to open documents with the preferred app, pase 0 in <application> and
// stuff all the document refs into <refsReceived>
// Consider having silent mode that does not show alerts, just returns error code
status_t FSOpenWith(BMessage *listOfRefs);
// runs the Open With window; pas a list of refs
void FSEmptyTrash();
status_t FSCreateNewFolderIn(const node_ref *destDir, entry_ref *newRef,
node_ref *new_node);
void FSCreateTrashDirs();
status_t FSGetTrashDir(BDirectory *trashDir, dev_t volume);
status_t FSGetDeskDir(BDirectory *deskDir, dev_t volume);
status_t FSRecursiveCalcSize(BInfoWindow *, BDirectory *,
off_t *runningSize, int32 *fileCount, int32 *dirCount);
bool FSInTrashDir(const entry_ref *);
// doesn't need to be exported
bool FSGetPoseLocation(const BNode *node, BPoint *point);
status_t FSSetPoseLocation(BEntry *entry, BPoint point);
status_t FSSetPoseLocation(ino_t destDirInode, BNode *destNode, BPoint point);
status_t FSGetBootDeskDir(BDirectory *deskDir);
status_t FSGetOriginalPath(BEntry *entry, BPath *path);
enum ReadAttrResult {
kReadAttrFailed,
kReadAttrNativeOK,
kReadAttrForeignOK
};
ReadAttrResult ReadAttr(const BNode *, const char *hostAttrName, const char *foreignAttrName,
type_code , off_t , void *, size_t , void (*swapFunc)(void *) = 0,
bool isForeign = false);
// Endian swapping ReadAttr call; endianness is determined by trying first the
// native attribute name, then the foreign one; an endian swapping function can
// be passed, if null data won't be swapped; if <isForeign> set the foreign endianness
// will be read directly without first trying the native one
ReadAttrResult GetAttrInfo(const BNode *, const char *hostAttrName, const char *foreignAttrName,
type_code * = NULL, size_t * = NULL);
status_t FSCreateNewFolder(const entry_ref *);
status_t FSRecursiveCreateFolder(const char *path);
void FSMakeOriginalName(BString &name, const BDirectory *destDir, const char *suffix = 0);
status_t TrackerLaunch(const entry_ref *app, bool async);
status_t TrackerLaunch(const BMessage *refs, bool async, bool okToRunOpenWith = true);
status_t TrackerLaunch(const entry_ref *app, const BMessage *refs, bool async,
bool okToRunOpenWith = true);
status_t LaunchBrokenLink(const char *, const BMessage *);
status_t FSFindTrackerSettingsDir(BPath *, bool autoCreate = true);
bool FSIsDeskDir(const BEntry *, dev_t);
bool ConfirmChangeIfWellKnownDirectory(const BEntry *entry, const char *action,
bool dontAsk = false, int32 *confirmedAlready = NULL);
// Deprecated calls use newer calls above instead
void FSLaunchItem(const entry_ref *, BMessage * = NULL, int32 workspace = -1);
status_t FSLaunchItem(const entry_ref *, BMessage *,
int32 workspace, bool asynch);
void FSOpenWithDocuments(const entry_ref *executableToLaunch,
BMessage *documentEntryRefs);
status_t FSLaunchUsing(const entry_ref *ref, BMessage *listOfRefs);
// some extra directory_which values
// move these to FindDirectory.h
const uint32 B_USER_MAIL_DIRECTORY = 3500;
const uint32 B_USER_QUERIES_DIRECTORY = 3501;
const uint32 B_USER_PEOPLE_DIRECTORY = 3502;
const uint32 B_USER_DOWNLOADS_DIRECTORY = 3503;
const uint32 B_USER_DESKBAR_APPS_DIRECTORY = 3504;
const uint32 B_USER_DESKBAR_PREFERENCES_DIRECTORY = 3505;
const uint32 B_USER_DESKBAR_DEVELOP_DIRECTORY = 3506;
const int32 B_BOOT_DISK = 10000000;
// map /boot into the directory_which enum for convenience
class WellKnowEntryList {
// matches up names, id's and node_refs of well known entries in the
// system hierarchy
public:
struct WellKnownEntry {
WellKnownEntry(const node_ref *node, directory_which which, const char *name)
:
node(*node),
which(which),
name(name)
{
}
// mwcc needs these explicitly to use vector
WellKnownEntry(const WellKnownEntry &clone)
:
node(clone.node),
which(clone.which),
name(clone.name)
{
}
WellKnownEntry()
{
}
node_ref node;
directory_which which;
const char *name;
};
static directory_which Match(const node_ref *);
static const WellKnownEntry *MatchEntry(const node_ref *);
static void Quit();
private:
const WellKnownEntry *MatchEntryCommon(const node_ref *);
WellKnowEntryList();
void AddOne(directory_which, const char *name);
void AddOne(directory_which, const char *path, const char *name);
void AddOne(directory_which, directory_which base, const char *extension,
const char *name);
std::vector<WellKnownEntry> entries;
static WellKnowEntryList *self;
};
#if B_BEOS_VERSION_DANO
#undef _IMPEXP_TRACKER
#endif
} // namespace BPrivate
using namespace BPrivate;
#endif /* FS_UTILS_H */
@@ -1,119 +0,0 @@
/*
* Copyright 2005, Jérôme Duval. All rights reserved.
* Distributed under the terms of the MIT License.
*
*/
#include "InstallerCopyLoopControl.h"
#include "InstallerWindow.h"
#include <stdio.h>
#include <Alert.h>
InstallerCopyLoopControl::InstallerCopyLoopControl(InstallerWindow *window)
: fWindow(window),
fMessenger(window),
fUserCanceled(false)
{
}
bool
InstallerCopyLoopControl::FileError(const char *message, const char *name, status_t error,
bool allowContinue)
{
char buffer[512];
sprintf(buffer, message, name, strerror(error));
if (allowContinue)
return (new BAlert("", buffer, "Cancel", "OK", 0,
B_WIDTH_AS_USUAL, B_STOP_ALERT))->Go() != 0;
(new BAlert("", buffer, "Cancel", 0, 0,
B_WIDTH_AS_USUAL, B_STOP_ALERT))->Go();
return false;
}
void
InstallerCopyLoopControl::UpdateStatus(const char *name, entry_ref ref, int32 count,
bool optional)
{
if (name) {
BMessage msg(STATUS_MESSAGE);
BString s = "Installing ";
s << name;
msg.AddString("status", s.String());
fMessenger.SendMessage(&msg);
}
}
bool
InstallerCopyLoopControl::CheckUserCanceled()
{
return fUserCanceled;
}
InstallerCopyLoopControl::OverwriteMode
InstallerCopyLoopControl::OverwriteOnConflict(const BEntry *srcEntry,
const char *destName, const BDirectory *destDir, bool srcIsDir,
bool dstIsDir)
{
if (srcIsDir && dstIsDir)
return kMerge;
else
return kReplace;
}
bool
InstallerCopyLoopControl::SkipEntry(const BEntry *, bool file)
{
return false;
}
void
InstallerCopyLoopControl::ChecksumChunk(const char *block, size_t size)
{
}
bool
InstallerCopyLoopControl::ChecksumFile(const entry_ref *ref)
{
return true;
}
bool
InstallerCopyLoopControl::SkipAttribute(const char *attributeName)
{
return false;
}
bool
InstallerCopyLoopControl::PreserveAttribute(const char *attributeName)
{
return false;
}
bool
InstallerCopyLoopControl::Cancel()
{
fUserCanceled = (new BAlert("",
"Are you sure you want to to stop the installation?",
"Continue", "Stop", 0,
B_WIDTH_AS_USUAL, B_STOP_ALERT))->Go() != 0;
return fUserCanceled;
}
void
InstallerCopyLoopControl::Reset()
{
fUserCanceled = false;
}
@@ -1,47 +0,0 @@
/*
* Copyright 2005, Jérôme Duval. All rights reserved.
* Distributed under the terms of the MIT License.
*
*/
#ifndef _INSTALLERCOPYLOOPCONTROL_H
#define _INSTALLERCOPYLOOPCONTROL_H
#include "FSUndoRedo.h"
#include "FSUtils.h"
class InstallerWindow;
class InstallerCopyLoopControl : public CopyLoopControl
{
public:
InstallerCopyLoopControl(InstallerWindow *window);
virtual ~InstallerCopyLoopControl() {};
virtual bool FileError(const char *message, const char *name, status_t error,
bool allowContinue);
virtual void UpdateStatus(const char *name, entry_ref ref, int32 count,
bool optional = false);
virtual bool CheckUserCanceled();
virtual OverwriteMode OverwriteOnConflict(const BEntry *srcEntry,
const char *destName, const BDirectory *destDir, bool srcIsDir,
bool dstIsDir);
virtual bool SkipEntry(const BEntry *, bool file);
virtual void ChecksumChunk(const char *block, size_t size);
virtual bool ChecksumFile(const entry_ref *);
virtual bool SkipAttribute(const char *attributeName);
virtual bool PreserveAttribute(const char *attributeName);
bool Cancel();
void Reset();
private:
InstallerWindow *fWindow;
BMessenger fMessenger;
bool fUserCanceled;
};
#endif
+16 -15
View File
@@ -16,6 +16,7 @@
#include <Button.h>
#include <ClassInfo.h>
#include <Directory.h>
#include <FindDirectory.h>
#include <GridLayoutBuilder.h>
#include <GroupLayoutBuilder.h>
#include <LayoutUtils.h>
@@ -35,10 +36,10 @@
#include "tracker_private.h"
#include "CopyEngine.h"
#include "DialogPane.h"
#include "PackageViews.h"
#include "PartitionMenuItem.h"
#include "WorkerThread.h"
#define DRIVESETUP_SIG "application/x-vnd.Haiku-DriveSetup"
@@ -209,7 +210,7 @@ InstallerWindow::InstallerWindow()
fNeedsToCenterOnScreen(true),
fDriveSetupLaunched(false),
fInstallStatus(kReadyForInstall),
fCopyEngine(new CopyEngine(this)),
fWorkerThread(new WorkerThread(this)),
fCopyEngineLock(NULL)
{
LogoView* logoView = new LogoView();
@@ -265,7 +266,7 @@ InstallerWindow::InstallerWindow()
"Setup partitions" B_UTF8_ELLIPSIS, new BMessage(SETUP_MESSAGE));
fMakeBootableButton = new BButton("makebootable_button",
"Write Boot Sector", new BMessage(kWriteBootSector));
"Write Boot Sector", new BMessage(MSG_WRITE_BOOT_SECTOR));
fMakeBootableButton->SetEnabled(false);
SetLayout(new BGroupLayout(B_HORIZONTAL));
@@ -357,7 +358,7 @@ void
InstallerWindow::MessageReceived(BMessage *msg)
{
switch (msg->what) {
case RESET_INSTALL:
case MSG_RESET:
delete fCopyEngineLock;
fCopyEngineLock = NULL;
@@ -383,11 +384,11 @@ InstallerWindow::MessageReceived(BMessage *msg)
BList* list = new BList();
int32 size = 0;
fPackagesView->GetPackagesToInstall(list, &size);
fCopyEngine->SetLock(fCopyEngineLock);
fCopyEngine->SetPackagesList(list);
fCopyEngine->SetSpaceRequired(size);
fWorkerThread->SetLock(fCopyEngineLock);
fWorkerThread->SetPackagesList(list);
fWorkerThread->SetSpaceRequired(size);
fInstallStatus = kInstalling;
BMessenger(fCopyEngine).SendMessage(ENGINE_START);
fWorkerThread->StartInstall();
fBeginButton->SetLabel("Stop");
_DisableInterface(true);
@@ -402,7 +403,7 @@ InstallerWindow::MessageReceived(BMessage *msg)
case kInstalling:
{
_QuitCopyEngine(true);
// if (fCopyEngine->Cancel()) {
// if (fWorkerThread->Cancel()) {
// fInstallStatus = kCancelled;
// _SetStatusMessage("Installation cancelled.");
// fProgressLayoutItem->SetVisible(false);
@@ -440,7 +441,7 @@ InstallerWindow::MessageReceived(BMessage *msg)
fSizeView->SetText(string);
break;
}
case STATUS_MESSAGE:
case MSG_STATUS_MESSAGE:
{
// TODO: Was this supposed to prevent status messages still arriving
// after the copy engine was shut down?
@@ -472,7 +473,7 @@ InstallerWindow::MessageReceived(BMessage *msg)
}
break;
}
case INSTALL_FINISHED:
case MSG_INSTALL_FINISHED:
{
delete fCopyEngineLock;
fCopyEngineLock = NULL;
@@ -512,8 +513,8 @@ InstallerWindow::MessageReceived(BMessage *msg)
}
break;
}
case kWriteBootSector:
fCopyEngine->WriteBootSector(fDestMenu);
case MSG_WRITE_BOOT_SECTOR:
fWorkerThread->WriteBootSector(fDestMenu);
break;
default:
@@ -533,7 +534,7 @@ InstallerWindow::QuitRequested()
return false;
}
_QuitCopyEngine(false);
fCopyEngine->PostMessage(B_QUIT_REQUESTED);
fWorkerThread->PostMessage(B_QUIT_REQUESTED);
be_app->PostMessage(B_QUIT_REQUESTED);
return true;
}
@@ -597,7 +598,7 @@ InstallerWindow::_ScanPartitions()
while ((item = fDestMenu->RemoveItem((int32)0)))
delete item;
fCopyEngine->ScanDisksPartitions(fSrcMenu, fDestMenu);
fWorkerThread->ScanDisksPartitions(fSrcMenu, fDestMenu);
if (fSrcMenu->ItemAt(0)) {
_PublishPackages();
+6 -6
View File
@@ -22,8 +22,8 @@ class BMenuField;
class BStatusBar;
class BStringView;
class BTextView;
class CopyEngine;
class PackagesView;
class WorkerThread;
enum InstallStatus {
kReadyForInstall,
@@ -32,10 +32,10 @@ enum InstallStatus {
kCancelled
};
const uint32 STATUS_MESSAGE = 'iSTM';
const uint32 INSTALL_FINISHED = 'iIFN';
const uint32 RESET_INSTALL = 'iRSI';
const uint32 kWriteBootSector = 'iWBS';
const uint32 MSG_STATUS_MESSAGE = 'iSTM';
const uint32 MSG_INSTALL_FINISHED = 'iIFN';
const uint32 MSG_RESET = 'iRSI';
const uint32 MSG_WRITE_BOOT_SECTOR = 'iWBS';
const char PACKAGES_DIRECTORY[] = "_packages_";
const char VAR_DIRECTORY[] = "var";
@@ -92,7 +92,7 @@ private:
bool fDriveSetupLaunched;
InstallStatus fInstallStatus;
CopyEngine* fCopyEngine;
WorkerThread* fWorkerThread;
BString fLastStatus;
BLocker* fCopyEngineLock;
};
+1 -3
View File
@@ -4,13 +4,11 @@ UsePrivateHeaders shared storage tracker ;
SubDirHdrs [ FDirName $(HAIKU_TOP) src kits tracker ] ;
Application Installer :
CopyEngine.cpp
CopyEngine2.cpp
FSUtils.cpp
InstallerApp.cpp
InstallerCopyLoopControl.cpp
InstallerWindow.cpp
PackageViews.cpp
PartitionMenuItem.cpp
WorkerThread.cpp
: be tracker translation $(TARGET_LIBSTDC++)
: Installer.rdef ;
+2 -2
View File
@@ -178,11 +178,11 @@ PackageCheckBox::MouseMoved(BPoint point, uint32 transit,
{
printf("%s called\n", __PRETTY_FUNCTION__);
if (transit == B_ENTERED_VIEW) {
BMessage msg(STATUS_MESSAGE);
BMessage msg(MSG_STATUS_MESSAGE);
msg.AddString("status", fPackage->Description());
BMessenger(NULL, Window()).SendMessage(&msg);
} else if (transit == B_EXITED_VIEW) {
BMessage msg(STATUS_MESSAGE);
BMessage msg(MSG_STATUS_MESSAGE);
BMessenger(NULL, Window()).SendMessage(&msg);
}
}
-798
View File
@@ -1,798 +0,0 @@
// Vector.h
//
// Copyright (c) 2003, Ingo Weinhold ([email protected])
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
//
// Except as contained in this notice, the name of a copyright holder shall
// not be used in advertising or otherwise to promote the sale, use or other
// dealings in this Software without prior written authorization of the
// copyright holder.
#ifndef _INSTALLER_VECTOR_H
#define _INSTALLER_VECTOR_H
#include <new>
#include <stdlib.h>
#include <string.h>
#include <SupportDefs.h>
template<typename Value> class VectorIterator;
// for convenience
#define _VECTOR_TEMPLATE_LIST template<typename Value>
#define _VECTOR_CLASS_NAME Vector<Value>
/*!
\class Vector
\brief A generic vector implementation.
*/
template<typename Value>
class Vector {
public:
typedef VectorIterator<Value> Iterator;
typedef VectorIterator<const Value> ConstIterator;
private:
static const size_t kDefaultChunkSize = 10;
static const size_t kMaximalChunkSize = 1024 * 1024;
public:
Vector(size_t chunkSize = kDefaultChunkSize);
~Vector();
status_t PushFront(const Value &value);
status_t PushBack(const Value &value);
void PopFront();
void PopBack();
status_t Insert(const Value &value, int32 index);
status_t Insert(const Value &value, const Iterator &iterator);
int32 Remove(const Value &value);
Iterator Erase(int32 index);
Iterator Erase(const Iterator &iterator);
inline int32 Count() const;
inline bool IsEmpty() const;
void MakeEmpty();
inline Iterator Begin();
inline ConstIterator Begin() const;
inline Iterator End();
inline ConstIterator End() const;
inline Iterator Null();
inline ConstIterator Null() const;
inline Iterator IteratorForIndex(int32 index);
inline ConstIterator IteratorForIndex(int32 index) const;
inline const Value &ElementAt(int32 index) const;
inline Value &ElementAt(int32 index);
int32 IndexOf(const Value &value, int32 start = 0) const;
Iterator Find(const Value &value);
Iterator Find(const Value &value, const Iterator &start);
ConstIterator Find(const Value &value) const;
ConstIterator Find(const Value &value, const ConstIterator &start) const;
inline Value &operator[](int32 index);
inline const Value &operator[](int32 index) const;
// debugging
int32 GetCapacity() const { return fCapacity; }
private:
inline static void _MoveItems(Value *values, int32 offset, int32 count);
bool _Resize(size_t count);
inline int32 _IteratorIndex(const Iterator &iterator) const;
inline int32 _IteratorIndex(const ConstIterator &iterator) const;
private:
size_t fCapacity;
size_t fChunkSize;
int32 fItemCount;
Value *fItems;
};
// VectorIterator
template<typename Value>
class VectorIterator {
private:
typedef VectorIterator<Value> Iterator;
public:
inline VectorIterator<Value>()
: fElement(NULL)
{
}
inline VectorIterator<Value>(const Iterator &other)
: fElement(other.fElement)
{
}
inline Iterator &operator++()
{
if (fElement)
++fElement;
return *this;
}
inline Iterator operator++(int)
{
Iterator it(*this);
++*this;
return it;
}
inline Iterator &operator--()
{
if (fElement)
--fElement;
return *this;
}
inline Iterator operator--(int)
{
Iterator it(*this);
--*this;
return it;
}
inline Iterator &operator=(const Iterator &other)
{
fElement = other.fElement;
return *this;
}
inline bool operator==(const Iterator &other) const
{
return (fElement == other.fElement);
}
inline bool operator!=(const Iterator &other) const
{
return !(*this == other);
}
inline Value &operator*() const
{
return *fElement;
}
inline Value *operator->() const
{
return fElement;
}
inline operator bool() const
{
return fElement;
}
// private
public:
inline VectorIterator<Value>(Value *element)
: fElement(element)
{
}
inline Value *Element() const
{
return fElement;
}
protected:
Value *fElement;
};
// Vector
// constructor
/*! \brief Creates an empty vector.
\param chunkSize The granularity for the vector's capacity, i.e. the
minimal number of elements the capacity grows or shrinks when
necessary.
*/
_VECTOR_TEMPLATE_LIST
_VECTOR_CLASS_NAME::Vector(size_t chunkSize)
: fCapacity(0),
fChunkSize(chunkSize),
fItemCount(0),
fItems(NULL)
{
if (fChunkSize == 0 || fChunkSize > kMaximalChunkSize)
fChunkSize = kDefaultChunkSize;
_Resize(0);
}
// destructor
/*! \brief Frees all resources associated with the object.
The contained elements are destroyed. Note, that, if the element
type is a pointer type, only the pointer is destroyed, not the object
it points to.
*/
_VECTOR_TEMPLATE_LIST
_VECTOR_CLASS_NAME::~Vector()
{
MakeEmpty();
free(fItems);
}
// PushFront
/*! \brief Inserts a copy of the supplied value at the beginning of the
vector.
\param value The element to be inserted.
\return
- \c B_OK: Everything went fine.
- \c B_NO_MEMORY: Insufficient memory for this operation.
*/
_VECTOR_TEMPLATE_LIST
status_t
_VECTOR_CLASS_NAME::PushFront(const Value &value)
{
return Insert(value, 0);
}
// PushBack
/*! \brief Inserts a copy of the supplied value at the end of the vector.
\param value The element to be inserted.
\return
- \c B_OK: Everything went fine.
- \c B_NO_MEMORY: Insufficient memory for this operation.
*/
_VECTOR_TEMPLATE_LIST
status_t
_VECTOR_CLASS_NAME::PushBack(const Value &value)
{
return Insert(value, fItemCount);
}
// PopFront
/*! \brief Removes the first element of the vector.
Invocation on an empty vector is harmless.
*/
_VECTOR_TEMPLATE_LIST
void
_VECTOR_CLASS_NAME::PopFront()
{
if (fItemCount > 0)
Erase(0);
}
// PopBack
/*! \brief Removes the last element of the vector.
Invocation on an empty vector is harmless.
*/
_VECTOR_TEMPLATE_LIST
void
_VECTOR_CLASS_NAME::PopBack()
{
if (fItemCount > 0)
Erase(fItemCount - 1);
}
// _MoveItems
/*! \brief Moves elements within an array.
\param items The elements to be moved.
\param offset The index to which the elements shall be moved. May be
negative.
\param count The number of elements to be moved.
*/
_VECTOR_TEMPLATE_LIST
inline
void
_VECTOR_CLASS_NAME::_MoveItems(Value* items, int32 offset, int32 count)
{
if (count > 0 && offset != 0)
memmove(items + offset, items, count * sizeof(Value));
}
// Insert
/*! \brief Inserts a copy of the the supplied value at the given index.
\param value The value to be inserted.
\param index The index at which to insert the new element. It must
hold: 0 <= \a index <= Count().
\return
- \c B_OK: Everything went fine.
- \c B_BAD_VALUE: \a index is out of range.
- \c B_NO_MEMORY: Insufficient memory for this operation.
*/
_VECTOR_TEMPLATE_LIST
status_t
_VECTOR_CLASS_NAME::Insert(const Value &value, int32 index)
{
if (index < 0 || index > fItemCount)
return B_BAD_VALUE;
if (!_Resize(fItemCount + 1))
return B_NO_MEMORY;
_MoveItems(fItems + index, 1, fItemCount - index - 1);
new(fItems + index) Value(value);
return B_OK;
}
// Insert
/*! \brief Inserts a copy of the the supplied value at the given position.
\param value The value to be inserted.
\param iterator An iterator specifying the position at which to insert
the new element.
\return
- \c B_OK: Everything went fine.
- \c B_BAD_VALUE: \a iterator is is invalid.
- \c B_NO_MEMORY: Insufficient memory for this operation.
*/
_VECTOR_TEMPLATE_LIST
status_t
_VECTOR_CLASS_NAME::Insert(const Value &value, const Iterator &iterator)
{
int32 index = _IteratorIndex(iterator);
if (index >= 0)
return Insert(value, index);
return B_BAD_VALUE;
}
// Remove
/*! \brief Removes all elements of the supplied value.
\param value The value of the elements to be removed.
\return The number of removed occurrences.
*/
_VECTOR_TEMPLATE_LIST
int32
_VECTOR_CLASS_NAME::Remove(const Value &value)
{
int32 count = 0;
for (int32 i = fItemCount - 1; i >= 0; i--) {
if (ElementAt(i) == value) {
Erase(i);
count++;
}
}
return count;
}
// Erase
/*! \brief Removes the element at the given index.
\param index The position of the element to be removed.
\return An iterator referring to the element now being located at index
\a index (End(), if it was the last element that has been
removed), or Null(), if \a index was out of range.
*/
_VECTOR_TEMPLATE_LIST
_VECTOR_CLASS_NAME::Iterator
_VECTOR_CLASS_NAME::Erase(int32 index)
{
if (index >= 0 && index < fItemCount) {
fItems[index].~Value();
_MoveItems(fItems + index + 1, -1, fItemCount - index - 1);
_Resize(fItemCount - 1);
return Iterator(fItems + index);
}
return Null();
}
// Erase
/*! \brief Removes the element at the given position.
\param iterator An iterator referring to the element to be removed.
\return An iterator referring to the element succeeding the removed
one (End(), if it was the last element that has been
removed), or Null(), if \a iterator was an invalid iterator
(in this case including End()).
*/
_VECTOR_TEMPLATE_LIST
_VECTOR_CLASS_NAME::Iterator
_VECTOR_CLASS_NAME::Erase(const Iterator &iterator)
{
int32 index = _IteratorIndex(iterator);
if (index >= 0 && index < fItemCount)
return Erase(index);
return Null();
}
// Count
/*! \brief Returns the number of elements the vector contains.
\return The number of elements the vector contains.
*/
_VECTOR_TEMPLATE_LIST
inline
int32
_VECTOR_CLASS_NAME::Count() const
{
return fItemCount;
}
// IsEmpty
/*! \brief Returns whether the vector is empty.
\return \c true, if the vector is empty, \c false otherwise.
*/
_VECTOR_TEMPLATE_LIST
inline
bool
_VECTOR_CLASS_NAME::IsEmpty() const
{
return (fItemCount == 0);
}
// MakeEmpty
/*! \brief Removes all elements from the vector.
*/
_VECTOR_TEMPLATE_LIST
void
_VECTOR_CLASS_NAME::MakeEmpty()
{
for (int32 i = 0; i < fItemCount; i++)
fItems[i].~Value();
_Resize(0);
}
// Begin
/*! \brief Returns an iterator referring to the beginning of the vector.
If the vector is not empty, Begin() refers to its first element,
otherwise it is equal to End() and must not be dereferenced!
\return An iterator referring to the beginning of the vector.
*/
_VECTOR_TEMPLATE_LIST
inline
_VECTOR_CLASS_NAME::Iterator
_VECTOR_CLASS_NAME::Begin()
{
return Iterator(fItems);
}
// Begin
/*! \brief Returns an iterator referring to the beginning of the vector.
If the vector is not empty, Begin() refers to its first element,
otherwise it is equal to End() and must not be dereferenced!
\return An iterator referring to the beginning of the vector.
*/
_VECTOR_TEMPLATE_LIST
inline
_VECTOR_CLASS_NAME::ConstIterator
_VECTOR_CLASS_NAME::Begin() const
{
return ConstIterator(fItems);
}
// End
/*! \brief Returns an iterator referring to the end of the vector.
The position identified by End() is the one succeeding the last
element, i.e. it must not be dereferenced!
\return An iterator referring to the end of the vector.
*/
_VECTOR_TEMPLATE_LIST
inline
_VECTOR_CLASS_NAME::Iterator
_VECTOR_CLASS_NAME::End()
{
return Iterator(fItems + fItemCount);
}
// End
/*! \brief Returns an iterator referring to the end of the vector.
The position identified by End() is the one succeeding the last
element, i.e. it must not be dereferenced!
\return An iterator referring to the end of the vector.
*/
_VECTOR_TEMPLATE_LIST
inline
_VECTOR_CLASS_NAME::ConstIterator
_VECTOR_CLASS_NAME::End() const
{
return ConstIterator(fItems + fItemCount);
}
// Null
/*! \brief Returns an invalid iterator.
Null() is used as a return value, if something went wrong. It must
neither be incremented or decremented nor dereferenced!
\return An invalid iterator.
*/
_VECTOR_TEMPLATE_LIST
inline
_VECTOR_CLASS_NAME::Iterator
_VECTOR_CLASS_NAME::Null()
{
return Iterator(NULL);
}
// Null
/*! \brief Returns an invalid iterator.
Null() is used as a return value, if something went wrong. It must
neither be incremented or decremented nor dereferenced!
\return An invalid iterator.
*/
_VECTOR_TEMPLATE_LIST
inline
_VECTOR_CLASS_NAME::ConstIterator
_VECTOR_CLASS_NAME::Null() const
{
return ConstIterator(NULL);
}
// IteratorForIndex
/*! \brief Returns an iterator for a given index.
\return An iterator referring to the same element as \a index, or
End(), if \a index is out of range.
*/
_VECTOR_TEMPLATE_LIST
inline
_VECTOR_CLASS_NAME::Iterator
_VECTOR_CLASS_NAME::IteratorForIndex(int32 index)
{
if (index >= 0 && index <= fItemCount)
return Iterator(fItems + index);
return End();
}
// IteratorForIndex
/*! \brief Returns an iterator for a given index.
\return An iterator referring to the same element as \a index, or
End(), if \a index is out of range.
*/
_VECTOR_TEMPLATE_LIST
inline
_VECTOR_CLASS_NAME::ConstIterator
_VECTOR_CLASS_NAME::IteratorForIndex(int32 index) const
{
if (index >= 0 && index <= fItemCount)
return ConstIterator(fItems + index);
return End();
}
// ElementAt
/*! \brief Returns the element at a given index.
\param index The index identifying the element to be returned.
\return The element identified by the given index.
*/
_VECTOR_TEMPLATE_LIST
inline
const Value &
_VECTOR_CLASS_NAME::ElementAt(int32 index) const
{
if (index >= 0 && index < fItemCount)
return fItems[index];
// Return the 0th element by default. Unless the allocation failed, there
// is always a 0th element -- uninitialized perhaps.
return fItems[0];
}
// ElementAt
/*! \brief Returns the element at a given index.
\param index The index identifying the element to be returned.
\return The element identified by the given index.
*/
_VECTOR_TEMPLATE_LIST
inline
Value &
_VECTOR_CLASS_NAME::ElementAt(int32 index)
{
if (index >= 0 && index < fItemCount)
return fItems[index];
// Return the 0th element by default. Unless the allocation failed, there
// is always a 0th element -- uninitialized perhaps.
return fItems[0];
}
// IndexOf
/*! \brief Returns the index of the next element with the specified value.
\param value The value of the element to be found.
\param start The index at which to be started to search for the element.
\return The index of the found element, or \c -1, if no further element
with the given value could be found or \a index is out of range.
*/
_VECTOR_TEMPLATE_LIST
int32
_VECTOR_CLASS_NAME::IndexOf(const Value &value, int32 start) const
{
if (start >= 0) {
for (int32 i = start; i < fItemCount; i++) {
if (fItems[i] == value)
return i;
}
}
return -1;
}
// Find
/*! \brief Returns an iterator referring to the next element with the
specified value.
\param value The value of the element to be found.
\return An iterator referring to the found element, or End(), if no
further with the given value could be found.
*/
_VECTOR_TEMPLATE_LIST
inline
_VECTOR_CLASS_NAME::Iterator
_VECTOR_CLASS_NAME::Find(const Value &value)
{
return Find(value, Begin());
}
// Find
/*! \brief Returns an iterator referring to the next element with the
specified value.
\param value The value of the element to be found.
\param start And iterator specifying where to start searching for the
element.
\return An iterator referring to the found element, or End(), if no
further with the given value could be found or \a start was
invalid.
*/
_VECTOR_TEMPLATE_LIST
_VECTOR_CLASS_NAME::Iterator
_VECTOR_CLASS_NAME::Find(const Value &value, const Iterator &start)
{
int32 index = IndexOf(value, _IteratorIndex(start));
if (index >= 0)
return Iterator(fItems + index);
return End();
}
// Find
/*! \brief Returns an iterator referring to the of the next element with the
specified value.
\param value The value of the element to be found.
\return An iterator referring to the found element, or End(), if no
further with the given value could be found.
*/
_VECTOR_TEMPLATE_LIST
inline
_VECTOR_CLASS_NAME::ConstIterator
_VECTOR_CLASS_NAME::Find(const Value &value) const
{
return Find(value, Begin());
}
// Find
/*! \brief Returns an iterator referring to the of the next element with the
specified value.
\param value The value of the element to be found.
\param start And iterator specifying where to start searching for the
element.
\return An iterator referring to the found element, or End(), if no
further with the given value could be found or \a start was
invalid.
*/
_VECTOR_TEMPLATE_LIST
_VECTOR_CLASS_NAME::ConstIterator
_VECTOR_CLASS_NAME::Find(const Value &value, const ConstIterator &start) const
{
int32 index = IndexOf(value, _IteratorIndex(start));
if (index >= 0)
return ConstIterator(fItems + index);
return End();
}
// []
/*! \brief Semantically equivalent to ElementAt().
*/
_VECTOR_TEMPLATE_LIST
inline
Value &
_VECTOR_CLASS_NAME::operator[](int32 index)
{
return ElementAt(index);
}
// []
/*! \brief Semantically equivalent to ElementAt().
*/
_VECTOR_TEMPLATE_LIST
inline
const Value &
_VECTOR_CLASS_NAME::operator[](int32 index) const
{
return ElementAt(index);
}
// _Resize
/*! \brief Resizes the vector.
The internal element array will be grown or shrunk to the next multiple
of \a fChunkSize >= \a count, but no less than \a fChunkSize.
Also adjusts \a fItemCount according to the supplied \a count, but does
not invoke a destructor or constructor on any element.
\param count The number of element.
\return \c true, if everything went fine, \c false, if the memory
allocation failed.
*/
_VECTOR_TEMPLATE_LIST
bool
_VECTOR_CLASS_NAME::_Resize(size_t count)
{
bool result = true;
// calculate the new capacity
int32 newSize = count;
if (newSize <= 0)
newSize = 1;
newSize = ((newSize - 1) / fChunkSize + 1) * fChunkSize;
// resize if necessary
if ((size_t)newSize != fCapacity) {
Value* newItems = (Value*)realloc(fItems, newSize * sizeof(Value));
if (newItems) {
fItems = newItems;
fCapacity = newSize;
} else
result = false;
}
if (result)
fItemCount = count;
return result;
}
// _IteratorIndex
/*! \brief Returns index of the element the supplied iterator refers to.
\return The index of the element the supplied iterator refers to, or
\c -1, if the iterator is invalid (End() is considered valid
here, and Count() is returned).
*/
_VECTOR_TEMPLATE_LIST
inline
int32
_VECTOR_CLASS_NAME::_IteratorIndex(const Iterator &iterator) const
{
if (iterator.Element()) {
int32 index = iterator.Element() - fItems;
if (index >= 0 && index <= fItemCount)
return index;
}
return -1;
}
// _IteratorIndex
/*! \brief Returns index of the element the supplied iterator refers to.
\return The index of the element the supplied iterator refers to, or
\c -1, if the iterator is invalid (End() is considered valid
here, and Count() is returned).
*/
_VECTOR_TEMPLATE_LIST
inline
int32
_VECTOR_CLASS_NAME::_IteratorIndex(const ConstIterator &iterator) const
{
if (iterator.Element()) {
int32 index = iterator.Element() - fItems;
if (index >= 0 && index <= fItemCount)
return index;
}
return -1;
}
#endif // _INSTALLER_VECTOR_H
@@ -1,26 +1,30 @@
/*
* Copyright 2005-2008, Jérôme DUVAL. All rights reserved.
* Distributed under the terms of the MIT License.
* Copyright 2009, Stephan Aßmus <superstippi@gmx.de>.
* Copyright 2005-2008, Jérôme DUVAL.
* All rights reserved. Distributed under the terms of the MIT License.
*/
#include "CopyEngine.h"
#include "WorkerThread.h"
#include <stdio.h>
#include <Alert.h>
#include <Autolock.h>
#include <Directory.h>
#include <DiskDeviceVisitor.h>
#include <DiskDeviceTypes.h>
#include <FindDirectory.h>
#include <Menu.h>
#include <MenuItem.h>
#include <Message.h>
#include <Messenger.h>
#include <Path.h>
#include <String.h>
#include <VolumeRoster.h>
#include "AutoLocker.h"
#include "CopyEngine2.h"
#include "InstallerWindow.h"
#include "FSUndoRedo.h"
#include "FSUtils.h"
#include "PackageViews.h"
#include "PartitionMenuItem.h"
@@ -28,8 +32,8 @@
//#define COPY_TRACE
#ifdef COPY_TRACE
#define CALLED() printf("CALLED %s\n",__PRETTY_FUNCTION__)
#define ERR2(x, y...) fprintf(stderr, "CopyEngine: "x" %s\n", y, strerror(err))
#define ERR(x) fprintf(stderr, "CopyEngine: "x" %s\n", strerror(err))
#define ERR2(x, y...) fprintf(stderr, "WorkerThread: "x" %s\n", y, strerror(err))
#define ERR(x) fprintf(stderr, "WorkerThread: "x" %s\n", strerror(err))
#else
#define CALLED()
#define ERR(x)
@@ -40,6 +44,10 @@ const char BOOT_PATH[] = "/boot";
extern void SizeAsString(off_t size, char *string);
const uint32 MSG_START_INSTALLING = 'eSRT';
class SourceVisitor : public BDiskDeviceVisitor
{
public:
@@ -63,37 +71,39 @@ class TargetVisitor : public BDiskDeviceVisitor
};
CopyEngine::CopyEngine(InstallerWindow *window)
// #pragma mark - WorkerThread
WorkerThread::WorkerThread(InstallerWindow *window)
: BLooper("copy_engine"),
fWindow(window),
fPackages(NULL),
fSpaceRequired(0)
{
fControl = new InstallerCopyLoopControl(window);
Run();
}
void
CopyEngine::MessageReceived(BMessage* message)
WorkerThread::MessageReceived(BMessage* message)
{
CALLED();
switch (message->what) {
case ENGINE_START:
Start(fWindow->GetSourceMenu(), fWindow->GetTargetMenu());
case MSG_START_INSTALLING:
_PerformInstall(fWindow->GetSourceMenu(), fWindow->GetTargetMenu());
break;
case kWriteBootSector:
case MSG_WRITE_BOOT_SECTOR:
{
int32 id;
if (message->FindInt32("id", &id) != B_OK) {
SetStatusMessage("Boot sector not written because of an "
_SetStatusMessage("Boot sector not written because of an "
" internal error.");
break;
}
// TODO: Refactor with Start()
// TODO: Refactor with _PerformInstall()
BPath targetDirectory;
BDiskDevice device;
BPartition* partition;
@@ -101,32 +111,32 @@ CopyEngine::MessageReceived(BMessage* message)
if (fDDRoster.GetPartitionWithID(id, &device, &partition) == B_OK) {
if (!partition->IsMounted()) {
if (partition->Mount() < B_OK) {
SetStatusMessage("The partition can't be mounted. "
_SetStatusMessage("The partition can't be mounted. "
"Please choose a different partition.");
break;
}
}
if (partition->GetMountPoint(&targetDirectory) != B_OK) {
SetStatusMessage("The mount point could not be retrieve.");
_SetStatusMessage("The mount point could not be retrieve.");
break;
}
} else if (fDDRoster.GetDeviceWithID(id, &device) == B_OK) {
if (!device.IsMounted()) {
if (device.Mount() < B_OK) {
SetStatusMessage("The disk can't be mounted. Please "
_SetStatusMessage("The disk can't be mounted. Please "
"choose a different disk.");
break;
}
}
if (device.GetMountPoint(&targetDirectory) != B_OK) {
SetStatusMessage("The mount point could not be retrieve.");
_SetStatusMessage("The mount point could not be retrieve.");
break;
}
}
LaunchFinishScript(targetDirectory);
_LaunchFinishScript(targetDirectory);
// TODO: Get error from executing script!
SetStatusMessage("Boot sector successfully written.");
_SetStatusMessage("Boot sector successfully written.");
}
default:
BLooper::MessageReceived(message);
@@ -134,17 +144,67 @@ CopyEngine::MessageReceived(BMessage* message)
}
void
CopyEngine::SetStatusMessage(const char *status)
WorkerThread::ScanDisksPartitions(BMenu *srcMenu, BMenu *targetMenu)
{
BMessage msg(STATUS_MESSAGE);
msg.AddString("status", status);
BMessenger(fWindow).SendMessage(&msg);
// NOTE: This is actually executed in the window thread.
BDiskDevice device;
BPartition *partition = NULL;
printf("\nScanDisksPartitions source partitions begin\n");
SourceVisitor srcVisitor(srcMenu);
fDDRoster.VisitEachMountedPartition(&srcVisitor, &device, &partition);
printf("\nScanDisksPartitions target partitions begin\n");
TargetVisitor targetVisitor(targetMenu);
fDDRoster.VisitEachPartition(&targetVisitor, &device, &partition);
}
void
CopyEngine::LaunchInitScript(BPath &path)
WorkerThread::SetPackagesList(BList *list)
{
// Executed in window thread.
BAutolock _(this);
delete fPackages;
fPackages = list;
}
void
WorkerThread::StartInstall()
{
// Executed in window thread.
PostMessage(MSG_START_INSTALLING, this);
}
void
WorkerThread::WriteBootSector(BMenu* targetMenu)
{
// Executed in window thread.
CALLED();
PartitionMenuItem* item = (PartitionMenuItem*)targetMenu->FindMarked();
if (item == NULL) {
ERR("bad menu items\n");
return;
}
BMessage message(MSG_WRITE_BOOT_SECTOR);
message.AddInt32("id", item->ID());
PostMessage(&message, this);
}
// #pragma mark -
void
WorkerThread::_LaunchInitScript(BPath &path)
{
BPath bootPath;
find_directory(B_BEOS_BOOT_DIRECTORY, &bootPath);
@@ -152,13 +212,13 @@ CopyEngine::LaunchInitScript(BPath &path)
command += bootPath.Path();
command += "/InstallerInitScript ";
command += path.Path();
SetStatusMessage("Starting Installation.");
_SetStatusMessage("Starting Installation.");
system(command.String());
}
void
CopyEngine::LaunchFinishScript(BPath &path)
WorkerThread::_LaunchFinishScript(BPath &path)
{
BPath bootPath;
find_directory(B_BEOS_BOOT_DIRECTORY, &bootPath);
@@ -166,27 +226,27 @@ CopyEngine::LaunchFinishScript(BPath &path)
command += bootPath.Path();
command += "/InstallerFinishScript ";
command += path.Path();
SetStatusMessage("Finishing Installation.");
_SetStatusMessage("Finishing Installation.");
system(command.String());
}
void
CopyEngine::Start(BMenu *srcMenu, BMenu *targetMenu)
WorkerThread::_PerformInstall(BMenu *srcMenu, BMenu *targetMenu)
{
CALLED();
BPath targetDirectory, srcDirectory;
BDirectory targetDir, srcDir;
BDirectory targetDir;
BDiskDevice device;
BPartition *partition;
BVolume targetVolume;
status_t err = B_OK;
int32 entries = 0;
entry_ref testRef;
bigtime_t now;
fControl->Reset();
BMessenger messenger(fWindow);
CopyEngine2 engine(messenger, new BMessage(MSG_STATUS_MESSAGE));
PartitionMenuItem *targetItem = (PartitionMenuItem *)targetMenu->FindMarked();
PartitionMenuItem *srcItem = (PartitionMenuItem *)srcMenu->FindMarked();
@@ -201,7 +261,7 @@ bigtime_t now;
if (fDDRoster.GetPartitionWithID(targetItem->ID(), &device, &partition) == B_OK) {
if (!partition->IsMounted()) {
if ((err = partition->Mount()) < B_OK) {
SetStatusMessage("The disk can't be mounted. Please choose a "
_SetStatusMessage("The disk can't be mounted. Please choose a "
"different disk.");
ERR("BPartition::Mount");
goto error;
@@ -218,7 +278,7 @@ bigtime_t now;
} else if (fDDRoster.GetDeviceWithID(targetItem->ID(), &device) == B_OK) {
if (!device.IsMounted()) {
if ((err = device.Mount()) < B_OK) {
SetStatusMessage("The disk can't be mounted. Please choose a "
_SetStatusMessage("The disk can't be mounted. Please choose a "
"different disk.");
ERR("BDiskDevice::Mount");
goto error;
@@ -259,7 +319,7 @@ bigtime_t now;
// check not installing on itself
if (strcmp(srcDirectory.Path(), targetDirectory.Path()) == 0) {
SetStatusMessage("You can't install the contents of a disk onto "
_SetStatusMessage("You can't install the contents of a disk onto "
"itself. Please choose a different disk.");
goto error;
}
@@ -270,7 +330,7 @@ bigtime_t now;
"current boot disk? The Installer will have to reboot your "
"machine if you proceed.", "OK", "Cancel", 0,
B_WIDTH_AS_USUAL, B_STOP_ALERT))->Go() != 0)) {
SetStatusMessage("Installation stopped.");
_SetStatusMessage("Installation stopped.");
goto error;
}
@@ -326,143 +386,54 @@ bigtime_t now;
}
LaunchInitScript(targetDirectory);
_LaunchInitScript(targetDirectory);
// copy source volume
targetDir.Rewind();
srcDir.SetTo(srcDirectory.Path());
now = system_time();
#if 0
err = CopyFolder(srcDir, targetDir);
#else
{
BMessenger messenger(fWindow);
CopyEngine2 engine(messenger, new BMessage(STATUS_MESSAGE));
err = engine.CopyFolder(srcDirectory.Path(), targetDirectory.Path(),
fCancelLock);
if (err != B_OK)
printf("error: %s\n", strerror(err));
}
#endif
printf("copy time: %.3fs\n", (system_time() - now) / 1000000.0);
if (err != B_OK || fControl->CheckUserCanceled())
err = engine.CopyFolder(srcDirectory.Path(), targetDirectory.Path(),
fCancelLock);
if (err != B_OK)
goto error;
// copy selected packages
if (fPackages) {
srcDirectory.Append(PACKAGES_DIRECTORY);
srcDir.SetTo(srcDirectory.Path());
BDirectory packageDir;
int32 count = fPackages->CountItems();
for (int32 i = 0; i < count; i++) {
Package *p = static_cast<Package*>(fPackages->ItemAt(i));
packageDir.SetTo(&srcDir, p->Folder());
err = CopyFolder(packageDir, targetDir);
if (err != B_OK || fControl->CheckUserCanceled())
BPath packageDir(srcDirectory.Path(), p->Folder());
err = engine.CopyFolder(packageDir.Path(), targetDirectory.Path(),
fCancelLock);
if (err != B_OK)
goto error;
}
}
LaunchFinishScript(targetDirectory);
_LaunchFinishScript(targetDirectory);
BMessenger(fWindow).SendMessage(INSTALL_FINISHED);
BMessenger(fWindow).SendMessage(MSG_INSTALL_FINISHED);
return;
error:
if (err == B_CANCELED || fControl->CheckUserCanceled())
SetStatusMessage("Installation canceled.");
ERR("Start failed");
BMessenger(fWindow).SendMessage(RESET_INSTALL);
}
status_t
CopyEngine::CopyFolder(BDirectory &srcDir, BDirectory &targetDir)
{
BEntry entry;
status_t err;
while (srcDir.GetNextEntry(&entry) == B_OK
&& !fControl->CheckUserCanceled()) {
StatStruct statbuf;
entry.GetStat(&statbuf);
Undo undo;
if (S_ISDIR(statbuf.st_mode)) {
char name[B_FILE_NAME_LENGTH];
if (entry.GetName(name) == B_OK
&& (strcmp(name, PACKAGES_DIRECTORY) == 0
|| strcmp(name, VAR_DIRECTORY) == 0)) {
continue;
}
err = FSCopyFolder(&entry, &targetDir, fControl, NULL, false, undo);
} else {
err = FSCopyFile(&entry, &statbuf, &targetDir, fControl, NULL,
false, undo);
}
if (err != B_OK) {
BPath path;
entry.GetPath(&path);
ERR2("error while copying %s", path.Path());
return err;
}
}
return B_OK;
BMessage statusMessage(MSG_RESET);
if (err == B_CANCELED)
_SetStatusMessage("Installation canceled.");
else
statusMessage.AddInt32("error", err);
ERR("_PerformInstall failed");
BMessenger(fWindow).SendMessage(&statusMessage);
}
void
CopyEngine::ScanDisksPartitions(BMenu *srcMenu, BMenu *targetMenu)
WorkerThread::_SetStatusMessage(const char *status)
{
// NOTE: This is actually executed in the window thread.
BDiskDevice device;
BPartition *partition = NULL;
printf("\nScanDisksPartitions source partitions begin\n");
SourceVisitor srcVisitor(srcMenu);
fDDRoster.VisitEachMountedPartition(&srcVisitor, &device, &partition);
printf("\nScanDisksPartitions target partitions begin\n");
TargetVisitor targetVisitor(targetMenu);
fDDRoster.VisitEachPartition(&targetVisitor, &device, &partition);
BMessage msg(MSG_STATUS_MESSAGE);
msg.AddString("status", status);
BMessenger(fWindow).SendMessage(&msg);
}
void
CopyEngine::SetPackagesList(BList *list)
{
delete fPackages;
fPackages = list;
}
bool
CopyEngine::Cancel()
{
return fControl->Cancel();
}
void
CopyEngine::WriteBootSector(BMenu* targetMenu)
{
// Executed in window thread.
CALLED();
PartitionMenuItem* item = (PartitionMenuItem*)targetMenu->FindMarked();
if (item == NULL) {
ERR("bad menu items\n");
return;
}
BMessage message(kWriteBootSector);
message.AddInt32("id", item->ID());
PostMessage(&message, this);
}
// #pragma mark -
// #pragma mark - SourceVisitor
SourceVisitor::SourceVisitor(BMenu *menu)
@@ -516,7 +487,7 @@ SourceVisitor::Visit(BPartition *partition, int32 level)
}
// #pragma mark -
// #pragma mark - TargetVisitor
TargetVisitor::TargetVisitor(BMenu *menu)
@@ -582,10 +553,15 @@ TargetVisitor::_MakeLabel(BPartition *partition, char *label, char *menuLabel)
BPath path;
partition->GetPath(&path);
sprintf(label, "%s - %s [%s] [%s]", partition->ContentName(),
size, partition->ContentType(), path.Path());
sprintf(menuLabel, "%s - %s [%s]", partition->ContentName(), size,
partition->ContentType());
// TODO: Reenable the printing of the content type once Haiku supports
// installing to other file systems than BFS.
// sprintf(label, "%s - %s [%s] [%s]", partition->ContentName(),
// size, partition->ContentType(), path.Path());
// sprintf(menuLabel, "%s - %s [%s]", partition->ContentName(), size,
// partition->ContentType());
sprintf(label, "%s - %s - %s", partition->ContentName(), size,
path.Path());
sprintf(menuLabel, "%s - %s", partition->ContentName(), size);
}
+56
View File
@@ -0,0 +1,56 @@
/*
* Copyright 2009, Stephan Aßmus <superstippi@gmx.de>.
* Copyright 2005, Jérôme DUVAL.
* All rights reserved. Distributed under the terms of the MIT License.
*/
#ifndef WORKER_THREAD_H
#define WORKER_THREAD_H
#include <DiskDevice.h>
#include <DiskDeviceRoster.h>
#include <Looper.h>
#include <Messenger.h>
#include <Partition.h>
#include <Volume.h>
class BList;
class BLocker;
class BMenu;
class InstallerWindow;
class WorkerThread : public BLooper {
public:
WorkerThread(InstallerWindow* window);
virtual void MessageReceived(BMessage* message);
void ScanDisksPartitions(BMenu* srcMenu,
BMenu* dstMenu);
void SetPackagesList(BList* list);
void SetSpaceRequired(off_t bytes)
{ fSpaceRequired = bytes; };
bool Cancel();
void SetLock(BLocker* lock)
{ fCancelLock = lock; }
void StartInstall();
void WriteBootSector(BMenu* dstMenu);
private:
void _LaunchInitScript(BPath& path);
void _LaunchFinishScript(BPath& path);
void _PerformInstall(BMenu* srcMenu, BMenu* dstMenu);
void _SetStatusMessage(const char* status);
InstallerWindow* fWindow;
BDiskDeviceRoster fDDRoster;
BList* fPackages;
off_t fSpaceRequired;
BLocker* fCancelLock;
};
#endif // WORKER_THREAD_H