[darwinbuild-changes] [658] branches/PR-6729491/darwinup

source_changes at macosforge.org source_changes at macosforge.org
Sun Dec 13 00:14:42 PST 2009


Revision: 658
          http://trac.macosforge.org/projects/darwinbuild/changeset/658
Author:   wsiegrist at apple.com
Date:     2009-12-13 00:14:38 -0800 (Sun, 13 Dec 2009)
Log Message:
-----------
Support remote archives. We look for http(s):// and user at host:path patterns, and exec curl or rsync to store temporarily in .DarwinDepot/Downloads/.

Modified Paths:
--------------
    branches/PR-6729491/darwinup/Archive.cpp
    branches/PR-6729491/darwinup/Archive.h
    branches/PR-6729491/darwinup/Depot.cpp
    branches/PR-6729491/darwinup/Depot.h
    branches/PR-6729491/darwinup/Utils.cpp
    branches/PR-6729491/darwinup/Utils.h
    branches/PR-6729491/darwinup/main.cpp

Modified: branches/PR-6729491/darwinup/Archive.cpp
===================================================================
--- branches/PR-6729491/darwinup/Archive.cpp	2009-12-13 06:39:01 UTC (rev 657)
+++ branches/PR-6729491/darwinup/Archive.cpp	2009-12-13 08:14:38 UTC (rev 658)
@@ -273,40 +273,64 @@
 }
 
 
-Archive* ArchiveFactory(const char* path) {
+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);
-	} else if (has_suffix(path, ".cpio")) {
-		archive = new CpioArchive(path);
-	} else if (has_suffix(path, ".cpio.gz") || has_suffix(path, ".cpgz")) {
-		archive = new CpioGZArchive(path);
-	} else if (has_suffix(path, ".cpio.bz2") || has_suffix(path, ".cpbz2")) {
-		archive = new CpioBZ2Archive(path);
-	} else if (has_suffix(path, ".xar")) {
-		archive = new XarArchive(path);
-	} else if (has_suffix(path, ".xar.gz") || has_suffix(path, ".xgz")) {
-		archive = new XarGZArchive(path);
-	} else if (has_suffix(path, ".xar.bz2") || has_suffix(path, ".xbz2")) {
-		archive = new XarBZ2Archive(path);		
-	} else if (has_suffix(path, ".zip")) {
-		archive = new ZipArchive(path);
+	
+	// use file extension to guess archive format
+	if (is_directory(actpath)) {
+		archive = new DittoArchive(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, ".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, ".xar")) {
+		archive = new XarArchive(actpath);
+	} else if (has_suffix(actpath, ".xar.gz") || has_suffix(actpath, ".xgz")) {
+		archive = new XarGZArchive(actpath);
+	} else if (has_suffix(actpath, ".xar.bz2") || has_suffix(actpath, ".xbz2")) {
+		archive = new XarBZ2Archive(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: branches/PR-6729491/darwinup/Archive.h
===================================================================
--- branches/PR-6729491/darwinup/Archive.h	2009-12-13 06:39:01 UTC (rev 657)
+++ branches/PR-6729491/darwinup/Archive.h	2009-12-13 08:14:38 UTC (rev 658)
@@ -48,10 +48,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);

Modified: branches/PR-6729491/darwinup/Depot.cpp
===================================================================
--- branches/PR-6729491/darwinup/Depot.cpp	2009-12-13 06:39:01 UTC (rev 657)
+++ branches/PR-6729491/darwinup/Depot.cpp	2009-12-13 08:14:38 UTC (rev 658)
@@ -46,6 +46,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;
@@ -61,6 +62,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() {
@@ -70,9 +72,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
@@ -80,7 +84,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;
 	}
 	
@@ -95,6 +99,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;

Modified: branches/PR-6729491/darwinup/Depot.h
===================================================================
--- branches/PR-6729491/darwinup/Depot.h	2009-12-13 06:39:01 UTC (rev 657)
+++ branches/PR-6729491/darwinup/Depot.h	2009-12-13 08:14:38 UTC (rev 658)
@@ -43,6 +43,7 @@
         const char*     prefix();
 	const char*	database_path();
 	const char*	archives_path();
+	const char*	downloads_path();
 
 	virtual int	begin_transaction();
 	virtual int	commit_transaction();
@@ -121,6 +122,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: branches/PR-6729491/darwinup/Utils.cpp
===================================================================
--- branches/PR-6729491/darwinup/Utils.cpp	2009-12-13 06:39:01 UTC (rev 657)
+++ branches/PR-6729491/darwinup/Utils.cpp	2009-12-13 08:14:38 UTC (rev 658)
@@ -24,6 +24,7 @@
 #include "Utils.h"
 #include <assert.h>
 #include <errno.h>
+#include <libgen.h>
 #include <limits.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -113,6 +114,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);
@@ -176,3 +194,36 @@
 	} 
 	return 0;
 }
+
+char* fetch_url(const char* srcpath, const char* dstpath) {
+	char* localfile;
+	int res = join_path(&localfile, dstpath, basename((char*)srcpath));
+	if (res || !localfile) return NULL;
+	
+	const char* args[] = {
+		"/usr/bin/curl",
+		"-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) {
+	char* localfile;
+	int res = join_path(&localfile, dstpath, basename((char*)srcpath));
+	if (!localfile) return NULL;
+		
+	const char* args[] = {
+		"/usr/bin/rsync",
+		"-av", srcpath,
+		localfile,
+		NULL
+	};
+
+	if (res == 0) res = exec_with_args(args);
+	if (res == 0) return localfile;
+	return NULL;	
+}

Modified: branches/PR-6729491/darwinup/Utils.h
===================================================================
--- branches/PR-6729491/darwinup/Utils.h	2009-12-13 06:39:01 UTC (rev 657)
+++ branches/PR-6729491/darwinup/Utils.h	2009-12-13 08:14:38 UTC (rev 658)
@@ -39,12 +39,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: branches/PR-6729491/darwinup/main.cpp
===================================================================
--- branches/PR-6729491/darwinup/main.cpp	2009-12-13 06:39:01 UTC (rev 657)
+++ branches/PR-6729491/darwinup/main.cpp	2009-12-13 08:14:38 UTC (rev 658)
@@ -111,7 +111,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) {
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/darwinbuild-changes/attachments/20091213/f2c20449/attachment-0001.html>


More information about the darwinbuild-changes mailing list