[darwinbuild-changes] [647] branches/PR-7250612/darwinup

source_changes at macosforge.org source_changes at macosforge.org
Tue Dec 8 13:34:13 PST 2009


Revision: 647
          http://trac.macosforge.org/projects/darwinbuild/changeset/647
Author:   wsiegrist at apple.com
Date:     2009-12-08 13:34:10 -0800 (Tue, 08 Dec 2009)
Log Message:
-----------
Handle cases where we are asked to install a directory in place of a file and vice versa. Adjust debug and error output.

Modified Paths:
--------------
    branches/PR-7250612/darwinup/Depot.cpp
    branches/PR-7250612/darwinup/File.cpp
    branches/PR-7250612/darwinup/main.cpp

Modified: branches/PR-7250612/darwinup/Depot.cpp
===================================================================
--- branches/PR-7250612/darwinup/Depot.cpp	2009-12-07 21:52:12 UTC (rev 646)
+++ branches/PR-7250612/darwinup/Depot.cpp	2009-12-08 21:34:10 UTC (rev 647)
@@ -435,7 +435,7 @@
 	InstallContext* context = (InstallContext*)ctx;
 	int res = 0;
 
-	IF_DEBUG("[DEBUG] backup_file: %s , %s \n", file->path(), context->archive->m_name);
+	IF_DEBUG("[backup] backup_file: %s , %s \n", file->path(), context->archive->m_name);
 
 	if (INFO_TEST(file->info(), FILE_INFO_ROLLBACK_DATA)) {
 	        char *path;        // the file's path
@@ -462,7 +462,10 @@
 		join_path(&dstpath, uuidpath, relpath);
 		assert(dstpath != NULL);
 
-		IF_DEBUG("[DEBUG] \npath = %s \nrelpath = %s \ndstpath = %s \nuuidpath = %s \n[/DEBUG]\n", path, relpath, dstpath, uuidpath); 
+		IF_DEBUG("[backup] path = %s \n", path);
+		IF_DEBUG("[backup] relpath = %s \n", relpath);
+		IF_DEBUG("[backup] dstpath = %s \n", dstpath);
+		IF_DEBUG("[backup] uuidpath = %s \n", uuidpath);
 
 		++context->files_modified;
 

Modified: branches/PR-7250612/darwinup/File.cpp
===================================================================
--- branches/PR-7250612/darwinup/File.cpp	2009-12-07 21:52:12 UTC (rev 646)
+++ branches/PR-7250612/darwinup/File.cpp	2009-12-08 21:34:10 UTC (rev 647)
@@ -32,6 +32,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
+#include <removefile.h>
 
 File::File() {
 	m_serial = 0;
@@ -151,35 +152,54 @@
 			fprintf(stderr, "ERROR: [install] path too long: %s/%s\n", dirpath, path);
 			return -1;
 		}
-		IF_DEBUG("[install] about to rename %s to %s\n", srcpath, dstpath);
+		IF_DEBUG("[install] rename(%s, %s)\n", srcpath, dstpath);
 		res = rename(srcpath, dstpath);
 		if (res == -1) {
 			if (errno == ENOENT) {
 				// the file wasn't found, try to do on-demand
 				// expansion of the archive that contains it.
 				if (is_directory(dirpath) == 0) {
-					IF_DEBUG("[install] File::install on-demand archive expansion");
+					IF_DEBUG("[install] File::install on-demand archive expansion \n");
 					res = archive->expand_directory(prefix);
 					if (res == 0) res = this->install(prefix, dest);
 				} else {
 					// archive was already expanded, so
 					// the file is truly missing (worry).
-					IF_DEBUG("[install] File::install missing file in archive");
+					IF_DEBUG("[install] File::install missing file in archive \n");
 					fprintf(stderr, "%s:%d: %s: %s (%d)\n", __FILE__, __LINE__, srcpath, strerror(errno), errno);
 				}
 			} else if (force && errno == ENOTDIR) {
 				// a) some part of destination path does not exist
 				// b) from is a directory, but to is not
 				IF_DEBUG("[install] File::install ENOTDIR\n");
+				fprintf(stderr, "%s:%d: %s: %s (%d)\n", __FILE__, __LINE__, dstpath, strerror(errno), errno);
 			} else if (force && errno == EISDIR) {
 				// to is a directory, but from is not
-				IF_DEBUG("[install] File::install EISDIR\n");
+				IF_DEBUG("[install] replacing directory with a file\n");
+				IF_DEBUG("[install] removefile(%s)\n", dstpath);
+				removefile_state_t rmstate;
+				rmstate = removefile_state_alloc();
+				res = removefile(dstpath, rmstate, REMOVEFILE_RECURSIVE);
+				removefile_state_free(rmstate);
+				if (res == -1) fprintf(stderr, "%s:%d: %s: %s (%d)\n", __FILE__, __LINE__, dstpath, strerror(errno), errno);
+				IF_DEBUG("[install] rename(%s, %s)\n", srcpath, dstpath);
+				res = rename(srcpath, dstpath);
+				if (res == -1) fprintf(stderr, "%s:%d: %s: %s (%d)\n", __FILE__, __LINE__, dstpath, strerror(errno), errno);
 			} else if (force && errno == ENOTEMPTY) {
 				// to is a directory and is not empty
 				IF_DEBUG("[install] File::install ENOTEMPTY\n");
+				fprintf(stderr, "%s:%d: %s: %s (%d)\n", __FILE__, __LINE__, dstpath, strerror(errno), errno);
 			} else {
 				if (!force) {
-					fprintf(stderr, "ERROR: darwinup cannot handle what you are trying to do. You can use the force option to allow more potentially-unsafe operations.\n");
+					fprintf(stderr,
+							"-------------------------------------------------------------------------------\n"
+							"darwinup has encountered a potentially unsafe mismatch between the root and    \n"
+							"destination. For example, you may be trying to install a file where a directory\n" 
+							"currently exists. darwinup will not install this root by default since it could\n"
+							"cause damage to your system. You can use the force (-f) option to allow        \n"
+							"darwinup to attempt the install anyway.                                        \n"
+							"-------------------------------------------------------------------------------\n"
+							);
 				}
 				fprintf(stderr, "%s:%d: %s: %s (%d)\n", __FILE__, __LINE__, dstpath, strerror(errno), errno);
 				fprintf(stderr, "ERROR: fatal error during File::install. Cannot continue.\n");
@@ -306,11 +326,25 @@
 	
 	IF_DEBUG("[install] mkdir(%s, %04o)\n", dstpath, mode);
 	if (res == 0) res = mkdir(dstpath, mode);
-	if (res && errno == EEXIST) res = 0;
 
-	if (force && res == -1 && errno == ENOTDIR) {
+	if (res && errno == EEXIST) {
+		if (is_directory(dstpath)) {
+			// this is expected in normal cases, so no need to force
+			IF_DEBUG("[install] directory already exists, setting mode \n");
+			res = chmod(dstpath, mode);
+			if (res == -1) fprintf(stderr, "%s:%d: %s: %s (%d)\n", __FILE__, __LINE__, dstpath, strerror(errno), errno);
+		} else if (force) {
+			// this could be bad, so require the force option
+			IF_DEBUG("[install] original node is a file, we need to replace with a directory \n");
+			IF_DEBUG("[install] unlink(%s)\n", dstpath);
+			res = unlink(dstpath);
+			IF_DEBUG("[install] mkdir(%s, %04o)\n", dstpath, mode);
+			res = mkdir(dstpath, mode);
+			if (res == -1) fprintf(stderr, "%s:%d: %s: %s (%d)\n", __FILE__, __LINE__, dstpath, strerror(errno), errno);
+		}
+	} else if (force && res == -1 && errno == ENOTDIR) {
 		// some part of destination path is not a directory
-		IF_DEBUG("[install] Directory::install ENOTDIR1\n");
+		IF_DEBUG("[install] Directory::install ENOTDIR \n");
 	} else if (res == -1) {
 		fprintf(stderr, "ERROR: %s:%d: %s: %s (%d)\n", __FILE__, __LINE__, dstpath, strerror(errno), errno);
 		fprintf(stderr, "ERROR: unable to create %s \n", dstpath);
@@ -408,7 +442,9 @@
 		return NULL;
 	} else if (force && res == -1 && errno == ENOTDIR) {
 		// some part of destination path does not exist
-		IF_DEBUG("[       ] FileFactory ENOTDIR\n");
+		// or is a file. This gets handled by Directory::install 
+		// eventually
+		IF_DEBUG("[factory]    parents do not exist or contain a file\n");
 		return NULL;
 	}	
 	if (res == -1) {

Modified: branches/PR-7250612/darwinup/main.cpp
===================================================================
--- branches/PR-7250612/darwinup/main.cpp	2009-12-07 21:52:12 UTC (rev 646)
+++ branches/PR-7250612/darwinup/main.cpp	2009-12-08 21:34:10 UTC (rev 647)
@@ -62,7 +62,7 @@
 	while ((ch = getopt(argc, argv, "fp:v")) != -1) {
 		switch (ch) {
 		case 'f':
-				fprintf(stderr, "DEBUG: forcing operations\n");
+				IF_DEBUG("forcing operations\n");
 				force = 1;
 				break;
 		case 'p':
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/darwinbuild-changes/attachments/20091208/3df89b92/attachment.html>


More information about the darwinbuild-changes mailing list