[darwinbuild-changes] [666] trunk
source_changes at macosforge.org
source_changes at macosforge.org
Wed Dec 16 10:16:43 PST 2009
Revision: 666
http://trac.macosforge.org/projects/darwinbuild/changeset/666
Author: wsiegrist at apple.com
Date: 2009-12-16 10:16:43 -0800 (Wed, 16 Dec 2009)
Log Message:
-----------
Merge PR-6729491, PR-7431723, PR-7461534. Add CHANGES entries. Cleanup usage statement.
Modified Paths:
--------------
trunk/CHANGES
trunk/darwinup/Archive.cpp
trunk/darwinup/Archive.h
trunk/darwinup/Depot.cpp
trunk/darwinup/Depot.h
trunk/darwinup/Utils.cpp
trunk/darwinup/Utils.h
trunk/darwinup/main.cpp
Property Changed:
----------------
trunk/
trunk/darwinbuild/darwinbuild.in
trunk/darwinbuild/darwinmaster.in
trunk/darwinbuild/installXcode.in
trunk/darwinbuild/packageRoots.in
trunk/darwinbuild/thinPackages.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
/branches/PR-6634286:632-650
/branches/PR-6688645:479-490
/branches/PR-6722857:495-499
/branches/PR-7250612:635-650
/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-6634286:632-650
/branches/PR-6688645:479-490
/branches/PR-6722857:495-499
/branches/PR-6729491:655-664
/branches/PR-7250612:635-650
/branches/PR-7431723:660-664
/branches/PR-7461534:650-664
/trunk:432-434
Modified: trunk/CHANGES
===================================================================
--- trunk/CHANGES 2009-12-16 16:10:12 UTC (rev 665)
+++ trunk/CHANGES 2009-12-16 18:16:43 UTC (rev 666)
@@ -1,6 +1,13 @@
Darwin Build Scripts Change History
-----------------------------------
+Release 13 [16-Dec-2009]
+ - darwinup: convert use of fork()/exec() to posix_spawn()
+ - darwinup: add Serial to archive list, allow use of serial, name,
+ and keywords to identify archives on the command line
+ - darwinup: support fetching archives via rsync and curl
+ - darwinup: support cpio, xar, zip and pax archives
+
Release 12 [10-Dec-2009]
- darwinup: rollback installations that fail
- darwinup: add force (-f) option to allow potentially unsafe operations
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
/branches/PR-6634286/darwinbuild/darwinbuild.in:632-650
/branches/PR-6688645/darwinbuild/darwinbuild.in:479-490
/branches/PR-6722857/darwinbuild/darwinbuild.in:495-499
/branches/PR-7250612/darwinbuild/darwinbuild.in:635-650
/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-6634286/darwinbuild/darwinbuild.in:632-650
/branches/PR-6688645/darwinbuild/darwinbuild.in:479-490
/branches/PR-6722857/darwinbuild/darwinbuild.in:495-499
/branches/PR-6729491/darwinbuild/darwinbuild.in:655-664
/branches/PR-7250612/darwinbuild/darwinbuild.in:635-650
/branches/PR-7431723/darwinbuild/darwinbuild.in:660-664
/branches/PR-7461534/darwinbuild/darwinbuild.in:650-664
/trunk/darwinbuild/darwinbuild:432-434
Property changes on: trunk/darwinbuild/darwinmaster.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
/branches/PR-6634286/darwinbuild/darwinmaster.in:632-650
/branches/PR-6688645/darwinbuild/darwinmaster.sh.in:479-490
/branches/PR-6722857/darwinbuild/darwinmaster.sh.in:495-499
/branches/PR-7250612/darwinbuild/darwinmaster.in:635-650
/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-6634286/darwinbuild/darwinmaster.in:632-650
/branches/PR-6688645/darwinbuild/darwinmaster.sh.in:479-490
/branches/PR-6722857/darwinbuild/darwinmaster.sh.in:495-499
/branches/PR-6729491/darwinbuild/darwinmaster.in:655-664
/branches/PR-7250612/darwinbuild/darwinmaster.in:635-650
/branches/PR-7431723/darwinbuild/darwinmaster.in:660-664
/branches/PR-7461534/darwinbuild/darwinmaster.in:650-664
/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
/branches/PR-6634286/darwinbuild/installXcode.in:632-650
/branches/PR-6688645/darwinbuild/installXcode.in:479-490
/branches/PR-6722857/darwinbuild/installXcode.in:495-499
/branches/PR-7250612/darwinbuild/installXcode.in:635-650
/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-6634286/darwinbuild/installXcode.in:632-650
/branches/PR-6688645/darwinbuild/installXcode.in:479-490
/branches/PR-6722857/darwinbuild/installXcode.in:495-499
/branches/PR-6729491/darwinbuild/installXcode.in:655-664
/branches/PR-7250612/darwinbuild/installXcode.in:635-650
/branches/PR-7431723/darwinbuild/installXcode.in:660-664
/branches/PR-7461534/darwinbuild/installXcode.in:650-664
/trunk/darwinbuild/installXcode:432-434
Property changes on: trunk/darwinbuild/packageRoots.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
/branches/PR-6634286/darwinbuild/packageRoots.in:632-650
/branches/PR-6688645/darwinbuild/packageRoots.sh.in:479-490
/branches/PR-6722857/darwinbuild/packageRoots.sh.in:495-499
/branches/PR-7250612/darwinbuild/packageRoots.in:635-650
/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-6634286/darwinbuild/packageRoots.in:632-650
/branches/PR-6688645/darwinbuild/packageRoots.sh.in:479-490
/branches/PR-6722857/darwinbuild/packageRoots.sh.in:495-499
/branches/PR-6729491/darwinbuild/packageRoots.in:655-664
/branches/PR-7250612/darwinbuild/packageRoots.in:635-650
/branches/PR-7431723/darwinbuild/packageRoots.in:660-664
/branches/PR-7461534/darwinbuild/packageRoots.in:650-664
/trunk/darwinbuild/packageRoots.sh:432-434
Property changes on: trunk/darwinbuild/thinPackages.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
/branches/PR-6634286/darwinbuild/thinPackages.in:632-650
/branches/PR-6688645/darwinbuild/thinPackages.sh.in:479-490
/branches/PR-6722857/darwinbuild/thinPackages.sh.in:495-499
/branches/PR-7250612/darwinbuild/thinPackages.in:635-650
/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-6634286/darwinbuild/thinPackages.in:632-650
/branches/PR-6688645/darwinbuild/thinPackages.sh.in:479-490
/branches/PR-6722857/darwinbuild/thinPackages.sh.in:495-499
/branches/PR-6729491/darwinbuild/thinPackages.in:655-664
/branches/PR-7250612/darwinbuild/thinPackages.in:635-650
/branches/PR-7431723/darwinbuild/thinPackages.in:660-664
/branches/PR-7461534/darwinbuild/thinPackages.in:650-664
/trunk/darwinbuild/thinPackages.sh:432-434
Modified: trunk/darwinup/Archive.cpp
===================================================================
--- trunk/darwinup/Archive.cpp 2009-12-16 16:10:12 UTC (rev 665)
+++ trunk/darwinup/Archive.cpp 2009-12-16 18:16:43 UTC (rev 666)
@@ -174,6 +174,31 @@
}
+DittoXArchive::DittoXArchive(const char* path) : Archive(path) {}
+
+int DittoXArchive::extract(const char* destdir) {
+ const char* args[] = {
+ "/usr/bin/ditto",
+ "-x", m_path,
+ destdir,
+ NULL
+ };
+ return exec_with_args(args);
+}
+
+CpioArchive::CpioArchive(const char* path) : DittoXArchive(path) {}
+
+CpioGZArchive::CpioGZArchive(const char* path) : DittoXArchive(path) {}
+
+CpioBZ2Archive::CpioBZ2Archive(const char* path) : DittoXArchive(path) {}
+
+PaxArchive::PaxArchive(const char* path) : DittoXArchive(path) {}
+
+PaxGZArchive::PaxGZArchive(const char* path) : DittoXArchive(path) {}
+
+PaxBZ2Archive::PaxBZ2Archive(const char* path) : DittoXArchive(path) {}
+
+
TarArchive::TarArchive(const char* path) : Archive(path) {}
int TarArchive::extract(const char* destdir) {
@@ -213,26 +238,92 @@
}
-Archive* ArchiveFactory(const char* path) {
+XarArchive::XarArchive(const char* path) : Archive(path) {}
+
+int XarArchive::extract(const char* destdir) {
+ const char* args[] = {
+ "/usr/bin/xar",
+ "-xf", m_path,
+ "-C", destdir,
+ NULL
+ };
+ return exec_with_args(args);
+}
+
+
+ZipArchive::ZipArchive(const char* path) : Archive(path) {}
+
+int ZipArchive::extract(const char* destdir) {
+ const char* args[] = {
+ "/usr/bin/ditto",
+ "-xk", m_path,
+ destdir,
+ NULL
+ };
+ return exec_with_args(args);
+}
+
+
+Archive* ArchiveFactory(const char* path, const char* tmppath) {
Archive* archive = NULL;
+ // actual path to archive
+ char* actpath = NULL;
+
+ // fetch remote archives if needed
+ if (is_url_path(path)) {
+ actpath = fetch_url(path, tmppath);
+ if (!actpath) {
+ fprintf(stderr, "Error: could not fetch remote URL: %s \n", path);
+ return NULL;
+ }
+ } else if (is_userhost_path(path)) {
+ actpath = fetch_userhost(path, tmppath);
+ if (!actpath) {
+ fprintf(stderr, "Error: could not fetch remote file from: %s \n", path);
+ return NULL;
+ }
+ } else {
+ actpath = (char *)path;
+ }
+
+
// make sure the archive exists
struct stat sb;
- int res = stat(path, &sb);
+ int res = stat(actpath, &sb);
if (res == -1 && errno == ENOENT) {
return NULL;
}
-
- if (is_directory(path)) {
- archive = new DittoArchive(path);
- } else if (has_suffix(path, ".tar")) {
- archive = new TarArchive(path);
- } else if (has_suffix(path, ".tar.gz") || has_suffix(path, ".tgz")) {
- archive = new TarGZArchive(path);
- } else if (has_suffix(path, ".tar.bz2") || has_suffix(path, ".tbz2")) {
- archive = new TarBZ2Archive(path);
+
+ // use file extension to guess archive format
+ if (is_directory(actpath)) {
+ archive = new DittoArchive(actpath);
+ } else if (has_suffix(actpath, ".cpio")) {
+ archive = new CpioArchive(actpath);
+ } else if (has_suffix(actpath, ".cpio.gz") || has_suffix(actpath, ".cpgz")) {
+ archive = new CpioGZArchive(actpath);
+ } else if (has_suffix(actpath, ".cpio.bz2") || has_suffix(actpath, ".cpbz2")) {
+ archive = new CpioBZ2Archive(actpath);
+ } else if (has_suffix(actpath, ".pax")) {
+ archive = new PaxArchive(actpath);
+ } else if (has_suffix(actpath, ".pax.gz") || has_suffix(actpath, ".pgz")) {
+ archive = new PaxGZArchive(actpath);
+ } else if (has_suffix(actpath, ".pax.bz2") || has_suffix(actpath, ".pbz2")) {
+ archive = new PaxBZ2Archive(actpath);
+ } else if (has_suffix(actpath, ".tar")) {
+ archive = new TarArchive(actpath);
+ } else if (has_suffix(actpath, ".tar.gz") || has_suffix(actpath, ".tgz")) {
+ archive = new TarGZArchive(actpath);
+ } else if (has_suffix(actpath, ".tar.bz2") || has_suffix(actpath, ".tbz2")) {
+ archive = new TarBZ2Archive(actpath);
+ } else if (has_suffix(actpath, ".xar")) {
+ archive = new XarArchive(actpath);
+ } else if (has_suffix(actpath, ".zip")) {
+ archive = new ZipArchive(actpath);
} else {
fprintf(stderr, "Error: unknown archive type: %s\n", path);
}
+
+ if (actpath && actpath != path) free(actpath);
return archive;
}
Modified: trunk/darwinup/Archive.h
===================================================================
--- trunk/darwinup/Archive.h 2009-12-16 16:10:12 UTC (rev 665)
+++ trunk/darwinup/Archive.h 2009-12-16 18:16:43 UTC (rev 666)
@@ -57,10 +57,12 @@
// ArchiveFactory exists to return the correct
// concrete subclass for a given archive to be
// installed. Currently this is determined
-// by the file's suffix.
+// by the file's suffix. The tmppath parameter
+// is the path where files can be stored during
+// processing, such as fetching remote archives.
////
-Archive* ArchiveFactory(const char* path);
+Archive* ArchiveFactory(const char* path, const char* tmppath);
struct Archive {
Archive(const char* path);
@@ -120,7 +122,7 @@
// Constructor for subclasses and Depot to use when unserializing an archive from the database.
Archive(uint64_t serial, uuid_t uuid, const char* name, const char* path, uint64_t info, time_t date_installed);
-
+
uint64_t m_serial;
uuid_t m_uuid;
char* m_name;
@@ -158,27 +160,96 @@
////
-// PkgArchive
+// DittoXArchive
//
-// Corresponds to the Mac OS X installer's .pkg bundle format.
-// Installs the archive using the pax(1) command line tool.
-// NOTE: this does not make any attempt to perform any of the
-// volume checks or run any preflight or postflight actions.
+// Handles any file that `ditto -x` can handle. Intended to be the parent
+// of suffix-specific archive objects.
////
-struct PkgArchive : public Archive {
- PkgArchive(const char* path);
+struct DittoXArchive : public Archive {
+ DittoXArchive(const char* path);
virtual int extract(const char* destdir);
};
+
////
+// CpioArchive
+//
+// Corresponds to the cpio(1) file format.
+// This installs archives using the ditto(1) command line tool with
+// the -x option.
+////
+struct CpioArchive : public DittoXArchive {
+ CpioArchive(const char* path);
+};
+
+////
+// CpioGZArchive
+//
+// Corresponds to the cpio(1) file format, compressed with gzip(1).
+// This installs archives using the ditto(1) command line tool with
+// the -x option.
+////
+struct CpioGZArchive : public DittoXArchive {
+ CpioGZArchive(const char* path);
+};
+
+////
+// CpioBZ2Archive
+//
+// Corresponds to the cpio(1) file format, compressed with bzip2(1).
+// This installs archives using the ditto(1) command line tool with
+// the -x option.
+////
+struct CpioBZ2Archive : public DittoXArchive {
+ CpioBZ2Archive(const char* path);
+};
+
+
+////
+// PaxArchive
+//
+// Corresponds to the pax(1) file format.
+// This installs archives using the ditto(1) command line tool with
+// the -x option.
+////
+struct PaxArchive : public DittoXArchive {
+ PaxArchive(const char* path);
+};
+
+
+////
+// PaxGZArchive
+//
+// Corresponds to the pax(1) file format, compressed with gzip(1).
+// This installs archives using the ditto(1) command line tool with
+// the -x option.
+////
+struct PaxGZArchive : public DittoXArchive {
+ PaxGZArchive(const char* path);
+};
+
+
+////
+// PaxBZ2Archive
+//
+// Corresponds to the pax(1) file format, compressed with bzip2(1).
+// This installs archives using the ditto(1) command line tool with
+// the -x option.
+////
+struct PaxBZ2Archive : public DittoXArchive {
+ PaxBZ2Archive(const char* path);
+};
+
+
+////
// TarArchive
//
// Corresponds to the tar(1) file format. This handles uncompressed tar
// archives by using the tar(1) command line tool.
////
struct TarArchive : public Archive {
- TarArchive(const char* path);
- virtual int extract(const char* destdir);
+ TarArchive(const char* path);
+ virtual int extract(const char* destdir);
};
@@ -190,8 +261,8 @@
// the -z option.
////
struct TarGZArchive : public Archive {
- TarGZArchive(const char* path);
- virtual int extract(const char* destdir);
+ TarGZArchive(const char* path);
+ virtual int extract(const char* destdir);
};
@@ -203,6 +274,30 @@
// the -j option.
////
struct TarBZ2Archive : public Archive {
- TarBZ2Archive(const char* path);
+ TarBZ2Archive(const char* path);
+ virtual int extract(const char* destdir);
+};
+
+
+////
+// XarArchive
+//
+// Corresponds to the xar(1) file format. This handles uncompressed cpio
+// archives by using the xar(1) command line tool.
+////
+struct XarArchive : public Archive {
+ XarArchive(const char* path);
virtual int extract(const char* destdir);
};
+
+
+////
+// ZipArchive
+//
+// Corresponds to a zip archive. We use the -k option to ditto(1)
+// to handle it.
+////
+struct ZipArchive : public Archive {
+ ZipArchive(const char* path);
+ virtual int extract(const char* destdir);
+};
Modified: trunk/darwinup/Depot.cpp
===================================================================
--- trunk/darwinup/Depot.cpp 2009-12-16 16:10:12 UTC (rev 665)
+++ trunk/darwinup/Depot.cpp 2009-12-16 18:16:43 UTC (rev 666)
@@ -55,6 +55,7 @@
m_depot_path = NULL;
m_database_path = NULL;
m_archives_path = NULL;
+ m_downloads_path = NULL;
m_db = NULL;
m_lock_fd = -1;
m_is_locked = 0;
@@ -70,6 +71,7 @@
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");
+ join_path(&m_downloads_path, m_depot_path, "/Downloads");
}
Depot::~Depot() {
@@ -79,9 +81,11 @@
if (m_depot_path) free(m_depot_path);
if (m_database_path) free(m_database_path);
if (m_archives_path) free(m_archives_path);
+ if (m_downloads_path) free(m_downloads_path);
}
const char* Depot::archives_path() { return m_archives_path; }
+const char* Depot::downloads_path() { return m_downloads_path; }
const char* Depot::prefix() { return m_prefix; }
// Initialize the depot storage on disk
@@ -89,7 +93,7 @@
int res = 0;
// initialization requires all these paths to be set
- if (!(m_prefix && m_depot_path && m_database_path && m_archives_path)) {
+ if (!(m_prefix && m_depot_path && m_database_path && m_archives_path && m_downloads_path)) {
return -1;
}
@@ -104,6 +108,12 @@
return res;
}
+ res = mkdir(m_downloads_path, m_depot_mode);
+ if (res && errno != EEXIST) {
+ perror(m_downloads_path);
+ return res;
+ }
+
res = this->lock(LOCK_SH);
if (res) return res;
m_is_locked = 1;
@@ -192,57 +202,181 @@
return archive;
}
-Archive* Depot::archive(const char* uuid) {
- uuid_t uu;
- if (uuid_parse(uuid, uu) == 0) {
- return Depot::archive(uu);
+// Unserialize an archive from the database.
+// Find the last archive installed with this name
+Archive* Depot::archive(archive_name_t name) {
+ int res = 0;
+ Archive* archive = NULL;
+ static sqlite3_stmt* stmt = NULL;
+ if (stmt == NULL && m_db) {
+ const char* query = "SELECT serial, uuid, info, date_added FROM archives WHERE name=? ORDER BY date_added DESC LIMIT 1";
+ res = sqlite3_prepare(m_db, query, -1, &stmt, NULL);
+ if (res != 0) fprintf(stderr, "%s:%d: sqlite3_prepare: %s: %s (%d)\n", __FILE__, __LINE__, query, sqlite3_errmsg(m_db), res);
+ }
+ if (stmt && res == 0) {
+ res = sqlite3_bind_text(stmt, 1, name, -1, SQLITE_STATIC);
+ if (res == 0) res = sqlite3_step(stmt);
+ if (res == SQLITE_ROW) {
+ uuid_t uuid;
+ const void* blob = sqlite3_column_blob(stmt, 1);
+ int blobsize = sqlite3_column_bytes(stmt, 1);
+ if (blobsize > 0) {
+ assert(blobsize == sizeof(uuid_t));
+ memcpy(uuid, blob, sizeof(uuid_t));
+ } else {
+ uuid_clear(uuid);
+ }
+ uint64_t serial = sqlite3_column_int64(stmt, 0);
+ uint64_t info = sqlite3_column_int64(stmt, 2);
+ time_t date_added = sqlite3_column_int(stmt, 3);
+ archive = new Archive(serial, uuid, (const char*)name, NULL, info, date_added);
+ }
+ sqlite3_reset(stmt);
+ }
+ return archive;
+}
+
+Archive* Depot::archive(archive_keyword_t keyword) {
+ int res = 0;
+ Archive* archive = NULL;
+ static sqlite3_stmt* stmt = NULL;
+ const char* query = NULL;
+ if (stmt == NULL && m_db) {
+ if (keyword == DEPOT_ARCHIVE_NEWEST) {
+ query = "SELECT serial FROM archives WHERE name != '<Rollback>' ORDER BY date_added DESC LIMIT 1";
+ } else if (keyword == DEPOT_ARCHIVE_OLDEST) {
+ query = "SELECT serial FROM archives WHERE name != '<Rollback>' ORDER BY date_added ASC LIMIT 1";
+ } else {
+ fprintf(stderr, "Error: unknown archive keyword.\n");
+ res = -1;
+ }
+ if (res == 0) res = sqlite3_prepare(m_db, query, -1, &stmt, NULL);
+ if (res != 0) fprintf(stderr, "%s:%d: sqlite3_prepare: %s: %s (%d)\n", __FILE__, __LINE__, query, sqlite3_errmsg(m_db), res);
+ }
+ if (stmt && res == 0) {
+ res = sqlite3_step(stmt);
+ if (res == SQLITE_ROW) {
+ uint64_t serial = sqlite3_column_int64(stmt, 0);
+ archive = Depot::archive(serial);
+ }
+ sqlite3_reset(stmt);
+ }
+ return archive;
+}
+
+// create a new Archive from a database row
+Archive* Depot::archive(sqlite3_stmt* stmt) {
+ uuid_t uuid;
+ uint64_t serial = sqlite3_column_int64(stmt, 0);
+ const void* blob = sqlite3_column_blob(stmt, 1);
+ int blobsize = sqlite3_column_bytes(stmt, 1);
+ const unsigned char* name = sqlite3_column_text(stmt, 2);
+ uint64_t info = sqlite3_column_int64(stmt, 3);
+ time_t date_added = sqlite3_column_int(stmt, 4);
+ if (blobsize > 0) {
+ assert(blobsize == sizeof(uuid_t));
+ memcpy(uuid, blob, sizeof(uuid_t));
} else {
- return NULL;
+ uuid_clear(uuid);
}
+ return new Archive(serial, uuid, (const char*)name, NULL, info, date_added);
}
-int Depot::iterate_archives(ArchiveIteratorFunc func, void* context) {
+
+// Return Archive from database matching arg, which is one of:
+//
+// uuid (ex: 22969F32-9C4F-4370-82C8-DD3609736D8D)
+// serial (ex: 12)
+// name (ex root.tar.gz)
+// keyword (either "newest" for the most recent root installed
+// or "oldest" for the oldest installed root)
+//
+Archive* Depot::get_archive(const char* arg) {
+ uuid_t uuid;
+ uint64_t serial;
+ if (uuid_parse(arg, uuid) == 0) {
+ return Depot::archive(uuid);
+ }
+ serial = strtoull(arg, NULL, 0);
+ if (serial) {
+ return Depot::archive(serial);
+ }
+ if (strncasecmp("oldest", arg, 6) == 0) {
+ IF_DEBUG("looking for oldest\n");
+ return Depot::archive(DEPOT_ARCHIVE_OLDEST);
+ }
+ if (strncasecmp("newest", arg, 6) == 0) {
+ IF_DEBUG("looking for newest\n");
+ return Depot::archive(DEPOT_ARCHIVE_NEWEST);
+ }
+ return Depot::archive((archive_name_t)arg);
+}
+
+Archive** Depot::get_all_archives(size_t* count) {
+ extern uint32_t verbosity;
int res = 0;
+ *count = this->count_archives();
+ //fprintf(stderr, "DEBUG: get_all_archives got count = %d \n", (int)*count);
+ Archive** list = (Archive**)malloc(*count * sizeof(Archive*));
static sqlite3_stmt* stmt = NULL;
if (stmt == NULL && m_db) {
- const char* query = "SELECT serial, uuid, name, info, date_added FROM archives ORDER BY serial DESC";
+ const char* query = "SELECT serial, uuid, name, info, date_added FROM archives WHERE name != '<Rollback>' ORDER BY serial DESC";
+ if (verbosity & VERBOSE_DEBUG) {
+ query = "SELECT serial, uuid, name, info, date_added FROM archives ORDER BY serial DESC";
+ }
res = sqlite3_prepare(m_db, query, -1, &stmt, NULL);
if (res != 0) fprintf(stderr, "%s:%d: sqlite3_prepare: %s: %s (%d)\n", __FILE__, __LINE__, query, sqlite3_errmsg(m_db), res);
}
if (stmt && res == 0) {
- while (res == 0) {
+ size_t i = 0;
+ while (res != SQLITE_DONE) {
res = sqlite3_step(stmt);
if (res == SQLITE_ROW) {
- res = 0;
- uuid_t uuid;
- uint64_t serial = sqlite3_column_int64(stmt, 0);
- const void* blob = sqlite3_column_blob(stmt, 1);
- int blobsize = sqlite3_column_bytes(stmt, 1);
- const unsigned char* name = sqlite3_column_text(stmt, 2);
- uint64_t info = sqlite3_column_int64(stmt, 3);
- time_t date_added = sqlite3_column_int(stmt, 4);
- if (blobsize > 0) {
- assert(blobsize == sizeof(uuid_t));
- memcpy(uuid, blob, sizeof(uuid_t));
- } else {
- uuid_clear(uuid);
- }
- Archive* archive = new Archive(serial, uuid, (const char*)name, NULL, info, date_added);
- if (archive) {
- res = func(archive, context);
- delete archive;
- } else {
- fprintf(stderr, "%s:%d: new Archive returned NULL\n", __FILE__, __LINE__);
- res = -1;
- break;
- }
- } else if (res == SQLITE_DONE) {
- res = 0;
- break;
- }
+ //fprintf(stderr, "DEBUG: making %d-th archive \n", (int)i);
+ list[i++] = this->archive(stmt);
+ //fprintf(stderr, "DEBUG: archive = %p \n", list[i-1]);
+ }
}
sqlite3_reset(stmt);
}
+ return list;
+}
+
+size_t Depot::count_archives() {
+ extern uint32_t verbosity;
+ int res = 0;
+ size_t count = 0;
+ static sqlite3_stmt* stmt = NULL;
+ if (stmt == NULL && m_db) {
+ const char* query = "SELECT count(*) FROM archives WHERE name != '<Rollback>'";
+ if (verbosity & VERBOSE_DEBUG) {
+ query = "SELECT count(*) FROM archives";
+ }
+ res = sqlite3_prepare(m_db, query, -1, &stmt, NULL);
+ if (res != 0) fprintf(stderr, "%s:%d: sqlite3_prepare: %s: %s (%d)\n", __FILE__, __LINE__, query, sqlite3_errmsg(m_db), res);
+ }
+ if (stmt && res == 0) {
+ res = sqlite3_step(stmt);
+ if (res == SQLITE_ROW) {
+ count = sqlite3_column_int64(stmt, 0);
+ }
+ sqlite3_reset(stmt);
+ }
+ return count;
+}
+
+int Depot::iterate_archives(ArchiveIteratorFunc func, void* context) {
+ int res = 0;
+ size_t count = 0;
+ Archive** list = this->get_all_archives(&count);
+ //fprintf(stderr, "DEBUG: iterate got: %p %d \n", *list, (int)count);
+ for (size_t i = 0; i < count; i++) {
+ //fprintf(stderr, "DEBUG: iterating on i = %d list[i] = %p \n", (int)i, list[i]);
+ if (list[i]) {
+ res = func(list[i], context);
+ delete list[i];
+ }
+ }
return res;
}
@@ -736,12 +870,18 @@
}
int Depot::uninstall(Archive* archive) {
+ extern uint32_t verbosity;
int res = 0;
assert(archive != NULL);
uint64_t serial = archive->serial();
if (INFO_TEST(archive->info(), ARCHIVE_INFO_ROLLBACK)) {
+ // 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;
+ }
fprintf(stderr, "%s:%d: cannot uninstall a rollback archive.\n", __FILE__, __LINE__);
return -1;
}
@@ -806,12 +946,18 @@
int Depot::verify(Archive* archive) {
int res = 0;
+ fprintf(stdout, "%-6s %-36s %-23s %s\n", "Serial", "UUID", "Date Installed", "Name");
+ fprintf(stdout, "====== ==================================== ======================= =================\n");
+ list_archive(archive, stdout);
+ fprintf(stdout, "=======================================================================================\n");
if (res == 0) res = this->iterate_files(archive, &Depot::verify_file, NULL);
+ fprintf(stdout, "=======================================================================================\n\n");
return res;
}
-int Depot::list_archive(Archive* archive, void* context) {
- extern uint32_t verbosity;
+int Depot::list_archive(Archive* archive, void* context) {
+ uint64_t serial = archive->serial();
+
char uuid[37];
uuid_unparse_upper(archive->uuid(), uuid);
@@ -821,18 +967,15 @@
localtime_r(&seconds, &local);
strftime(date, sizeof(date), "%F %T %Z", &local);
- if (!INFO_TEST(archive->info(), ARCHIVE_INFO_ROLLBACK) ||
- (verbosity & VERBOSE_DEBUG)) {
- fprintf((FILE*)context, "%-36s %-23s %s\n", uuid, date, archive->name());
- }
+ fprintf((FILE*)context, "%-6llu %-36s %-23s %s\n", serial, uuid, date, archive->name());
return 0;
}
int Depot::list() {
int res = 0;
- fprintf(stdout, "%-36s %-23s %s\n", "UUID", "Date Installed", "Name");
- fprintf(stdout, "==================================== ======================= =================\n");
+ fprintf(stdout, "%-6s %-36s %-23s %s\n", "Serial", "UUID", "Date Installed", "Name");
+ fprintf(stdout, "====== ==================================== ======================= =================\n");
if (res == 0) res = this->iterate_archives(&Depot::list_archive, stdout);
return res;
}
@@ -846,11 +989,12 @@
int Depot::files(Archive* archive) {
int res = 0;
- fprintf(stdout, "%-36s %-23s %s\n", "UUID", "Date Installed", "Name");
- fprintf(stdout, "==================================== ======================= =================\n");
+ fprintf(stdout, "%-6s %-36s %-23s %s\n", "Serial", "UUID", "Date Installed", "Name");
+ fprintf(stdout, "====== ==================================== ======================= =================\n");
list_archive(archive, stdout);
- fprintf(stdout, "================================================================================\n");
+ fprintf(stdout, "=======================================================================================\n");
if (res == 0) res = this->iterate_files(archive, &Depot::print_file, stdout);
+ fprintf(stdout, "=======================================================================================\n\n");
return res;
}
@@ -858,9 +1002,9 @@
Depot* depot = (Depot*)context;
int res = 0;
list_archive(archive, stdout);
- fprintf(stdout, "================================================================================\n");
+ fprintf(stdout, "=======================================================================================\n");
if (res == 0) res = depot->iterate_files(archive, &Depot::print_file, stdout);
- fprintf(stdout, "================================================================================\n\n\n");
+ fprintf(stdout, "=======================================================================================\n\n");
return res;
}
@@ -868,8 +1012,8 @@
extern uint32_t verbosity;
verbosity = 0xFFFFFFFF; // dump is intrinsically a debug command
int res = 0;
- fprintf(stdout, "%-36s %-23s %s\n", "UUID", "Date Installed", "Name");
- fprintf(stdout, "==================================== ======================= =================\n");
+ fprintf(stdout, "%-6s %-36s %-23s %s\n", "Serial", "UUID", "Date Installed", "Name");
+ fprintf(stdout, "====== ==================================== ======================= =================\n");
if (res == 0) res = this->iterate_archives(&Depot::dump_archive, this);
return res;
}
@@ -1138,7 +1282,63 @@
return res;
}
+// helper to dispatch the actual command for process_archive()
+int Depot::dispatch_command(Archive* archive, const char* command) {
+ int res = 0;
+ if (strncasecmp((char*)command, "files", 5) == 0) {
+ res = this->files(archive);
+ } else if (strncasecmp((char*)command, "uninstall", 9) == 0) {
+ res = this->uninstall(archive);
+ } else if (strncasecmp((char*)command, "verify", 6) == 0) {
+ res = this->verify(archive);
+ } else {
+ fprintf(stderr, "Error: unknown command given to dispatch_command.\n");
+ }
+ if (res != 0) {
+ fprintf(stderr, "An error occurred.\n");
+ }
+ return res;
+}
+
+// perform a command on an archive specification
+int Depot::process_archive(const char* command, const char* arg) {
+ extern uint32_t verbosity;
+ int res = 0;
+ size_t count = 0;
+ Archive** list = NULL;
+
+ if (strncasecmp(arg, "all", 3) == 0) {
+ list = this->get_all_archives(&count);
+ } else {
+ // make a list of 1 Archive
+ list = (Archive**)malloc(sizeof(Archive*));
+ list[0] = this->get_archive(arg);
+ count = 1;
+ }
+
+ //fprintf(stderr, "DEBUG: count = %d \n", (int)count);
+
+ for (size_t i = 0; i < count; i++) {
+ //fprintf(stderr, "DEBUG: i = %d \n", (int)i);
+ if (!list[i]) {
+ fprintf(stderr, "Archive not found: %s\n", arg);
+ return -1;
+ }
+ if (verbosity & VERBOSE_DEBUG) {
+ char uuid[37];
+ uuid_unparse_upper(list[i]->uuid(), uuid);
+ fprintf(stderr, "Found archive: %s\n", uuid);
+ }
+ //fprintf(stderr, "DEBUG: dispatching %p %s \n", list[i], command);
+ res = this->dispatch_command(list[i], command);
+ delete list[i];
+ }
+ free(list);
+ return res;
+}
+
+
#define __SQL(callback, context, fmt) \
va_list args; \
char* errmsg; \
Modified: trunk/darwinup/Depot.h
===================================================================
--- trunk/darwinup/Depot.h 2009-12-16 16:10:12 UTC (rev 665)
+++ trunk/darwinup/Depot.h 2009-12-16 18:16:43 UTC (rev 666)
@@ -40,6 +40,13 @@
typedef int (*ArchiveIteratorFunc)(Archive* archive, void* context);
typedef int (*FileIteratorFunc)(File* file, void* context);
+typedef char* archive_name_t;
+
+enum archive_keyword_t {
+ DEPOT_ARCHIVE_NEWEST,
+ DEPOT_ARCHIVE_OLDEST
+};
+
struct Depot {
Depot();
Depot(const char* prefix);
@@ -49,18 +56,26 @@
int initialize();
int is_initialized();
- const char* prefix();
+ const char* prefix();
const char* database_path();
const char* archives_path();
+ const char* downloads_path();
virtual int begin_transaction();
virtual int commit_transaction();
virtual int rollback_transaction();
- Archive* archive(uint64_t serial);
- Archive* archive(uuid_t uuid);
- Archive* archive(const char* uuid);
+ Archive* archive(uint64_t serial);
+ Archive* archive(uuid_t uuid);
+ Archive* archive(archive_name_t name);
+ Archive* archive(archive_keyword_t keyword);
+ Archive* archive(sqlite3_stmt* stmt);
+ Archive* get_archive(const char* arg);
+ // returns a list of Archive*. Caller must free the list.
+ Archive** get_all_archives(size_t *count);
+ size_t count_archives();
+
int dump();
static int dump_archive(Archive* archive, void* context);
@@ -83,8 +98,13 @@
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();
+ // processes an archive according to command
+ // arg is an archive identifier, such as serial or uuid
+ int dispatch_command(Archive* archive, const char* command);
+ int process_archive(const char* command, const char* arg);
+
+ // test if the depot is currently locked
+ int is_locked();
protected:
@@ -114,7 +134,7 @@
// Removes all archive entries which have no corresponding files entries.
int prune_archives();
-
+
File* file_superseded_by(File* file);
File* file_preceded_by(File* file);
File* file_star_eded_by(File* file, sqlite3_stmt* stmt);
@@ -130,6 +150,7 @@
char* m_depot_path;
char* m_database_path;
char* m_archives_path;
+ char* m_downloads_path;
int m_lock_fd;
int m_is_locked;
};
Modified: trunk/darwinup/Utils.cpp
===================================================================
--- trunk/darwinup/Utils.cpp 2009-12-16 16:10:12 UTC (rev 665)
+++ trunk/darwinup/Utils.cpp 2009-12-16 18:16:43 UTC (rev 666)
@@ -33,11 +33,13 @@
#include "Utils.h"
#include <assert.h>
#include <errno.h>
+#include <libgen.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
+#include <spawn.h>
#include <sys/stat.h>
extern char** environ;
@@ -122,6 +124,23 @@
return (res == 0 && S_ISREG(sb.st_mode));
}
+int is_url_path(const char* path) {
+ if (strncmp("http://", path, 7) == 0) {
+ return 1;
+ }
+ if (strncmp("https://", path, 8) == 0) {
+ return 1;
+ }
+ return 0;
+}
+
+int is_userhost_path(const char* path) {
+ // look for user at host:path
+ char *at = strchr(path, '@');
+ char *colon = strchr(path, ':');
+ return at && colon && at < colon;
+}
+
int has_suffix(const char* str, const char* sfx) {
str = strstr(str, sfx);
return (str && strcmp(str, sfx) == 0);
@@ -132,12 +151,13 @@
pid_t pid;
int status;
- pid = fork();
- assert(pid != -1);
- if (pid == 0) {
- assert(execve(args[0], (char**)args, environ) != -1);
- // NOT REACHED
- }
+ IF_DEBUG("Spawning %s \n", args[0]);
+
+ res = posix_spawn(&pid, args[0], NULL, NULL, (char**)args, environ);
+ if (res != 0) fprintf(stderr, "Error: Failed to spawn %s: %s (%d)\n", args[0], strerror(res), res);
+
+ IF_DEBUG("Running %s on pid %d \n", args[0], (int)pid);
+
do {
res = waitpid(pid, &status, 0);
} while (res == -1 && errno == EINTR);
@@ -148,6 +168,9 @@
res = -1;
}
}
+
+ IF_DEBUG("Done running %s \n", args[0]);
+
return res;
}
@@ -185,3 +208,40 @@
}
return 0;
}
+
+char* fetch_url(const char* srcpath, const char* dstpath) {
+ extern uint32_t verbosity;
+ char* localfile;
+ int res = join_path(&localfile, dstpath, basename((char*)srcpath));
+ if (res || !localfile) return NULL;
+
+ const char* args[] = {
+ "/usr/bin/curl",
+ (verbosity ? "-v" : "-s"),
+ "-L", srcpath,
+ "-o", localfile,
+ NULL
+ };
+ if (res == 0) res = exec_with_args(args);
+ if (res == 0) return localfile;
+ return NULL;
+}
+
+char* fetch_userhost(const char* srcpath, const char* dstpath) {
+ extern uint32_t verbosity;
+ char* localfile;
+ int res = join_path(&localfile, dstpath, basename((char*)srcpath));
+ if (!localfile) return NULL;
+
+ const char* args[] = {
+ "/usr/bin/rsync",
+ (verbosity ? "-v" : "-q"),
+ "-a", srcpath,
+ localfile,
+ NULL
+ };
+
+ if (res == 0) res = exec_with_args(args);
+ if (res == 0) return localfile;
+ return NULL;
+}
Modified: trunk/darwinup/Utils.h
===================================================================
--- trunk/darwinup/Utils.h 2009-12-16 16:10:12 UTC (rev 665)
+++ trunk/darwinup/Utils.h 2009-12-16 18:16:43 UTC (rev 666)
@@ -48,12 +48,17 @@
int remove_directory(const char* path);
int is_directory(const char* path);
int is_regular_file(const char* path);
+int is_url_path(const char* path);
+int is_userhost_path(const char* path);
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);
+char* fetch_url(const char* srcpath, const char* dstpath);
+char* fetch_userhost(const char* srcpath, const char* dstpath);
+
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-12-16 16:10:12 UTC (rev 665)
+++ trunk/darwinup/main.cpp 2009-12-16 18:16:43 UTC (rev 666)
@@ -52,9 +52,29 @@
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");
+ fprintf(stderr, " files <archive> \n");
+ fprintf(stderr, " uninstall <archive> \n");
+ fprintf(stderr, " verify <archive> \n");
+ fprintf(stderr, " \n");
+ fprintf(stderr, "<path> is one of: \n");
+ fprintf(stderr, " /path/to/local/dir-or-file \n");
+ fprintf(stderr, " user at host:/path/to/remote/dir-or-file \n");
+ fprintf(stderr, " http[s]://host/path/to/remote/file \n");
+ fprintf(stderr, " \n");
+ fprintf(stderr, "Files must be in one of the supported archive formats: \n");
+ fprintf(stderr, " cpio, cpio.gz, cpio.bz2 \n");
+ fprintf(stderr, " pax, pax.gz, pax.bz2 \n");
+ fprintf(stderr, " tar, tar.gz, tar.bz2 \n");
+ fprintf(stderr, " xar, zip \n");
+ fprintf(stderr, " \n");
+ fprintf(stderr, "<archive> is one of: \n");
+ fprintf(stderr, " <serial> the Serial number \n");
+ fprintf(stderr, " <uuid> the UUID \n");
+ fprintf(stderr, " <name> the last root installed with that name \n");
+ fprintf(stderr, " newest the newest (last) root installed \n");
+ fprintf(stderr, " oldest the oldest root installed \n");
+ fprintf(stderr, " all all installed roots \n");
+ fprintf(stderr, " \n");
exit(1);
}
@@ -120,7 +140,7 @@
if (argc == 2 && strcmp(argv[0], "install") == 0) {
char uuid[37];
- Archive* archive = ArchiveFactory(argv[1]);
+ Archive* archive = ArchiveFactory(argv[1], depot->downloads_path());
if (archive) {
res = depot->install(archive);
if (res == 0) {
@@ -145,40 +165,11 @@
} else if (argc == 1 && strcmp(argv[0], "dump") == 0) {
depot->dump();
} else if (argc == 2 && strcmp(argv[0], "files") == 0) {
- Archive* archive = depot->archive(argv[1]);
- if (archive) {
- res = depot->files(archive);
- delete archive;
- } else {
- fprintf(stderr, "Archive not found: %s\n", argv[1]);
- res = 1;
- }
+ res = depot->process_archive(argv[0], argv[1]);
} else if (argc == 2 && strcmp(argv[0], "uninstall") == 0) {
- Archive* archive = depot->archive(argv[1]);
- if (archive) {
- res = depot->uninstall(archive);
- if (res != 0) {
- fprintf(stderr, "An error occurred.\n");
- res = 1;
- }
- delete archive;
- } else {
- fprintf(stderr, "Archive not found: %s\n", argv[1]);
- res = 1;
- }
+ res = depot->process_archive(argv[0], argv[1]);
} else if (argc == 2 && strcmp(argv[0], "verify") == 0) {
- Archive* archive = depot->archive(argv[1]);
- if (archive) {
- res = depot->verify(archive);
- if (res != 0) {
- fprintf(stderr, "An error occurred.\n");
- res = 1;
- }
- delete archive;
- } else {
- fprintf(stderr, "Archive not found: %s\n", argv[1]);
- res = 1;
- }
+ res = depot->process_archive(argv[0], argv[1]);
} else {
usage(progname);
}
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/darwinbuild-changes/attachments/20091216/3e201c3e/attachment-0001.html>
More information about the darwinbuild-changes
mailing list