[darwinbuild-changes] [881] trunk
source_changes at macosforge.org
source_changes at macosforge.org
Fri Sep 17 17:28:32 PDT 2010
Revision: 881
http://trac.macosforge.org/projects/darwinbuild/changeset/881
Author: wsiegrist at apple.com
Date: 2010-09-17 17:28:31 -0700 (Fri, 17 Sep 2010)
Log Message:
-----------
Merge PR-8416637
Modified Paths:
--------------
trunk/darwinup/Depot.cpp
trunk/darwinup/Depot.h
trunk/darwinup/File.cpp
trunk/darwinup/File.h
trunk/darwinup/Utils.cpp
trunk/darwinup/main.cpp
trunk/testing/darwinup/dest.tar.gz
trunk/testing/darwinup/run-tests.sh
Added Paths:
-----------
trunk/testing/darwinup/rep_dir_file.tar.gz
trunk/testing/darwinup/rep_dir_link.tar.gz
trunk/testing/darwinup/rep_file_dir.tar.gz
trunk/testing/darwinup/rep_file_link.tar.gz
trunk/testing/darwinup/rep_flink_dir.tar.gz
trunk/testing/darwinup/rep_flink_file.tar.gz
trunk/testing/darwinup/rep_link_dir.tar.gz
trunk/testing/darwinup/rep_link_file.tar.gz
Removed Paths:
-------------
trunk/testing/darwinup/root4.tar.gz
Property Changed:
----------------
trunk/
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
/branches/PR-6634286:632-650
/branches/PR-6688645:479-490
/branches/PR-6722857:495-499
/branches/PR-6729491:655-664
/branches/PR-6973110:804-813
/branches/PR-7250612:635-650
/branches/PR-7341154:682-694
/branches/PR-7431723:660-664
/branches/PR-7461534:650-664
/branches/PR-7482850:670-671
/branches/PR-7489777:676-731
/branches/PR-7529688:692-694
/branches/PR-7593824:739-772
/branches/PR-7598640:703-731
/branches/PR-7748469:777-785
/branches/PR-7765119:790-791
/branches/PR-7798586:796-799
/branches/PR-7872907:830-840
/branches/PR-7935095:819-821
/branches/PR-8116613:849
/branches/PR-8279204:854-862
+ /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-6634286:632-650
/branches/PR-6688645:479-490
/branches/PR-6722857:495-499
/branches/PR-6729491:655-664
/branches/PR-6973110:804-813
/branches/PR-7250612:635-650
/branches/PR-7341154:682-694
/branches/PR-7431723:660-664
/branches/PR-7461534:650-664
/branches/PR-7482850:670-671
/branches/PR-7489777:676-731
/branches/PR-7529688:692-694
/branches/PR-7593824:739-772
/branches/PR-7598640:703-731
/branches/PR-7748469:777-785
/branches/PR-7765119:790-791
/branches/PR-7798586:796-799
/branches/PR-7872907:830-840
/branches/PR-7935095:819-821
/branches/PR-8116613:849
/branches/PR-8279204:854-862
/branches/PR-8416637:870-880
Modified: trunk/darwinup/Depot.cpp
===================================================================
--- trunk/darwinup/Depot.cpp 2010-09-16 22:51:34 UTC (rev 880)
+++ trunk/darwinup/Depot.cpp 2010-09-18 00:28:31 UTC (rev 881)
@@ -103,9 +103,9 @@
m_db = new DarwinupDatabase(m_database_path);
if (!m_db || !m_db->is_connected()) {
fprintf(stderr, "Error: unable to connect to database.\n");
- return 1;
+ return DB_ERROR;
}
- return 0;
+ return DB_OK;
}
int Depot::create_storage() {
@@ -138,7 +138,7 @@
perror(m_downloads_path);
return res;
}
- return 0;
+ return DEPOT_OK;
}
// Initialize the depot
@@ -148,7 +148,7 @@
// initialization requires all these paths to be set
if (!(m_prefix && m_depot_path && m_database_path &&
m_archives_path && m_downloads_path)) {
- return -1;
+ return DEPOT_ERROR;
}
if (writable) {
@@ -172,11 +172,11 @@
res = stat(m_database_path, &sb);
if (!writable && res == -1 && (errno == ENOENT || errno == ENOTDIR)) {
// depot does not exist
- return -2;
+ return DEPOT_NOT_EXIST;
}
if (!writable && res == -1 && errno == EACCES) {
// permission denied
- return -3;
+ return DEPOT_PERM_DENIED;
}
// take an exclusive lock
@@ -402,9 +402,9 @@
return res;
}
-
int Depot::analyze_stage(const char* path, Archive* archive, Archive* rollback,
int* rollback_files) {
+ extern uint32_t force;
extern uint32_t dryrun;
int res = 0;
assert(archive != NULL);
@@ -475,9 +475,22 @@
if (INFO_TEST(actual->info(), FILE_INFO_NO_ENTRY)) {
state = 'A';
} else {
+ if (INFO_TEST(actual_flags, FILE_INFO_TYPE_DIFFERS) && !force) {
+ // the existing file on disk is a different type than what
+ // we are trying to install, so require the force option,
+ // otherwise print an error and bail
+ mode_t file_type = file->mode() & S_IFMT;
+ mode_t actual_type = actual->mode() & S_IFMT;
+ fprintf(stderr, FILE_OBJ_CHANGE_ERROR, actual->path(),
+ FILE_TYPE_STRING(file_type),
+ FILE_TYPE_STRING(actual_type));
+ return DEPOT_OBJ_CHANGE;
+ }
state = 'U';
}
+
+
if (INFO_TEST(actual_flags, FILE_INFO_TYPE_DIFFERS) ||
INFO_TEST(actual_flags, FILE_INFO_DATA_DIFFERS)) {
IF_DEBUG("[analyze] needs installation\n");
@@ -674,20 +687,25 @@
uuid_unparse_upper(archive->uuid(), uuid);
fprintf(stdout, "%s\n", uuid);
} else {
- fprintf(stderr, "Error: Install failed. Rolling back installation.\n");
- res = this->uninstall(archive);
- if (res) {
- fprintf(stderr, "Error: Unable to rollback installation. "
- "Your system is in an inconsistent state! File a bug!\n");
- } else {
- fprintf(stdout, "Rollback successful.\n");
+ fprintf(stderr, "Error: Install failed.\n");
+ if (res != DEPOT_OBJ_CHANGE) {
+ // object change errors come from analyze stage,
+ // so there is no installation to roll back
+ fprintf(stderr, "Rolling back installation.\n");
+ res = this->uninstall(archive);
+ if (res) {
+ fprintf(stderr, "Error: Unable to rollback installation. "
+ "Your system is in an inconsistent state! File a bug!\n");
+ } else {
+ fprintf(stdout, "Rollback successful.\n");
+ }
}
- res = 1;
+ res = DEPOT_ERROR;
}
} else {
- fprintf(stdout, "Error: unable to load \"%s\". Either the path is invalid or"
+ fprintf(stdout, "Error: unable to load \"%s\". Either the path is missing, invalid or"
" the file is in an unknown format.\n", path);
- return -1;
+ return DEPOT_ERROR;
}
return res;
@@ -739,8 +757,8 @@
int rollback_files = 0;
if (res == 0) res = this->analyze_stage(archive_path, archive, rollback, &rollback_files);
- // we can stop now if this is a dry run
- if (dryrun) {
+ // we can stop now if analyze failed or this is a dry run
+ if (res || dryrun) {
remove_directory(archive_path);
remove_directory(rollback_path);
free(rollback_path);
@@ -855,7 +873,7 @@
// We never uninstall a file that was part of the base system
if (INFO_TEST(file->info(), FILE_INFO_BASE_SYSTEM)) {
IF_DEBUG("[uninstall] base system; skipping\n");
- return 0;
+ return DEPOT_OK;
}
char* actpath;
@@ -941,10 +959,10 @@
// if in debug mode, get_all_archives returns rollbacks too, so just ignore
if (verbosity & VERBOSE_DEBUG) {
fprintf(stderr, "[uninstall] skipping uninstall since archive is a rollback.\n");
- return 0;
+ return DEPOT_OK;
}
fprintf(stderr, "%s:%d: cannot uninstall a rollback archive.\n", __FILE__, __LINE__);
- return -1;
+ return DEPOT_ERROR;
}
/**
@@ -968,7 +986,7 @@
"happen.\n"
"-------------------------------------------------------------------------------\n",
archive->name(), archive->build(), m_build);
- return 9999;
+ return DEPOT_BUILD_MISMATCH;
}
if (res != 0) return res;
@@ -1027,7 +1045,7 @@
fprintf(stdout, "R ");
}
file->print(stdout);
- return 0;
+ return DEPOT_OK;
}
void Depot::archive_header() {
@@ -1063,7 +1081,7 @@
fprintf((FILE*)context, "%-6llu %-36s %-12s %-7s %s\n",
serial, uuid, date, (archive->build()?archive->build():""), archive->name());
- return 0;
+ return DEPOT_OK;
}
int Depot::list() {
@@ -1110,7 +1128,7 @@
extern uint32_t verbosity;
if (verbosity & VERBOSE_DEBUG) fprintf((FILE*)context, "%04x ", file->info());
file->print((FILE*)context);
- return 0;
+ return DEPOT_OK;
}
int Depot::files(Archive* archive) {
@@ -1322,7 +1340,7 @@
}
free(path);
- return 0;
+ return DEPOT_OK;
}
int Depot::has_file(Archive* archive, File* file) {
@@ -1401,7 +1419,7 @@
for (size_t i = 0; i < count; i++) {
if (!list[i]) {
fprintf(stdout, "Archive not found: %s\n", archspec);
- return -1;
+ return DEPOT_ERROR;
}
if (verbosity & VERBOSE_DEBUG) {
char uuid[37];
@@ -1423,13 +1441,13 @@
(strncasecmp(archspec, "superseded", 10) == 0 && strlen(archspec) == 10)) {
fprintf(stderr, "Error: keywords 'all' and 'superseded' cannot be used with the"
" rename command.\n");
- return -2;
+ return DEPOT_USAGE_ERROR;
}
Archive* archive = this->get_archive(archspec);
if (!archive) {
fprintf(stdout, "Archive not found: %s\n", archspec);
- return -1;
+ return DEPOT_NOT_EXIST;
}
char uuid[37];
@@ -1440,7 +1458,7 @@
if (!name || strlen(name) == 0) {
fprintf(stderr, "Error: invalid name: '%s'\n", name);
- return -3;
+ return DEPOT_ERROR;
}
free(archive->m_name);
Modified: trunk/darwinup/Depot.h
===================================================================
--- trunk/darwinup/Depot.h 2010-09-16 22:51:34 UTC (rev 880)
+++ trunk/darwinup/Depot.h 2010-09-18 00:28:31 UTC (rev 881)
@@ -39,6 +39,15 @@
#include "DB.h"
#include "Archive.h"
+#define DEPOT_OK 0
+#define DEPOT_ERROR -1
+#define DEPOT_NOT_EXIST -2
+#define DEPOT_PERM_DENIED -3
+#define DEPOT_OBJ_CHANGE -4
+#define DEPOT_BUILD_MISMATCH -5
+#define DEPOT_USAGE_ERROR -6
+
+
struct Archive;
struct File;
struct DarwinupDatabase;
Modified: trunk/darwinup/File.cpp
===================================================================
--- trunk/darwinup/File.cpp 2010-09-16 22:51:34 UTC (rev 880)
+++ trunk/darwinup/File.cpp 2010-09-18 00:28:31 UTC (rev 881)
@@ -82,7 +82,8 @@
m_digest = NULL;
}
-File::File(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::File(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) {
m_serial = serial;
m_archive = archive;
m_info = info;
@@ -116,17 +117,21 @@
uint32_t File::compare(File* a, File* b) {
if (a == b) return FILE_INFO_IDENTICAL; // identity
- if (a == NULL) return 0xFFFFFFFF; // existent and nonexistent file are infinitely different
- if (b == NULL) return 0xFFFFFFFF; // existent and nonexistent file are infinitely different
+ // existent and nonexistent file are infinitely different
+ if (a == NULL) return 0xFFFFFFFF;
+ if (b == NULL) return 0xFFFFFFFF;
uint32_t result = FILE_INFO_IDENTICAL;
if (a->m_uid != b->m_uid) result |= FILE_INFO_UID_DIFFERS;
if (a->m_gid != b->m_gid) result |= FILE_INFO_GID_DIFFERS;
if (a->m_mode != b->m_mode) result |= FILE_INFO_MODE_DIFFERS;
- if ((a->m_mode & S_IFMT) != (b->m_mode & S_IFMT)) result |= FILE_INFO_TYPE_DIFFERS;
- if ((a->m_mode & ALLPERMS) != (b->m_mode & ALLPERMS)) result |= FILE_INFO_PERM_DIFFERS;
+ if ((a->m_mode & S_IFMT) != (b->m_mode & S_IFMT))
+ result |= FILE_INFO_TYPE_DIFFERS;
+ if ((a->m_mode & ALLPERMS) != (b->m_mode & ALLPERMS))
+ result |= FILE_INFO_PERM_DIFFERS;
//if (a->m_size != b->m_size) result |= FILE_INFO_SIZE_DIFFERS;
- if (Digest::equal(a->m_digest, b->m_digest) == 0) result |= FILE_INFO_DATA_DIFFERS;
+ if (Digest::equal(a->m_digest, b->m_digest) == 0)
+ result |= FILE_INFO_DATA_DIFFERS;
return result;
}
@@ -158,7 +163,8 @@
if (dirpath) {
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, path);
+ fprintf(stderr, "ERROR: [install] path too long: %s/%s\n",
+ dirpath, path);
return -1;
}
IF_DEBUG("[install] rename(%s, %s)\n", srcpath, dstpath);
@@ -168,20 +174,22 @@
// 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 \n");
+ 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 \n");
- fprintf(stderr, "%s:%d: %s: %s (%d)\n", __FILE__, __LINE__, srcpath, strerror(errno), errno);
+ 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);
+ 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] replacing directory with a file\n");
@@ -190,28 +198,24 @@
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 (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);
+ 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);
+ fprintf(stderr, "%s:%d: %s: %s (%d)\n",
+ __FILE__, __LINE__, dstpath, strerror(errno), errno);
} else {
- if (!force) {
- 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");
+ 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");
}
} else {
IF_DEBUG("[install] rename(%s, %s)\n", srcpath, dstpath);
@@ -226,7 +230,8 @@
int File::remove() {
// not implemented
- fprintf(stderr, "%s:%d: call to abstract function File::remove\n", __FILE__, __LINE__);
+ fprintf(stderr, "%s:%d: call to abstract function File::remove\n",
+ __FILE__, __LINE__);
return -1;
}
@@ -251,13 +256,17 @@
m_info = INFO_SET(m_info, FILE_INFO_NO_ENTRY);
}
-NoEntry::NoEntry(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) {}
+NoEntry::NoEntry(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) {}
Regular::Regular(Archive* archive, FTSENT* ent) : File(archive, ent) {
m_digest = new SHA1DigestMachO(ent->fts_accpath);
}
-Regular::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) : File(serial, archive, info, path, mode, uid, gid, size, digest) {
+Regular::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)
+: File(serial, archive, info, path, mode, uid, gid, size, digest) {
if (digest == NULL || serial == 0) {
m_digest = new SHA1DigestMachO(path);
}
@@ -273,7 +282,8 @@
// remove the file anyway
res = 0;
} else if (res != 0) {
- fprintf(stderr, "%s:%d: %s: %s (%d)\n", __FILE__, __LINE__, m_path, strerror(errno), errno);
+ fprintf(stderr, "%s:%d: %s: %s (%d)\n",
+ __FILE__, __LINE__, m_path, strerror(errno), errno);
}
return res;
}
@@ -282,7 +292,9 @@
m_digest = new SHA1DigestSymlink(ent->fts_accpath);
}
-Symlink::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) : File(serial, archive, info, path, mode, uid, gid, size, digest) {
+Symlink::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)
+: File(serial, archive, info, path, mode, uid, gid, size, digest) {
if (digest == NULL || serial == 0) {
m_digest = new SHA1DigestSymlink(path);
}
@@ -298,7 +310,8 @@
// remove the file anyway
res = 0;
} else if (res == -1) {
- fprintf(stderr, "%s:%d: %s (%d)\n", __FILE__, __LINE__, strerror(errno), errno);
+ fprintf(stderr, "%s:%d: %s (%d)\n",
+ __FILE__, __LINE__, strerror(errno), errno);
}
return res;
}
@@ -312,7 +325,8 @@
gid_t gid = this->gid();
IF_DEBUG("[install] lchown(%d, %d)\n", uid, gid);
if (res == 0) res = lchown(path, uid, gid);
- if (res == -1) fprintf(stderr, "%s:%d: %s: %s (%d)\n", __FILE__, __LINE__, path, strerror(errno), errno);
+ if (res == -1) fprintf(stderr, "%s:%d: %s: %s (%d)\n",
+ __FILE__, __LINE__, path, strerror(errno), errno);
//IF_DEBUG("[install] lchmod(%o)\n", mode);
//if (res == 0) res = lchmod(path, mode);
free(path);
@@ -321,7 +335,10 @@
Directory::Directory(Archive* archive, FTSENT* ent) : File(archive, ent) {}
-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) {};
+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, const char* dest) {
// We create a new directory instead of renaming the
@@ -346,28 +363,35 @@
// 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);
+ 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] 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);
+ 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 ENOTDIR \n");
} else if (res == -1) {
- fprintf(stderr, "ERROR: %s:%d: %s: %s (%d)\n", __FILE__, __LINE__, dstpath, strerror(errno), errno);
+ fprintf(stderr, "ERROR: %s:%d: %s: %s (%d)\n",
+ __FILE__, __LINE__, dstpath, strerror(errno), errno);
fprintf(stderr, "ERROR: unable to create %s \n", dstpath);
}
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);
+ fprintf(stderr, "ERROR: %s:%d: %s: %s (%d)\n",
+ __FILE__, __LINE__, dstpath, strerror(errno), errno);
fprintf(stderr, "ERROR: unable to change ownership of %s \n", dstpath);
}
}
@@ -388,31 +412,38 @@
} else if (res == -1 && errno == ENOTEMPTY) {
res = remove_directory(path);
} else if (res == -1) {
- fprintf(stderr, "%s:%d: %s (%d)\n", __FILE__, __LINE__, strerror(errno), errno);
+ fprintf(stderr, "%s:%d: %s (%d)\n",
+ __FILE__, __LINE__, strerror(errno), errno);
}
return res;
}
-File* FileFactory(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* FileFactory(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* file = NULL;
switch (mode & S_IFMT) {
case S_IFDIR:
- file = new Directory(serial, archive, info, path, mode, uid, gid, size, digest);
+ file = new Directory(serial, archive, info, path, mode, uid, gid, size,
+ digest);
break;
case S_IFREG:
- file = new Regular(serial, archive, info, path, mode, uid, gid, size, digest);
+ file = new Regular(serial, archive, info, path, mode, uid, gid, size,
+ digest);
break;
case S_IFLNK:
- file = new Symlink(serial, archive, info, path, mode, uid, gid, size, digest);
+ file = new Symlink(serial, archive, info, path, mode, uid, gid, size,
+ digest);
break;
case 0:
if (INFO_TEST(info, FILE_INFO_NO_ENTRY)) {
- file = new NoEntry(serial, archive, info, path, mode, uid, gid, size, digest);
+ file = new NoEntry(serial, archive, info, path, mode, uid, gid, size,
+ digest);
break;
}
default:
- fprintf(stderr, "%s:%d: unexpected file type %o\n", __FILE__, __LINE__, mode & S_IFMT);
+ fprintf(stderr, "%s:%d: unexpected file type %o\n",
+ __FILE__, __LINE__, mode & S_IFMT);
break;
}
return file;
@@ -435,10 +466,12 @@
break;
case FTS_DEFAULT:
case FTS_DNR:
- fprintf(stderr, "%s:%d: could not read directory. Run as root.\n", __FILE__, __LINE__);
+ fprintf(stderr, "%s:%d: could not read directory. Run as root.\n",
+ __FILE__, __LINE__);
break;
default:
- fprintf(stderr, "%s:%d: unexpected fts_info type %d\n", __FILE__, __LINE__, ent->fts_info);
+ fprintf(stderr, "%s:%d: unexpected fts_info type %d\n",
+ __FILE__, __LINE__, ent->fts_info);
break;
}
return file;
@@ -462,11 +495,13 @@
return NULL;
}
if (res == -1) {
- fprintf(stderr, "%s:%d: %s: %s (%d)\n", __FILE__, __LINE__, path, strerror(errno), errno);
+ fprintf(stderr, "%s:%d: %s: %s (%d)\n",
+ __FILE__, __LINE__, path, strerror(errno), errno);
fprintf(stderr, "ERROR: unable to stat %s \n", path);
return NULL;
}
- file = FileFactory(0, NULL, FILE_INFO_NONE, path, sb.st_mode, sb.st_uid, sb.st_gid, sb.st_size, NULL);
+ file = FileFactory(0, NULL, FILE_INFO_NONE, path, sb.st_mode, sb.st_uid,
+ sb.st_gid, sb.st_size, NULL);
return file;
}
Modified: trunk/darwinup/File.h
===================================================================
--- trunk/darwinup/File.h 2010-09-16 22:51:34 UTC (rev 880)
+++ trunk/darwinup/File.h 2010-09-18 00:28:31 UTC (rev 881)
@@ -39,6 +39,28 @@
#include <sys/stat.h>
#include <fts.h>
+#define FILE_OBJ_CHANGE_ERROR \
+"-----------------------------------------------------------------------------\n" \
+"Potentially unsafe mismatch between the root and destination: \n\n" \
+"%s\n\n" \
+"You seem to be trying to install a %s over a %s. \n" \
+"Darwinup will not install this root by default since it could cause damage \n" \
+"to your system. You can use the force (-f) option to allow darwinup to \n" \
+"attempt the install anyway. \n" \
+"-----------------------------------------------------------------------------\n"
+
+#define FILE_TYPE_STRING(type) \
+(type == S_IFIFO ? "named pipe" : \
+(type == S_IFCHR ? "character special" : \
+(type == S_IFDIR ? "directory" : \
+(type == S_IFBLK ? "block special" : \
+(type == S_IFREG ? "file" : \
+(type == S_IFLNK ? "symbolic link" : \
+(type == S_IFSOCK ? "socket" : \
+(type == S_IFWHT ? "whiteout" : \
+"unknown"))))))))
+
+
enum file_starseded_t {
FILE_SUPERSEDED,
FILE_PRECEDED
Modified: trunk/darwinup/Utils.cpp
===================================================================
--- trunk/darwinup/Utils.cpp 2010-09-16 22:51:34 UTC (rev 880)
+++ trunk/darwinup/Utils.cpp 2010-09-18 00:28:31 UTC (rev 881)
@@ -104,7 +104,7 @@
int is_directory(const char* path) {
struct stat sb;
- int res = stat(path, &sb);
+ int res = lstat(path, &sb);
return (res == 0 && S_ISDIR(sb.st_mode));
}
Modified: trunk/darwinup/main.cpp
===================================================================
--- trunk/darwinup/main.cpp 2010-09-16 22:51:34 UTC (rev 880)
+++ trunk/darwinup/main.cpp 2010-09-18 00:28:31 UTC (rev 881)
@@ -183,14 +183,14 @@
// list handles args optional and in special ways
if (strcmp(argv[0], "list") == 0) {
res = depot->initialize(false);
- if (res == -2) {
+ if (res == DEPOT_NOT_EXIST) {
// we are not asking to write,
// but no depot exists yet either,
// so print an empty list
depot->archive_header();
exit(0);
}
- if (res == -3) {
+ if (res == DEPOT_PERM_DENIED) {
// permission denied when trying to read
// the depot
fprintf(stderr, "Permission denied when trying to read the database.\n");
@@ -229,6 +229,10 @@
res = depot->process_archive(argv[0], argv[i]);
} else if (strcmp(argv[0], "uninstall") == 0) {
if (i==1 && depot->initialize(true)) exit(15);
+ // uninstall is always in force mode so it can
+ // uninstall archives that were installed under
+ // force mode
+ force = 1;
res = depot->process_archive(argv[0], argv[i]);
} else if (strcmp(argv[0], "verify") == 0) {
if (i==1 && depot->initialize(true)) exit(16);
Modified: trunk/testing/darwinup/dest.tar.gz
===================================================================
(Binary files differ)
Copied: trunk/testing/darwinup/rep_dir_file.tar.gz (from rev 880, branches/PR-8416637/testing/darwinup/rep_dir_file.tar.gz)
===================================================================
(Binary files differ)
Copied: trunk/testing/darwinup/rep_dir_link.tar.gz (from rev 880, branches/PR-8416637/testing/darwinup/rep_dir_link.tar.gz)
===================================================================
(Binary files differ)
Copied: trunk/testing/darwinup/rep_file_dir.tar.gz (from rev 880, branches/PR-8416637/testing/darwinup/rep_file_dir.tar.gz)
===================================================================
(Binary files differ)
Copied: trunk/testing/darwinup/rep_file_link.tar.gz (from rev 880, branches/PR-8416637/testing/darwinup/rep_file_link.tar.gz)
===================================================================
(Binary files differ)
Copied: trunk/testing/darwinup/rep_flink_dir.tar.gz (from rev 880, branches/PR-8416637/testing/darwinup/rep_flink_dir.tar.gz)
===================================================================
(Binary files differ)
Copied: trunk/testing/darwinup/rep_flink_file.tar.gz (from rev 880, branches/PR-8416637/testing/darwinup/rep_flink_file.tar.gz)
===================================================================
(Binary files differ)
Copied: trunk/testing/darwinup/rep_link_dir.tar.gz (from rev 880, branches/PR-8416637/testing/darwinup/rep_link_dir.tar.gz)
===================================================================
(Binary files differ)
Copied: trunk/testing/darwinup/rep_link_file.tar.gz (from rev 880, branches/PR-8416637/testing/darwinup/rep_link_file.tar.gz)
===================================================================
(Binary files differ)
Deleted: trunk/testing/darwinup/root4.tar.gz
===================================================================
(Binary files differ)
Modified: trunk/testing/darwinup/run-tests.sh
===================================================================
--- trunk/testing/darwinup/run-tests.sh 2010-09-16 22:51:34 UTC (rev 880)
+++ trunk/testing/darwinup/run-tests.sh 2010-09-18 00:28:31 UTC (rev 881)
@@ -20,6 +20,20 @@
ROOTS="root root2 root3"
+
+function is_file {
+ test -f $1 -a ! -L $1
+}
+
+function is_dir {
+ test -d $1 -a ! -L $1
+}
+
+function is_link {
+ test -L $1;
+}
+
+
echo "INFO: Cleaning up testing area ..."
rm -rf $PREFIX
mkdir -p $PREFIX
@@ -32,11 +46,17 @@
tar zxvf $R.tar.gz -C $PREFIX
done;
-for R in root4 root5 root6 root7 symlinks symlink_update;
+for R in root5 root6 root7 symlinks symlink_update;
do
tar zxvf $R.tar.gz -C $PREFIX
done;
+for R in rep_dir_file rep_dir_link rep_file_dir rep_file_link \
+ rep_link_dir rep_link_file rep_flink_dir rep_flink_file;
+do
+ tar zxvf $R.tar.gz -C $PREFIX
+done;
+
for R in 300dirs.tbz2 300files.tbz2 deep-rollback.cpgz deep-rollback-2.xar extension.tar.bz2;
do
cp $R $PREFIX/
@@ -277,24 +297,24 @@
$DARWINUP install $PREFIX/root
$DARWINUP install $PREFIX/root6
$DARWINUP rename root "RENAME1"
-C=$($DARWINUP list | grep "RENAME1" | wc -l | xargs)
+C=$($DARWINUP list | grep "RENAME1" | grep -Ev '^Found' | wc -l | xargs)
test "$C" == "1"
$DARWINUP rename oldest "RENAME2"
-C=$($DARWINUP list | grep "RENAME2" | wc -l | xargs)
+C=$($DARWINUP list | grep "RENAME2" | grep -Ev '^Found' | wc -l | xargs)
test "$C" == "1"
$DARWINUP uninstall "RENAME1"
-C=$($DARWINUP list | grep "RENAME1" | wc -l | xargs)
+C=$($DARWINUP list | grep "RENAME1" | grep -Ev '^Found' | wc -l | xargs)
test "$C" == "0"
-C=$($DARWINUP files "RENAME2" | wc -l | xargs)
+C=$($DARWINUP files "RENAME2" | grep -Ev '^Found' | wc -l | xargs)
test "$C" == "17"
-C=$($DARWINUP verify "RENAME2" | wc -l | xargs)
+C=$($DARWINUP verify "RENAME2" | grep -Ev '^Found' | wc -l | xargs)
test "$C" == "17"
$DARWINUP rename root6 RENAME3 RENAME3 RENAME4 RENAME4 RENAME5 RENAME5 RENAME6
-C=$($DARWINUP list | grep "root6" | wc -l | xargs)
+C=$($DARWINUP list | grep "root6" | grep -Ev '^Found' | wc -l | xargs)
test "$C" == "0"
-C=$($DARWINUP list | grep "RENAME6" | wc -l | xargs)
+C=$($DARWINUP list | grep "RENAME6" | grep -Ev '^Found' | wc -l | xargs)
test "$C" == "1"
-C=$($DARWINUP files "RENAME6" | wc -l | xargs)
+C=$($DARWINUP files "RENAME6" | grep -Ev '^Found' | wc -l | xargs)
test "$C" == "8"
$DARWINUP uninstall all
echo "DIFF: diffing original test files to dest (should be no diffs) ..."
@@ -313,16 +333,142 @@
$DIFF $ORIG $DEST 2>&1
+echo "========== TEST: Forcing object change: file to directory =========="
+is_file $DEST/rep_file
+$DARWINUP -f install $PREFIX/rep_file_dir
+is_dir $DEST/rep_file
+$DARWINUP uninstall newest
+is_file $DEST/rep_file
+echo "DIFF: diffing original test files to dest (should be no diffs) ..."
+$DIFF $ORIG $DEST 2>&1
+
+echo "========== TEST: Forcing object change: file to symlink =========="
+is_file $DEST/rep_file
+$DARWINUP -f install $PREFIX/rep_file_link
+is_link $DEST/rep_file
+$DARWINUP uninstall newest
+is_file $DEST/rep_file
+echo "DIFF: diffing original test files to dest (should be no diffs) ..."
+$DIFF $ORIG $DEST 2>&1
+
+echo "========== TEST: Forcing object change: directory to file =========="
+is_dir $DEST/rep_dir
+$DARWINUP -f install $PREFIX/rep_dir_file
+is_file $DEST/rep_dir
+$DARWINUP uninstall newest
+is_dir $DEST/rep_dir
+echo "DIFF: diffing original test files to dest (should be no diffs) ..."
+$DIFF $ORIG $DEST 2>&1
+
+echo "========== TEST: Forcing object change: directory to symlink =========="
+is_dir $DEST/rep_dir
+$DARWINUP -f install $PREFIX/rep_dir_link
+is_link $DEST/rep_dir
+$DARWINUP uninstall newest
+is_dir $DEST/rep_dir
+echo "DIFF: diffing original test files to dest (should be no diffs) ..."
+$DIFF $ORIG $DEST 2>&1
+
+echo "========== TEST: Forcing object change: symlink->dir to file =========="
+is_link $DEST/rep_link
+$DARWINUP -f install $PREFIX/rep_link_file
+is_file $DEST/rep_link
+$DARWINUP uninstall newest
+is_link $DEST/rep_link
+echo "DIFF: diffing original test files to dest (should be no diffs) ..."
+$DIFF $ORIG $DEST 2>&1
+
+echo "========== TEST: Forcing object change: symlink->dir to directory =========="
+is_link $DEST/rep_link
+$DARWINUP -f install $PREFIX/rep_link_dir
+is_dir $DEST/rep_link
+$DARWINUP uninstall newest
+is_link $DEST/rep_link
+echo "DIFF: diffing original test files to dest (should be no diffs) ..."
+$DIFF $ORIG $DEST 2>&1
+
+echo "========== TEST: Forcing object change: symlink->file to file =========="
+is_link $DEST/rep_flink
+$DARWINUP -f install $PREFIX/rep_flink_file
+is_file $DEST/rep_flink
+$DARWINUP uninstall newest
+is_link $DEST/rep_flink
+echo "DIFF: diffing original test files to dest (should be no diffs) ..."
+$DIFF $ORIG $DEST 2>&1
+
+echo "========== TEST: Forcing object change: symlink->file to directory =========="
+is_link $DEST/rep_flink
+$DARWINUP -f install $PREFIX/rep_flink_dir
+is_dir $DEST/rep_flink
+$DARWINUP uninstall newest
+is_link $DEST/rep_flink
+echo "DIFF: diffing original test files to dest (should be no diffs) ..."
+$DIFF $ORIG $DEST 2>&1
+
+
+
#
# The following are expected failures
#
+echo "========== Expected Failures =========="
set +e
-echo "========== TEST: Trying a root that will fail due to object change =========="
-$DARWINUP install $PREFIX/root4
-if [ $? -ne 1 ]; then exit 1; fi
+
+echo "========== TEST: Try replacing File with Directory =========="
+$DARWINUP install $PREFIX/rep_file_dir
+if [ $? -ne 255 ]; then exit 1; fi
echo "DIFF: diffing original test files to dest (should be no diffs) ..."
$DIFF $ORIG $DEST 2>&1
+if [ $? -ne 0 ]; then exit 1; fi
+echo "========== TEST: Try replacing File with Symlink =========="
+$DARWINUP install $PREFIX/rep_file_link
+if [ $? -ne 255 ]; then exit 1; fi
+echo "DIFF: diffing original test files to dest (should be no diffs) ..."
+$DIFF $ORIG $DEST 2>&1
+if [ $? -ne 0 ]; then exit 1; fi
+
+echo "========== TEST: Try replacing Directory with Symlink =========="
+$DARWINUP install $PREFIX/rep_dir_link
+if [ $? -ne 255 ]; then exit 1; fi
+echo "DIFF: diffing original test files to dest (should be no diffs) ..."
+$DIFF $ORIG $DEST 2>&1
+if [ $? -ne 0 ]; then exit 1; fi
+
+echo "========== TEST: Try replacing Directory with File =========="
+$DARWINUP install $PREFIX/rep_dir_file
+if [ $? -ne 255 ]; then exit 1; fi
+echo "DIFF: diffing original test files to dest (should be no diffs) ..."
+$DIFF $ORIG $DEST 2>&1
+if [ $? -ne 0 ]; then exit 1; fi
+
+echo "========== TEST: Try replacing Symlink to directory with Directory =========="
+$DARWINUP install $PREFIX/rep_link_dir
+if [ $? -ne 255 ]; then exit 1; fi
+echo "DIFF: diffing original test files to dest (should be no diffs) ..."
+$DIFF $ORIG $DEST 2>&1
+if [ $? -ne 0 ]; then exit 1; fi
+
+echo "========== TEST: Try replacing Symlink to directory with File =========="
+$DARWINUP install $PREFIX/rep_link_file
+if [ $? -ne 255 ]; then exit 1; fi
+echo "DIFF: diffing original test files to dest (should be no diffs) ..."
+$DIFF $ORIG $DEST 2>&1
+if [ $? -ne 0 ]; then exit 1; fi
+
+echo "========== TEST: Try replacing Symlink to file with Directory =========="
+$DARWINUP install $PREFIX/rep_flink_dir
+if [ $? -ne 255 ]; then exit 1; fi
+echo "DIFF: diffing original test files to dest (should be no diffs) ..."
+$DIFF $ORIG $DEST 2>&1
+if [ $? -ne 0 ]; then exit 1; fi
+
+echo "========== TEST: Try replacing Symlink to file with File =========="
+$DARWINUP install $PREFIX/rep_flink_file
+if [ $? -ne 255 ]; then exit 1; fi
+echo "DIFF: diffing original test files to dest (should be no diffs) ..."
+$DIFF $ORIG $DEST 2>&1
+if [ $? -ne 0 ]; then exit 1; fi
+
popd >> /dev/null
echo "INFO: Done testing!"
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/darwinbuild-changes/attachments/20100917/cfbc5c17/attachment-0001.html>
More information about the darwinbuild-changes
mailing list