[darwinbuild-changes] [479] branches/PR-6688645/darwinup

source_changes at macosforge.org source_changes at macosforge.org
Tue Mar 17 19:24:22 PDT 2009


Revision: 479
          http://trac.macosforge.org/projects/darwinbuild/changeset/479
Author:   wsiegrist at apple.com
Date:     2009-03-17 19:24:14 -0700 (Tue, 17 Mar 2009)
Log Message:
-----------
Partial work towards adding a -p option to install roots onto arbitrary paths/partitions. We have to add the destination path to the Depot object in order to keep passing it to our File objects since they assume the path in the Archive is relative to the root partition. I also improved the usage statement and found 1 missing free() after an asprintf().

Modified Paths:
--------------
    branches/PR-6688645/darwinup/Archive.cpp
    branches/PR-6688645/darwinup/Depot.cpp
    branches/PR-6688645/darwinup/Depot.h
    branches/PR-6688645/darwinup/File.cpp
    branches/PR-6688645/darwinup/File.h
    branches/PR-6688645/darwinup/main.cpp

Modified: branches/PR-6688645/darwinup/Archive.cpp
===================================================================
--- branches/PR-6688645/darwinup/Archive.cpp	2009-03-17 19:50:36 UTC (rev 478)
+++ branches/PR-6688645/darwinup/Archive.cpp	2009-03-18 02:24:14 UTC (rev 479)
@@ -80,6 +80,7 @@
 char* Archive::create_directory(const char* prefix) {
 	int res = 0;
 	char* path = this->directory_name(prefix);
+	IF_DEBUG("creating directory: %s\n", path);
 	if (path && res == 0) res = mkdir(path, 0777);
 	if (res != 0) {
 		fprintf(stderr, "%s:%d: could not create directory: %s: %s (%d)\n", __FILE__, __LINE__, path, strerror(errno), errno);
@@ -96,6 +97,7 @@
 	char uuidstr[37];
 	uuid_unparse_upper(m_uuid, uuidstr);
 	asprintf(&tarpath, "%s/%s.tar.bz2", prefix, uuidstr);
+	IF_DEBUG("compacting %s/%s to %s\n", prefix, uuidstr, tarpath);
 	if (tarpath) {
 		const char* args[] = {
 			"/usr/bin/tar",
@@ -119,6 +121,7 @@
 	char uuidstr[37];
 	uuid_unparse_upper(m_uuid, uuidstr);
 	asprintf(&tarpath, "%s/%s.tar.bz2", prefix, uuidstr);
+	IF_DEBUG("expanding %s to %s\n", tarpath, prefix);
 	if (tarpath) {
 		const char* args[] = {
 			"/usr/bin/tar",
@@ -223,4 +226,4 @@
 		fprintf(stderr, "Error: unknown archive type: %s\n", path);
 	}
 	return archive;
-}
\ No newline at end of file
+}

Modified: branches/PR-6688645/darwinup/Depot.cpp
===================================================================
--- branches/PR-6688645/darwinup/Depot.cpp	2009-03-17 19:50:36 UTC (rev 478)
+++ branches/PR-6688645/darwinup/Depot.cpp	2009-03-18 02:24:14 UTC (rev 479)
@@ -42,6 +42,7 @@
 #include <sqlite3.h>
 
 Depot::Depot() {
+        m_prefix = NULL;
 	m_depot_path = NULL;
 	m_database_path = NULL;
 	m_archives_path = NULL;
@@ -52,7 +53,8 @@
 Depot::Depot(const char* prefix) {
 	m_lock_fd = -1;
 
-	asprintf(&m_depot_path,    "%s/.DarwinDepot",  prefix);
+	asprintf(&m_prefix,        "%s",               prefix);
+	asprintf(&m_depot_path,    "%s/.DarwinDepot",  m_prefix);
 	asprintf(&m_database_path, "%s/Database-V100", m_depot_path);
 	asprintf(&m_archives_path, "%s/Archives",      m_depot_path);
 
@@ -81,12 +83,14 @@
 Depot::~Depot() {
 	if (m_lock_fd != -1)	this->unlock();
 	if (m_db)		sqlite3_close(m_db);
+        if (m_prefix)           free(m_prefix);
 	if (m_depot_path)	free(m_depot_path);
 	if (m_database_path)	free(m_database_path);
 	if (m_archives_path)	free(m_archives_path);
 }
 
 const char*	Depot::archives_path()		{ return m_archives_path; }
+const char*     Depot::prefix()                 { return m_prefix; }
 
 // Unserialize an archive from the database.
 // Find the archive by UUID.
@@ -266,6 +270,8 @@
 
 	const char* path_argv[] = { path, NULL };
 	
+	IF_DEBUG("[analyze] analyzing path: %s\n", path);
+
 	FTS* fts = fts_open((char**)path_argv, FTS_PHYSICAL | FTS_COMFOLLOW | FTS_XDEV, fts_compare);
 	FTSENT* ent = fts_read(fts); // throw away the entry for path itself
 	while (res != -1 && (ent = fts_read(fts)) != NULL) {
@@ -279,7 +285,10 @@
 			// the file we last installed in this location (preceding),
 			// and the file that actually exists in this location (actual).
 		
-			File* actual = FileFactory(file->path());
+			char* actpath;
+			asprintf(&actpath, "%s/%s", this->prefix(), file->path());
+			File* actual = FileFactory(actpath);
+
 			File* preceding = this->file_preceded_by(file);
 			
 			if (actual == NULL) {
@@ -363,6 +372,7 @@
 				} else {
 					res = 0;
 				}
+				free(backup_dirpath);
 			}
 			
 			
@@ -379,6 +389,7 @@
 			assert(res == 0);
 			if (preceding && preceding != actual) delete preceding;
 			if (actual) delete actual;
+			free(actpath);
 			delete file;
 		}
 	}
@@ -467,9 +478,9 @@
 	if (INFO_TEST(file->info(), FILE_INFO_INSTALL_DATA)) {
 		++context->files_modified;
 
-		res = file->install(context->depot->m_archives_path);
+		res = file->install(context->depot->m_archives_path, context->depot->m_prefix);
 	} else {
-		res = file->install_info();
+		res = file->install_info(context->depot->m_prefix);
 	}
 	if (res != 0) fprintf(stderr, "%s:%d: install failed: %s: %s (%d)\n", __FILE__, __LINE__, file->path(), strerror(errno), errno);
 	return res;
@@ -626,7 +637,9 @@
 		return 0;
 	}
 	
-	File* actual = FileFactory(file->path());
+	char* actpath;
+	asprintf(&actpath, "%s/%s", context->depot->m_prefix, file->path());
+	File* actual = FileFactory(actpath);
 	uint32_t flags = File::compare(file, actual);
 		
 	if (actual != NULL && flags != FILE_INFO_IDENTICAL) {
@@ -641,7 +654,7 @@
 			if (INFO_TEST(preceding->info(), FILE_INFO_NO_ENTRY)) {
 				state = 'R';
 				IF_DEBUG("[uninstall]    removing file\n");
-				if (actual && res == 0) res = actual->remove();
+				if (actual && res == 0) res = actual->remove(context->depot->m_prefix);
 			} else {
 				// copy the preceding file back out to the system
 				// if it's different from what's already there
@@ -649,11 +662,11 @@
 				if (INFO_TEST(flags, FILE_INFO_DATA_DIFFERS)) {
 					state = 'U';
 					IF_DEBUG("[uninstall]    restoring\n");
-					if (res == 0) res = preceding->install(context->depot->m_archives_path);
+					if (res == 0) res = preceding->install(context->depot->m_archives_path, context->depot->m_prefix);
 				} else if (INFO_TEST(flags, FILE_INFO_MODE_DIFFERS) ||
 					   INFO_TEST(flags, FILE_INFO_GID_DIFFERS) ||
 					   INFO_TEST(flags, FILE_INFO_UID_DIFFERS)) {
-					if (res == 0) res = preceding->install_info();
+					if (res == 0) res = preceding->install_info(context->depot->m_prefix);
 				} else {
 					IF_DEBUG("[uninstall]    no changes; leaving in place\n");
 				}
@@ -673,6 +686,8 @@
 	fprintf(stderr, "%c %s\n", state, file->path());
 
 	if (res != 0) fprintf(stderr, "%s:%d: uninstall failed: %s\n", __FILE__, __LINE__, file->path());
+
+	free(actpath);
 	return res;
 }
 

Modified: branches/PR-6688645/darwinup/Depot.h
===================================================================
--- branches/PR-6688645/darwinup/Depot.h	2009-03-17 19:50:36 UTC (rev 478)
+++ branches/PR-6688645/darwinup/Depot.h	2009-03-18 02:24:14 UTC (rev 479)
@@ -37,6 +37,7 @@
 	
 	virtual ~Depot();
 
+        const char*     prefix();
 	const char*	database_path();
 	const char*	archives_path();
 
@@ -110,6 +111,7 @@
 
 	sqlite3*	m_db;
 	mode_t		m_depot_mode;
+        char*           m_prefix;
 	char*		m_depot_path;
 	char*		m_database_path;
 	char*		m_archives_path;

Modified: branches/PR-6688645/darwinup/File.cpp
===================================================================
--- branches/PR-6688645/darwinup/File.cpp	2009-03-17 19:50:36 UTC (rev 478)
+++ branches/PR-6688645/darwinup/File.cpp	2009-03-18 02:24:14 UTC (rev 479)
@@ -132,20 +132,25 @@
 	free(dig);
 }
 
-int File::install(const char* prefix) {
+int File::install(const char* prefix, const char* dest) {
 	int res = 0;
 	Archive* archive = this->archive();
 	assert(archive != NULL);
 	char* dirpath = archive->directory_name(prefix);
+	IF_DEBUG("[install] dirpath is %s\n", dirpath);
 
 	char srcpath[PATH_MAX];
-	const char* dstpath = this->path();
+	const char* path = this->path();
+	char* dstpath;
+	asprintf(&dstpath, "%s/%s", dest, path);
+
 	if (dirpath) {
-		ssize_t len = snprintf(srcpath, sizeof(srcpath), "%s/%s", dirpath, dstpath);
+	        ssize_t len = snprintf(srcpath, sizeof(srcpath), "%s/%s", dirpath, path);
 		if ((size_t)len > sizeof(srcpath)) {
-			fprintf(stderr, "ERROR: [install] path too long: %s/%s\n", dirpath, dstpath);
+			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);
 		res = rename(srcpath, dstpath);
 		if (res == -1) {
 			if (errno == ENOENT) {
@@ -153,7 +158,7 @@
 				// expansion of the archive that contains it.
 				if (is_directory(dirpath) == 0) {
 					res = archive->expand_directory(prefix);
-					if (res == 0) res = this->install(prefix);
+					if (res == 0) res = this->install(prefix, dest);
 				} else {
 					// archive was already expanded, so
 					// the file is truly missing (worry).
@@ -176,18 +181,20 @@
 	} else {
 		res = -1;
 	}
+	free(dstpath);
 	return res;
 }
 
-int File::remove() {
+int File::remove(const char* dest) {
 	// not implemented
 	fprintf(stderr, "%s:%d: call to abstract function File::remove\n", __FILE__, __LINE__);
 	return -1;
 }
 
-int File::install_info() {
+int File::install_info(const char* dest) {
 	int res = 0;
-	const char* path = this->path();
+	char* path;
+	asprintf(&path, "%s/%s", dest, this->path());
 	uid_t uid = this->uid();
 	gid_t gid = this->gid();
 	mode_t mode = this->mode() & ALLPERMS;
@@ -197,6 +204,7 @@
 	IF_DEBUG("[install] chmod(%s, %04o)\n", path, mode);
 	if (res == 0) res = chmod(path, mode);
 
+	free(path);
 	return res;
 }
 
@@ -216,9 +224,10 @@
 	}
 }
 
-int Regular::remove() {
+int Regular::remove(const char* dest) {
 	int res = 0;
-	const char* path = this->path();
+	char* path;
+	asprintf(&path, "%s/%s", dest, this->path());
 	res = unlink(path);
 	if (res == -1 && errno == ENOENT) {
 		// We can safely ignore this because we were going to
@@ -227,6 +236,8 @@
 	} else if (res != 0) {
 		fprintf(stderr, "%s:%d: %s: %s (%d)\n", __FILE__, __LINE__, m_path, strerror(errno), errno);
 	}
+
+	free(path);
 	return res;
 }
 
@@ -240,9 +251,10 @@
 	}
 }
 
-int Symlink::remove() {
+int Symlink::remove(const char* dest) {
 	int res = 0;
-	const char* path = this->path();
+	char* path;
+	asprintf(&path, "%s/%s", dest, this->path());
 	res = unlink(path);
 	if (res == -1 && errno == ENOENT) {
 		// We can safely ignore this because we were going to
@@ -251,10 +263,12 @@
 	} else if (res == -1) {
 		fprintf(stderr, "%s:%d: %s (%d)\n", __FILE__, __LINE__, strerror(errno), errno);
 	}
+
+	free(path);
 	return res;
 }
 
-int Symlink::install_info() {
+int Symlink::install_info(const char* dest) {
 	int res = 0;
 	const char* path = this->path();
 	//mode_t mode = this->mode() & ALLPERMS;
@@ -271,13 +285,15 @@
 
 Directory::Directory(uint64_t serial, Archive* archive, uint32_t info, const char* path, mode_t mode, uid_t uid, gid_t gid, off_t size, Digest* digest) : File(serial, archive, info, path, mode, uid, gid, size, digest) {};
 
-int Directory::install(const char* prefix) {
+int Directory::install(const char* prefix, const char* dest) {
 	// We create a new directory instead of renaming the
 	// existing one, since that would move the entire
 	// sub-tree, and lead to a lot of ENOENT errors.
 	int res = 0;
 	
-	const char* dstpath = this->path();
+	char* dstpath;
+	asprintf(&dstpath, "%s/%s", dest, this->path());
+	
 	mode_t mode = this->mode() & ALLPERMS;
 	uid_t uid = this->uid();
 	gid_t gid = this->gid();
@@ -287,12 +303,15 @@
 	if (res != 0) fprintf(stderr, "ERROR: %s:%d: %s: %s (%d)\n", __FILE__, __LINE__, dstpath, strerror(errno), errno);
 	if (res == 0) res = chown(dstpath, uid, gid);
 	if (res != 0) fprintf(stderr, "ERROR: %s:%d: %s: %s (%d)\n", __FILE__, __LINE__, dstpath, strerror(errno), errno);
+
+	free(dstpath);
 	return res;
 }
 
-int Directory::remove() {
+int Directory::remove(const char* dest) {
 	int res = 0;
-	const char* path = this->path();
+	char* path;
+	asprintf(&path, "%s/%s", dest, this->path());
 	res = rmdir(path);
 	if (res == -1 && errno == ENOENT) {
 		// We can safely ignore this because we were going to
@@ -303,6 +322,8 @@
 	} else if (res == -1) {
 		fprintf(stderr, "%s:%d: %s (%d)\n", __FILE__, __LINE__, strerror(errno), errno);
 	}
+
+	free(path);
 	return res;
 }
 

Modified: branches/PR-6688645/darwinup/File.h
===================================================================
--- branches/PR-6688645/darwinup/File.h	2009-03-17 19:50:36 UTC (rev 478)
+++ branches/PR-6688645/darwinup/File.h	2009-03-18 02:24:14 UTC (rev 479)
@@ -130,18 +130,17 @@
 	//  Member functions
 	////
 
-	// Installs the file at the given prefix onto the
-	// root volume.  i.e., for regular files:
-	// rename(prefix + this->archive()->uuid() + this->path(), this->path());
-	virtual int install(const char* prefix);
+	// Installs the file from the archive into the prefix
+	// i.e., for regular files:
+	// rename(prefix + this->archive()->uuid() + this->path(), dest + this->path());
+        virtual int install(const char* prefix, const char* dest);
 	
-	// Sets the mode, uid, and gid of the file on the
-	// root volume.
+	// Sets the mode, uid, and gid of the file in the dest path
 	// XXX: rename as repair()?
-	virtual int install_info();
+	virtual int install_info(const char* dest);
 	
-	// Removes the file from the root volume.
-	virtual int remove();
+	// Removes the file from the dest path
+	virtual int remove(const char* dest);
 
 	// Prints one line to the output stream indicating
 	// the file mode, ownership, digest and name.
@@ -182,7 +181,7 @@
 struct Regular : File {
 	Regular(Archive* archive, FTSENT* ent);
 	Regular(uint64_t serial, Archive* archive, uint32_t info, const char* path, mode_t mode, uid_t uid, gid_t gid, off_t size, Digest* digest);
-	virtual int remove();
+	virtual int remove(const char* dest);
 };
 
 ////
@@ -192,8 +191,8 @@
 struct Symlink : File {
 	Symlink(Archive* archive, FTSENT* ent);
 	Symlink(uint64_t serial, Archive* archive, uint32_t info, const char* path, mode_t mode, uid_t uid, gid_t gid, off_t size, Digest* digest);
-	virtual int install_info();
-	virtual int remove();
+	virtual int install_info(const char* dest);
+	virtual int remove(const char* dest);
 };
 
 ////
@@ -203,6 +202,6 @@
 struct Directory : File {
 	Directory(Archive* archive, FTSENT* ent);
 	Directory(uint64_t serial, Archive* archive, uint32_t info, const char* path, mode_t mode, uid_t uid, gid_t gid, off_t size, Digest* digest);
-	virtual int install(const char* prefix);
-	virtual int remove();
+	virtual int install(const char* prefix, const char* dest);
+	virtual int remove(const char* dest);
 };

Modified: branches/PR-6688645/darwinup/main.cpp
===================================================================
--- branches/PR-6688645/darwinup/main.cpp	2009-03-17 19:50:36 UTC (rev 478)
+++ branches/PR-6688645/darwinup/main.cpp	2009-03-18 02:24:14 UTC (rev 479)
@@ -30,17 +30,21 @@
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
+#include <limits.h>
 
 void usage(char* progname) {
-	char* pad = strdup(progname);
-	size_t i;
-	for (i = 0; i < strlen(pad); ++i) pad[i] = ' ';
-	
-	fprintf(stderr, "usage: %s install   <path>\n", progname);
-	fprintf(stderr, "       %s list\n", pad);
-	fprintf(stderr, "       %s files     <uuid>\n", pad);
-	fprintf(stderr, "       %s uninstall <uuid>\n", pad);
-	fprintf(stderr, "       %s verify    <uuid>\n", pad);
+	fprintf(stderr, "usage:    %s [-v] [-p PATH] [command] [args]       \n", progname);
+	fprintf(stderr, "                                                             \n");
+	fprintf(stderr, "options:                                                     \n");
+	fprintf(stderr, "          -p PATH    install roots to partition (default: /) \n");
+	fprintf(stderr, "          -v         verbose (use -vv for extra verbosity)   \n");
+	fprintf(stderr, "                                                             \n");
+	fprintf(stderr, "commands:                                                    \n");
+	fprintf(stderr, "          install    <path>                                  \n");
+	fprintf(stderr, "          list                                               \n");
+	fprintf(stderr, "          files      <uuid>                                  \n");
+	fprintf(stderr, "          uninstall  <uuid>                                  \n");
+	fprintf(stderr, "          verify     <uuid>                                  \n");
 	exit(1);
 }
 
@@ -48,18 +52,23 @@
 uint32_t verbosity;
 
 int main(int argc, char* argv[]) {
-	int res = 0;
-	Depot* depot = new Depot("/");
-	
 	char* progname = strdup(basename(argv[0]));
 	
+	// the partition we are working on
+	char partition[PATH_MAX] = "/";
+
 	int ch;
-	while ((ch = getopt(argc, argv, "v")) != -1) {
+	while ((ch = getopt(argc, argv, "p:v")) != -1) {
 		switch (ch) {
 		case 'v':
 			verbosity <<= 1;
 			verbosity |= VERBOSE;
 			break;
+		case 'p':
+			int optlen = strlen(optarg);
+			int limitlen = (optlen < PATH_MAX ? optlen : PATH_MAX);
+			strncpy(partition, optarg, limitlen);
+			break;
 		case '?':
 		default:
 			usage(progname);
@@ -68,6 +77,9 @@
 	argc -= optind;
 	argv += optind;
 
+	int res = 0;
+	Depot* depot = new Depot(partition);
+
 	if (argc == 2 && strcmp(argv[0], "install") == 0) {
 		char uuid[37];
 		Archive* archive = ArchiveFactory(argv[1]);
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/darwinbuild-changes/attachments/20090317/24c4d245/attachment-0001.html>


More information about the darwinbuild-changes mailing list