[Haiku-commits] r31042 - haiku/trunk/src/apps/installer
stippi at mail.berlios.de
stippi at mail.berlios.de
Sun Jun 14 13:07:56 CEST 2009
Author: stippi
Date: 2009-06-14 13:07:52 +0200 (Sun, 14 Jun 2009)
New Revision: 31042
ViewCVS: http://svn.berlios.de/viewcvs/haiku?rev=31042&view=rev
Modified:
haiku/trunk/src/apps/installer/CopyEngine.cpp
haiku/trunk/src/apps/installer/CopyEngine.h
haiku/trunk/src/apps/installer/InstallerWindow.cpp
haiku/trunk/src/apps/installer/WorkerThread.cpp
Log:
* Fixed problems when installing onto non-empty target volumes. The
'system' folder will be a clean copy of the source volume. Other
folders will be merged (as before), but in case a folder is in the
way of a link or file from the source volume, it will now be purged.
* Clarified the alert for non-empty target volumes, so it is very clear
what happens. (Maybe there ought to the be option to only copy the system
folder, though.)
* Fixed a problem with copying attributes in certain cases.
* Fixed the main GUI not resetting state properly after encountering an
error during the copy process.
Modified: haiku/trunk/src/apps/installer/CopyEngine.cpp
===================================================================
--- haiku/trunk/src/apps/installer/CopyEngine.cpp 2009-06-14 11:03:39 UTC (rev 31041)
+++ haiku/trunk/src/apps/installer/CopyEngine.cpp 2009-06-14 11:07:52 UTC (rev 31042)
@@ -263,8 +263,11 @@
return ret;
ret = create_directory(_destination, 0777);
- if (ret < B_OK && ret != B_FILE_EXISTS)
+ if (ret < B_OK && ret != B_FILE_EXISTS) {
+ fprintf(stderr, "Could not create '%s': %s\n", _destination,
+ strerror(ret));
return ret;
+ }
BDirectory destination(_destination);
ret = destination.InitCheck();
@@ -301,10 +304,24 @@
// handle recursive directory copy
if (copy.Exists()) {
- // Do not overwrite attributes on folders that exist.
- // This should work better when the install target already
- // contains a Haiku installation.
- copyAttributes = false;
+ ret = B_OK;
+ if (copy.IsDirectory()) {
+ if (_ShouldClobberFolder(name, statInfo, level))
+ ret = _RemoveFolder(copy);
+ else {
+ // Do not overwrite attributes on folders that exist.
+ // This should work better when the install target
+ // already contains a Haiku installation.
+ copyAttributes = false;
+ }
+ } else
+ ret = copy.Remove();
+
+ if (ret != B_OK) {
+ fprintf(stderr, "Failed to make room for folder '%s': "
+ "%s\n", name, strerror(ret));
+ return ret;
+ }
}
BPath srcFolder;
@@ -329,35 +346,52 @@
// We are supposed to quit
return B_CANCELED;
}
- } else if (S_ISLNK(statInfo.st_mode)) {
- // copy symbolic links
- BSymLink srcLink(&entry);
- if (ret < B_OK)
- return ret;
-
- char linkPath[B_PATH_NAME_LENGTH];
- ssize_t read = srcLink.ReadLink(linkPath, B_PATH_NAME_LENGTH - 1);
- if (read < 0)
- return (status_t)read;
-
- // just in case it already exists...
- copy.Remove();
-
- BSymLink dstLink;
- ret = destination.CreateSymLink(name, linkPath, &dstLink);
- if (ret < B_OK)
- return ret;
} else {
- // copy file data
- // NOTE: Do not pass the locker, we simply keep holding the lock!
- ret = CopyFile(entry, copy);
- if (ret < B_OK)
- return ret;
+ if (copy.Exists()) {
+ if (copy.IsDirectory())
+ ret = _RemoveFolder(copy);
+ else
+ ret = copy.Remove();
+ if (ret != B_OK) {
+ fprintf(stderr, "Failed to make room for entry '%s': "
+ "%s\n", name, strerror(ret));
+ return ret;
+ }
+ }
+ if (S_ISLNK(statInfo.st_mode)) {
+ // copy symbolic links
+ BSymLink srcLink(&entry);
+ if (ret < B_OK)
+ return ret;
+
+ char linkPath[B_PATH_NAME_LENGTH];
+ ssize_t read = srcLink.ReadLink(linkPath, B_PATH_NAME_LENGTH - 1);
+ if (read < 0)
+ return (status_t)read;
+
+ // just in case it already exists...
+ copy.Remove();
+
+ BSymLink dstLink;
+ ret = destination.CreateSymLink(name, linkPath, &dstLink);
+ if (ret < B_OK)
+ return ret;
+ } else {
+ // copy file data
+ // NOTE: Do not pass the locker, we simply keep holding the lock!
+ ret = CopyFile(entry, copy);
+ if (ret < B_OK)
+ return ret;
+ }
}
if (!copyAttributes)
continue;
+ ret = copy.SetTo(&destination, name);
+ if (ret != B_OK)
+ return ret;
+
// copy attributes
BNode sourceNode(&entry);
BNode targetNode(©);
@@ -396,6 +430,30 @@
}
+status_t
+CopyEngine::_RemoveFolder(BEntry& entry)
+{
+ BDirectory directory(&entry);
+ status_t ret = directory.InitCheck();
+ if (ret != B_OK)
+ return ret;
+
+ BEntry subEntry;
+ while (directory.GetNextEntry(&subEntry) == B_OK) {
+ if (subEntry.IsDirectory()) {
+ ret = _RemoveFolder(subEntry);
+ if (ret != B_OK)
+ return ret;
+ } else {
+ ret = subEntry.Remove();
+ if (ret != B_OK)
+ return ret;
+ }
+ }
+ return entry.Remove();
+}
+
+
void
CopyEngine::_UpdateProgress()
{
@@ -430,6 +488,24 @@
}
+bool
+CopyEngine::_ShouldClobberFolder(const char* name, const struct stat& statInfo,
+ int32 level) const
+{
+ if (level == 1 && S_ISDIR(statInfo.st_mode)) {
+ if (strcmp("system", name) == 0) {
+ printf("clobbering '%s'.\n", name);
+ return true;
+ }
+// if (strcmp("develop", name) == 0) {
+// printf("clobbering '%s'.\n", name);
+// return true;
+// }
+ }
+ return false;
+}
+
+
int32
CopyEngine::_WriteThreadEntry(void* cookie)
{
Modified: haiku/trunk/src/apps/installer/CopyEngine.h
===================================================================
--- haiku/trunk/src/apps/installer/CopyEngine.h 2009-06-14 11:03:39 UTC (rev 31041)
+++ haiku/trunk/src/apps/installer/CopyEngine.h 2009-06-14 11:07:52 UTC (rev 31042)
@@ -48,6 +48,12 @@
const struct stat& statInfo,
int32 level) const;
+ bool _ShouldClobberFolder(const char* name,
+ const struct stat& statInfo,
+ int32 level) const;
+
+ status_t _RemoveFolder(BEntry& entry);
+
void _UpdateProgress();
static int32 _WriteThreadEntry(void* cookie);
Modified: haiku/trunk/src/apps/installer/InstallerWindow.cpp
===================================================================
--- haiku/trunk/src/apps/installer/InstallerWindow.cpp 2009-06-14 11:03:39 UTC (rev 31041)
+++ haiku/trunk/src/apps/installer/InstallerWindow.cpp 2009-06-14 11:07:52 UTC (rev 31042)
@@ -373,15 +373,12 @@
(new BAlert("error", errorMessage, "Ok"))->Go();
}
- fInstallStatus = kReadyForInstall;
- fBeginButton->SetEnabled(true);
_DisableInterface(false);
fProgressLayoutItem->SetVisible(false);
fPkgSwitchLayoutItem->SetVisible(true);
_ShowOptionalPackages();
-
- fBeginButton->SetLabel("Begin");
+ _UpdateControls();
break;
}
case START_SCAN:
Modified: haiku/trunk/src/apps/installer/WorkerThread.cpp
===================================================================
--- haiku/trunk/src/apps/installer/WorkerThread.cpp 2009-06-14 11:03:39 UTC (rev 31041)
+++ haiku/trunk/src/apps/installer/WorkerThread.cpp 2009-06-14 11:07:52 UTC (rev 31042)
@@ -234,14 +234,14 @@
void
-WorkerThread::_PerformInstall(BMenu *srcMenu, BMenu *targetMenu)
+WorkerThread::_PerformInstall(BMenu* srcMenu, BMenu* targetMenu)
{
CALLED();
BPath targetDirectory, srcDirectory;
BDirectory targetDir;
BDiskDevice device;
- BPartition *partition;
+ BPartition* partition;
BVolume targetVolume;
status_t err = B_OK;
int32 entries = 0;
@@ -250,8 +250,8 @@
BMessenger messenger(fWindow);
CopyEngine engine(messenger, new BMessage(MSG_STATUS_MESSAGE));
- PartitionMenuItem *targetItem = (PartitionMenuItem *)targetMenu->FindMarked();
- PartitionMenuItem *srcItem = (PartitionMenuItem *)srcMenu->FindMarked();
+ PartitionMenuItem* targetItem = (PartitionMenuItem*)targetMenu->FindMarked();
+ PartitionMenuItem* srcItem = (PartitionMenuItem*)srcMenu->FindMarked();
if (!srcItem || !targetItem) {
ERR("bad menu items\n");
goto error;
@@ -381,7 +381,12 @@
}
if (entries != 0
&& ((new BAlert("", "The target volume is not empty. Are you sure you "
- "want to install anyway?", "Install Anyway", "Cancel", 0,
+ "want to install anyway?\n\nNote: The 'system' folder will be a "
+ "clean copy from the source volume, all other folders will be "
+ "merged, whereas files and links that exist on both the source "
+ "and target volume will be overwritten with the source volume "
+ "version.",
+ "Install Anyway", "Cancel", 0,
B_WIDTH_AS_USUAL, B_STOP_ALERT))->Go() != 0)) {
err = B_CANCELED;
goto error;
More information about the Haiku-commits
mailing list