[darwinbuild-changes] [491] trunk
source_changes at macosforge.org
source_changes at macosforge.org
Fri Mar 20 15:19:50 PDT 2009
Revision: 491
http://trac.macosforge.org/projects/darwinbuild/changeset/491
Author: wsiegrist at apple.com
Date: 2009-03-20 15:19:50 -0700 (Fri, 20 Mar 2009)
Log Message:
-----------
Merging PR-6688645
Modified Paths:
--------------
trunk/darwinup/Archive.cpp
trunk/darwinup/Depot.cpp
trunk/darwinup/Depot.h
trunk/darwinup/File.cpp
trunk/darwinup/File.h
trunk/darwinup/Utils.cpp
trunk/darwinup/Utils.h
trunk/darwinup/main.cpp
Property Changed:
----------------
trunk/
trunk/darwinbuild/darwinbuild.in
trunk/darwinbuild/darwinmaster.sh.in
trunk/darwinbuild/installXcode.in
trunk/darwinbuild/packageRoots.sh.in
trunk/darwinbuild/thinPackages.sh.in
Property changes on: trunk
___________________________________________________________________
Modified: svn:mergeinfo
- /branches/PR-4841388:399-419
/branches/PR-6358021:442-443
/branches/PR-6392966:423-427
/branches/PR-6398060:433-434
/branches/PR-6493844:460-461
/branches/PR-6497694:466-468,471
/trunk:432-434
+ /branches/PR-4841388:399-419
/branches/PR-6358021:442-443
/branches/PR-6392966:423-427
/branches/PR-6398060:433-434
/branches/PR-6493844:460-461
/branches/PR-6497694:466-468,471
/branches/PR-6688645:479-490
/trunk:432-434
Property changes on: trunk/darwinbuild/darwinbuild.in
___________________________________________________________________
Modified: svn:mergeinfo
- /branches/PR-4841388/darwinbuild/darwinbuild:399-419
/branches/PR-6358021/darwinbuild/darwinbuild:442-443
/branches/PR-6392966/darwinbuild/darwinbuild:423-427
/branches/PR-6398060/darwinbuild/darwinbuild:433-434
/branches/PR-6493844/darwinbuild/darwinbuild.in:460-461
/branches/PR-6497694/darwinbuild/darwinbuild.in:466-468,471
/trunk/darwinbuild/darwinbuild:432-434
+ /branches/PR-4841388/darwinbuild/darwinbuild:399-419
/branches/PR-6358021/darwinbuild/darwinbuild:442-443
/branches/PR-6392966/darwinbuild/darwinbuild:423-427
/branches/PR-6398060/darwinbuild/darwinbuild:433-434
/branches/PR-6493844/darwinbuild/darwinbuild.in:460-461
/branches/PR-6497694/darwinbuild/darwinbuild.in:466-468,471
/branches/PR-6688645/darwinbuild/darwinbuild.in:479-490
/trunk/darwinbuild/darwinbuild:432-434
Property changes on: trunk/darwinbuild/darwinmaster.sh.in
___________________________________________________________________
Modified: svn:mergeinfo
- /branches/PR-4841388/darwinbuild/darwinmaster.sh:399-419
/branches/PR-6358021/darwinbuild/darwinmaster.sh:442-443
/branches/PR-6392966/darwinbuild/darwinmaster.sh:423-427
/branches/PR-6398060/darwinbuild/darwinmaster.sh:433-434
/branches/PR-6493844/darwinbuild/darwinmaster.sh.in:460-461
/branches/PR-6497694/darwinbuild/darwinmaster.sh.in:466-468,471
/trunk/darwinbuild/darwinmaster.sh:432-434
+ /branches/PR-4841388/darwinbuild/darwinmaster.sh:399-419
/branches/PR-6358021/darwinbuild/darwinmaster.sh:442-443
/branches/PR-6392966/darwinbuild/darwinmaster.sh:423-427
/branches/PR-6398060/darwinbuild/darwinmaster.sh:433-434
/branches/PR-6493844/darwinbuild/darwinmaster.sh.in:460-461
/branches/PR-6497694/darwinbuild/darwinmaster.sh.in:466-468,471
/branches/PR-6688645/darwinbuild/darwinmaster.sh.in:479-490
/trunk/darwinbuild/darwinmaster.sh:432-434
Property changes on: trunk/darwinbuild/installXcode.in
___________________________________________________________________
Modified: svn:mergeinfo
- /branches/PR-4841388/darwinbuild/installXcode:399-419
/branches/PR-6358021/darwinbuild/installXcode:442-443
/branches/PR-6392966/darwinbuild/installXcode:423-427
/branches/PR-6398060/darwinbuild/installXcode:433-434
/branches/PR-6493844/darwinbuild/installXcode.in:460-461
/branches/PR-6497694/darwinbuild/installXcode.in:466-468,471
/trunk/darwinbuild/installXcode:432-434
+ /branches/PR-4841388/darwinbuild/installXcode:399-419
/branches/PR-6358021/darwinbuild/installXcode:442-443
/branches/PR-6392966/darwinbuild/installXcode:423-427
/branches/PR-6398060/darwinbuild/installXcode:433-434
/branches/PR-6493844/darwinbuild/installXcode.in:460-461
/branches/PR-6497694/darwinbuild/installXcode.in:466-468,471
/branches/PR-6688645/darwinbuild/installXcode.in:479-490
/trunk/darwinbuild/installXcode:432-434
Property changes on: trunk/darwinbuild/packageRoots.sh.in
___________________________________________________________________
Modified: svn:mergeinfo
- /branches/PR-4841388/darwinbuild/packageRoots.sh:399-419
/branches/PR-6358021/darwinbuild/packageRoots.sh:442-443
/branches/PR-6392966/darwinbuild/packageRoots.sh:423-427
/branches/PR-6398060/darwinbuild/packageRoots.sh:433-434
/branches/PR-6493844/darwinbuild/packageRoots.sh.in:460-461
/branches/PR-6497694/darwinbuild/packageRoots.sh.in:466-468,471
/trunk/darwinbuild/packageRoots.sh:432-434
+ /branches/PR-4841388/darwinbuild/packageRoots.sh:399-419
/branches/PR-6358021/darwinbuild/packageRoots.sh:442-443
/branches/PR-6392966/darwinbuild/packageRoots.sh:423-427
/branches/PR-6398060/darwinbuild/packageRoots.sh:433-434
/branches/PR-6493844/darwinbuild/packageRoots.sh.in:460-461
/branches/PR-6497694/darwinbuild/packageRoots.sh.in:466-468,471
/branches/PR-6688645/darwinbuild/packageRoots.sh.in:479-490
/trunk/darwinbuild/packageRoots.sh:432-434
Property changes on: trunk/darwinbuild/thinPackages.sh.in
___________________________________________________________________
Modified: svn:mergeinfo
- /branches/PR-4841388/darwinbuild/thinPackages.sh:399-419
/branches/PR-6358021/darwinbuild/thinPackages.sh:442-443
/branches/PR-6392966/darwinbuild/thinPackages.sh:423-427
/branches/PR-6398060/darwinbuild/thinPackages.sh:433-434
/branches/PR-6493844/darwinbuild/thinPackages.sh.in:460-461
/branches/PR-6497694/darwinbuild/thinPackages.sh.in:466-468,471
/trunk/darwinbuild/thinPackages.sh:432-434
+ /branches/PR-4841388/darwinbuild/thinPackages.sh:399-419
/branches/PR-6358021/darwinbuild/thinPackages.sh:442-443
/branches/PR-6392966/darwinbuild/thinPackages.sh:423-427
/branches/PR-6398060/darwinbuild/thinPackages.sh:433-434
/branches/PR-6493844/darwinbuild/thinPackages.sh.in:460-461
/branches/PR-6497694/darwinbuild/thinPackages.sh.in:466-468,471
/branches/PR-6688645/darwinbuild/thinPackages.sh.in:479-490
/trunk/darwinbuild/thinPackages.sh:432-434
Modified: trunk/darwinup/Archive.cpp
===================================================================
--- trunk/darwinup/Archive.cpp 2009-03-20 21:17:31 UTC (rev 490)
+++ trunk/darwinup/Archive.cpp 2009-03-20 22:19:50 UTC (rev 491)
@@ -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: trunk/darwinup/Depot.cpp
===================================================================
--- trunk/darwinup/Depot.cpp 2009-03-20 21:17:31 UTC (rev 490)
+++ trunk/darwinup/Depot.cpp 2009-03-20 22:19:50 UTC (rev 491)
@@ -42,28 +42,36 @@
#include <sqlite3.h>
Depot::Depot() {
+ m_prefix = NULL;
m_depot_path = NULL;
m_database_path = NULL;
m_archives_path = NULL;
m_db = NULL;
m_lock_fd = -1;
+ m_is_locked = 0;
}
Depot::Depot(const char* prefix) {
m_lock_fd = -1;
+ m_is_locked = 0;
+ asprintf(&m_prefix, "%s", prefix);
+ join_path(&m_depot_path, m_prefix, "/.DarwinDepot");
+ join_path(&m_database_path, m_depot_path, "/Database-V100");
+ join_path(&m_archives_path, m_depot_path, "/Archives");
- asprintf(&m_depot_path, "%s/.DarwinDepot", prefix);
- asprintf(&m_database_path, "%s/Database-V100", m_depot_path);
- asprintf(&m_archives_path, "%s/Archives", m_depot_path);
-
mkdir(m_depot_path, m_depot_mode);
mkdir(m_archives_path, m_depot_mode);
- (void)this->lock(LOCK_SH);
+ int res = 0;
+ res = this->lock(LOCK_SH);
+ if (res == 0) {
+ m_is_locked = 1;
+ }
+
int exists = is_regular_file(m_database_path);
- int res = sqlite3_open(m_database_path, &m_db);
+ res = sqlite3_open(m_database_path, &m_db);
if (res != 0) {
sqlite3_close(m_db);
m_db = NULL;
@@ -81,12 +89,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 +276,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 +291,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;
+ join_path(&actpath, this->prefix(), file->path());
+ File* actual = FileFactory(actpath);
+
File* preceding = this->file_preceded_by(file);
if (actual == NULL) {
@@ -345,16 +360,28 @@
char path[PATH_MAX];
char* backup_dirpath;
- size_t len = strlcpy(path, actual->path(), sizeof(path));
+ // we need the path minus our destination path for moving to the archive
+ char *relpath = strstr(actual->path(), m_prefix);
+ if (relpath) {
+ // advance to just past the destination path
+ relpath += strlen(m_prefix);
+ }
+
+ size_t len = strlcpy(path, (relpath ? relpath : actual->path()),
+ sizeof(path));
assert(len <= sizeof(path));
+
const char* dir = dirname(path);
assert(dir != NULL);
+ char *uuidpath;
char uuidstr[37];
uuid_unparse_upper(rollback->uuid(), uuidstr);
- asprintf(&backup_dirpath, "%s/%s/%s", m_archives_path, uuidstr, dir);
+ asprintf(&uuidpath, "%s/%s", m_archives_path, uuidstr);
+ assert(uuidpath != NULL);
+ join_path(&backup_dirpath, uuidpath, dir);
assert(backup_dirpath != NULL);
res = mkdir_p(backup_dirpath);
@@ -363,6 +390,8 @@
} else {
res = 0;
}
+ free(backup_dirpath);
+ free(uuidpath);
}
@@ -379,6 +408,7 @@
assert(res == 0);
if (preceding && preceding != actual) delete preceding;
if (actual) delete actual;
+ free(actpath);
delete file;
}
}
@@ -415,10 +445,18 @@
int res = 0;
if (INFO_TEST(file->info(), FILE_INFO_ROLLBACK_DATA)) {
- char* dstpath;
+ char *dstpath, *relpath, *uuidpath;
char uuidstr[37];
- uuid_unparse_upper(context->archive->uuid(), uuidstr);
- asprintf(&dstpath, "%s/%s/%s", context->depot->m_archives_path, uuidstr, file->path());
+ // we need the path minus our destination path for moving to the archive
+ relpath = strstr(file->path(), context->depot->m_prefix);
+ if (relpath) {
+ // advance to just past the destination path
+ relpath += strlen(context->depot->m_prefix);
+ }
+ uuid_unparse_upper(context->archive->uuid(), uuidstr);
+ asprintf(&uuidpath, "%s/%s", context->depot->m_archives_path, uuidstr);
+ assert(uuidpath != NULL);
+ join_path(&dstpath, uuidpath, (relpath ? relpath : file->path()));
assert(dstpath != NULL);
++context->files_modified;
@@ -440,21 +478,22 @@
"/usr/lib/libgcc_s"};
size_t numfiles = sizeof(tarfiles)/sizeof(*tarfiles);
for (i = 0; i < numfiles; i++) {
- if (strncmp(tarfiles[i], file->path(), strlen(tarfiles[i])) == 0) {
- docopy = true;
- break;
- }
+ if (strncmp(tarfiles[i], file->path(), strlen(tarfiles[i])) == 0) {
+ docopy = true;
+ break;
+ }
}
if (docopy) {
- IF_DEBUG("[backup] copyfile(%s, %s)\n", file->path(), dstpath);
- res = copyfile(file->path(), dstpath, NULL, COPYFILE_ALL);
+ IF_DEBUG("[backup] copyfile(%s, %s)\n", file->path(), dstpath);
+ res = copyfile(file->path(), dstpath, NULL, COPYFILE_ALL);
} else {
- IF_DEBUG("[backup] rename(%s, %s)\n", file->path(), dstpath);
- res = rename(file->path(), dstpath);
+ IF_DEBUG("[backup] rename(%s, %s)\n", file->path(), dstpath);
+ res = rename(file->path(), dstpath);
}
if (res != 0) fprintf(stderr, "%s:%d: backup failed: %s: %s (%d)\n", __FILE__, __LINE__, dstpath, strerror(errno), errno);
free(dstpath);
+ free(uuidpath);
}
return res;
}
@@ -467,9 +506,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;
@@ -485,8 +524,8 @@
// Check the consistency of the database before proceeding with the installation
// If this fails, abort the installation.
-// res = this->check_consistency();
-// if (res != 0) return res;
+ // res = this->check_consistency();
+ // if (res != 0) return res;
res = this->lock(LOCK_EX);
if (res != 0) return res;
@@ -626,7 +665,10 @@
return 0;
}
- File* actual = FileFactory(file->path());
+ char* actpath;
+ join_path(&actpath, context->depot->m_prefix, file->path());
+ IF_DEBUG("[uninstall] actual path is %s\n", actpath);
+ File* actual = FileFactory(actpath);
uint32_t flags = File::compare(file, actual);
if (actual != NULL && flags != FILE_INFO_IDENTICAL) {
@@ -649,11 +691,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 +715,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;
}
@@ -963,6 +1007,8 @@
return this->SQL("COMMIT TRANSACTION");
}
+int Depot::is_locked() { return m_is_locked; }
+
int Depot::lock(int operation) {
int res = 0;
if (m_lock_fd == -1) {
Modified: trunk/darwinup/Depot.h
===================================================================
--- trunk/darwinup/Depot.h 2009-03-20 21:17:31 UTC (rev 490)
+++ trunk/darwinup/Depot.h 2009-03-20 22:19:50 UTC (rev 491)
@@ -37,6 +37,7 @@
virtual ~Depot();
+ const char* prefix();
const char* database_path();
const char* archives_path();
@@ -70,6 +71,9 @@
int iterate_files(Archive* archive, FileIteratorFunc func, void* context);
int iterate_archives(ArchiveIteratorFunc func, void* context);
+ // test if the depot is currently locked
+ int is_locked();
+
protected:
// Serialize access to the Depot via flock(2).
@@ -110,8 +114,10 @@
sqlite3* m_db;
mode_t m_depot_mode;
+ char* m_prefix;
char* m_depot_path;
char* m_database_path;
char* m_archives_path;
int m_lock_fd;
+ int m_is_locked;
};
Modified: trunk/darwinup/File.cpp
===================================================================
--- trunk/darwinup/File.cpp 2009-03-20 21:17:31 UTC (rev 490)
+++ trunk/darwinup/File.cpp 2009-03-20 22:19:50 UTC (rev 491)
@@ -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;
+ join_path(&dstpath, 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,6 +181,7 @@
} else {
res = -1;
}
+ free(dstpath);
return res;
}
@@ -185,9 +191,10 @@
return -1;
}
-int File::install_info() {
+int File::install_info(const char* dest) {
int res = 0;
- const char* path = this->path();
+ char* path;
+ join_path(&path, 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;
}
@@ -220,6 +228,7 @@
int res = 0;
const char* path = this->path();
res = unlink(path);
+ IF_DEBUG("[remove] unlink %s\n", path);
if (res == -1 && errno == ENOENT) {
// We can safely ignore this because we were going to
// remove the file anyway
@@ -244,6 +253,7 @@
int res = 0;
const char* path = this->path();
res = unlink(path);
+ IF_DEBUG("[remove] unlink %s", path);
if (res == -1 && errno == ENOENT) {
// We can safely ignore this because we were going to
// remove the file anyway
@@ -254,7 +264,7 @@
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 +281,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;
+ join_path(&dstpath, dest, this->path());
+
mode_t mode = this->mode() & ALLPERMS;
uid_t uid = this->uid();
gid_t gid = this->gid();
@@ -287,6 +299,8 @@
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;
}
@@ -294,12 +308,13 @@
int res = 0;
const char* path = this->path();
res = rmdir(path);
+ IF_DEBUG("[remove] rmdir %s\n", path);
if (res == -1 && errno == ENOENT) {
// We can safely ignore this because we were going to
// remove the directory anyway
res = 0;
} else if (res == -1 && errno == ENOTEMPTY) {
- res = remove_directory(path);
+ res = remove_directory(path);
} else if (res == -1) {
fprintf(stderr, "%s:%d: %s (%d)\n", __FILE__, __LINE__, strerror(errno), errno);
}
Modified: trunk/darwinup/File.h
===================================================================
--- trunk/darwinup/File.h 2009-03-20 21:17:31 UTC (rev 490)
+++ trunk/darwinup/File.h 2009-03-20 22:19:50 UTC (rev 491)
@@ -130,17 +130,16 @@
// 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.
+ // Removes the file
virtual int remove();
// Prints one line to the output stream indicating
@@ -192,7 +191,7 @@
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 install_info(const char* dest);
virtual int remove();
};
@@ -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 install(const char* prefix, const char* dest);
virtual int remove();
};
Modified: trunk/darwinup/Utils.cpp
===================================================================
--- trunk/darwinup/Utils.cpp 2009-03-20 21:17:31 UTC (rev 490)
+++ trunk/darwinup/Utils.cpp 2009-03-20 22:19:50 UTC (rev 491)
@@ -141,3 +141,38 @@
}
return res;
}
+
+#define compact_slashes(buf, count) do { memmove(buf - count + 1, buf, strlen(buf) + 1); buf -= count; } while (0)
+
+/**
+ * join_path joins two paths and removes any extra slashes,
+ * even internal ones in p1 or p2. It allocates memory
+ * for the string and the caller is responsible for freeing.
+ */
+int join_path(char **out, const char *p1, const char *p2) {
+ asprintf(out, "%s/%s", p1, p2);
+ if (!out) {
+ fprintf(stderr, "Error: join_path is out of memory!\n");
+ return -1;
+ }
+
+ int slashes = 0;
+ char *cur = *out;
+ while (*cur != '\0') {
+ if (*cur == '/') {
+ slashes++;
+ } else {
+ // we found the next non-slash
+ if (slashes > 1) {
+ compact_slashes(cur, slashes);
+ }
+ slashes = 0;
+ }
+ cur++;
+ }
+ // see if we had extra slashes at the very end of p2
+ if (slashes > 1) {
+ compact_slashes(cur, slashes);
+ }
+ return 0;
+}
Modified: trunk/darwinup/Utils.h
===================================================================
--- trunk/darwinup/Utils.h 2009-03-20 21:17:31 UTC (rev 490)
+++ trunk/darwinup/Utils.h 2009-03-20 22:19:50 UTC (rev 491)
@@ -42,6 +42,9 @@
int has_suffix(const char* str, const char* sfx);
int exec_with_args(const char** args);
+int join_path(char** out, const char* p1, const char* p2);
+int compact_slashes(char* orig, int slashes);
+
inline int INFO_TEST(uint32_t word, uint32_t flag) { return ((word & flag) != 0); }
inline int INFO_SET(uint32_t word, uint32_t flag) { return (word | flag); }
inline int INFO_CLR(uint32_t word, uint32_t flag) { return (word & (~flag)); }
Modified: trunk/darwinup/main.cpp
===================================================================
--- trunk/darwinup/main.cpp 2009-03-20 21:17:31 UTC (rev 490)
+++ trunk/darwinup/main.cpp 2009-03-20 22:19:50 UTC (rev 491)
@@ -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 DIR] [command] [args] \n", progname);
+ fprintf(stderr, " \n");
+ fprintf(stderr, "options: \n");
+ fprintf(stderr, " -p DIR operate on roots under DIR (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,26 @@
uint32_t verbosity;
int main(int argc, char* argv[]) {
- int res = 0;
- Depot* depot = new Depot("/");
-
- char* progname = strdup(basename(argv[0]));
-
+ char* progname = strdup(basename(argv[0]));
+
+ char* path;
+ int custom_path = 0;
+
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':
+ if (strlen(optarg) > (PATH_MAX - 1)) {
+ fprintf(stderr, "Error: -p option value is too long \n");
+ exit(3);
+ }
+ path = optarg;
+ custom_path = 1;
+ break;
case '?':
default:
usage(progname);
@@ -68,6 +80,20 @@
argc -= optind;
argv += optind;
+ int res = 0;
+
+ if (!custom_path) {
+ asprintf(&path, "/");
+ }
+ Depot* depot = new Depot(path);
+ if (!depot->is_locked()) {
+ fprintf(stderr,
+ "Error: unable to access and lock %s. " \
+ "The directory must exist and be writable.\n", depot->prefix());
+ exit(2);
+ }
+
+
if (argc == 2 && strcmp(argv[0], "install") == 0) {
char uuid[37];
Archive* archive = ArchiveFactory(argv[1]);
@@ -125,6 +151,9 @@
} else {
usage(progname);
}
+ if (!custom_path) {
+ free(path);
+ }
exit(res);
return res;
}
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/darwinbuild-changes/attachments/20090320/9294f016/attachment-0001.html>
More information about the darwinbuild-changes
mailing list