From fca1c30b801537ce35c1e4aa50331ae52c9bf567 Mon Sep 17 00:00:00 2001
From: Timo Teräs <timo.teras@iki.fi>
Date: Tue, 14 Dec 2010 17:04:26 +0200
Subject: pkg, db: add preliminary support for arch field

Architecture is now:
 - parsed from .PKGINFO
 - written to index and installed db
 - appended to repository URL when fetching files
---
 src/apk_database.h |  2 +-
 src/apk_defines.h  |  1 +
 src/apk_package.h  |  2 +-
 src/database.c     | 26 ++++++++++++++++++++------
 src/package.c      | 10 ++++++++++
 5 files changed, 33 insertions(+), 8 deletions(-)

diff --git a/src/apk_database.h b/src/apk_database.h
index 76ce8a9..cfac023 100644
--- a/src/apk_database.h
+++ b/src/apk_database.h
@@ -103,7 +103,7 @@ struct apk_database {
 	char *root;
 	int root_fd, lock_fd, cache_fd, cachetmp_fd, keys_fd;
 	unsigned name_id, num_repos;
-	const char *cache_dir;
+	const char *cache_dir, *arch;
 	int permanent;
 	unsigned int local_repos;
 
diff --git a/src/apk_defines.h b/src/apk_defines.h
index 30927bd..6d5f49c 100644
--- a/src/apk_defines.h
+++ b/src/apk_defines.h
@@ -49,6 +49,7 @@
 
 extern int apk_verbosity;
 extern unsigned int apk_flags;
+extern const char *apk_arch;
 
 #define APK_FORCE		0x0001
 #define APK_SIMULATE		0x0002
diff --git a/src/apk_package.h b/src/apk_package.h
index 55f6845..8ba1ffe 100644
--- a/src/apk_package.h
+++ b/src/apk_package.h
@@ -85,7 +85,7 @@ struct apk_package {
 	apk_hash_node hash_node;
 	unsigned repos;
 	struct apk_name *name;
-	char *version;
+	char *version, *arch;
 	char *url, *description, *license;
 	struct apk_dependency_array *depends;
 	size_t installed_size, size;
diff --git a/src/database.c b/src/database.c
index 8f9e931..8ad3bdd 100644
--- a/src/database.c
+++ b/src/database.c
@@ -30,6 +30,14 @@
 #include "apk_archive.h"
 #include "apk_print.h"
 
+#if defined(__x86_64__)
+#define APK_DEFAULT_ARCH	"x86_64"
+#elif defined(__i386__)
+#define APK_DEFAULT_ARCH	"x86"
+#else
+#define APK_DEFAULT_ARCH	"noarch"
+#endif
+
 enum {
 	APK_DISALLOW_RMDIR = 0,
 	APK_ALLOW_RMDIR = 1
@@ -37,6 +45,7 @@ enum {
 
 int apk_verbosity = 1;
 unsigned int apk_flags = 0;
+const char *apk_arch = APK_DEFAULT_ARCH;
 
 const char * const apkindex_tar_gz = "APKINDEX.tar.gz";
 static const char * const apk_static_cache_dir = "var/lib/apk";
@@ -444,8 +453,9 @@ int apk_cache_download(struct apk_database *db, const char *url,
 	char fullurl[PATH_MAX];
 	int r;
 
-	snprintf(fullurl, sizeof(fullurl), "%s%s%s",
-		 url, url[strlen(url)-1] == '/' ? "" : "/", item);
+	snprintf(fullurl, sizeof(fullurl), "%s%s%s/%s",
+		 url, url[strlen(url)-1] == '/' ? "" : "/",
+		 db->arch, item);
 	apk_message("fetch %s", fullurl);
 
 	if (apk_flags & APK_SIMULATE)
@@ -1112,6 +1122,8 @@ int apk_db_open(struct apk_database *db, struct apk_db_options *dbopts)
 	blob = APK_BLOB_STR("etc:*etc/init.d");
 	apk_blob_for_each_segment(blob, ":", add_protected_path, db);
 
+	db->arch = apk_arch;
+
 	db->cache_fd = openat(db->root_fd, db->cache_dir, O_RDONLY | O_CLOEXEC);
 	mkdirat(db->cache_fd, "tmp", 0644);
 	db->cachetmp_fd = openat(db->cache_fd, "tmp", O_RDONLY | O_CLOEXEC);
@@ -1389,13 +1401,15 @@ static int apk_repo_is_remote(struct apk_repository *repo)
 }
 
 static struct apk_bstream *apk_repo_file_open(struct apk_repository *repo,
+					      const char *arch,
 					      const char *file,
 					      char *buf, int buflen)
 {
 	const char *url = repo->url;
 
-	snprintf(buf, buflen, "%s%s%s",
-		 url, url[strlen(url)-1] == '/' ? "" : "/", file);
+	snprintf(buf, buflen, "%s%s%s/%s",
+		 url, url[strlen(url)-1] == '/' ? "" : "/",
+		 arch, file);
 
 	if ((apk_flags & APK_NO_NETWORK) && apk_repo_is_remote(repo))
 		return NULL;
@@ -1563,7 +1577,7 @@ int apk_db_add_repository(apk_database_t _db, apk_blob_t repository)
 		bs = apk_bstream_from_file(db->cache_fd, buf);
 	} else {
 		db->local_repos |= BIT(r);
-		bs = apk_repo_file_open(repo, apkindex_tar_gz, buf, sizeof(buf));
+		bs = apk_repo_file_open(repo, db->arch, apkindex_tar_gz, buf, sizeof(buf));
 	}
 	if (bs == NULL) {
 		apk_warning("Failed to open index for %s", repo->url);
@@ -1987,7 +2001,7 @@ static int apk_db_unpack_pkg(struct apk_database *db,
 
 		if (bs == NULL) {
 			apk_pkg_format_plain(pkg, APK_BLOB_BUF(item));
-			bs = apk_repo_file_open(repo, item, file, sizeof(file));
+			bs = apk_repo_file_open(repo, pkg->arch ?: db->arch, item, file, sizeof(file));
 			if (apk_repo_is_remote(repo))
 				need_copy = TRUE;
 		}
diff --git a/src/package.c b/src/package.c
index 377c82c..e327ce5 100644
--- a/src/package.c
+++ b/src/package.c
@@ -623,6 +623,9 @@ int apk_pkg_add_info(struct apk_database *db, struct apk_package *pkg,
 	case 'L':
 		pkg->license = apk_blob_cstr(value);
 		break;
+	case 'A':
+		pkg->arch = apk_blob_cstr(value);
+		break;
 	case 'D':
 		apk_deps_parse(db, &pkg->depends, value);
 		break;
@@ -655,6 +658,7 @@ static int read_info_line(void *ctx, apk_blob_t line)
 		{ "url",     'U' },
 		{ "size",    'I' },
 		{ "license", 'L' },
+		{ "arch",    'A' },
 		{ "depend",  'D' },
 	};
 	struct read_info_ctx *ri = (struct read_info_ctx *) ctx;
@@ -767,6 +771,8 @@ void apk_pkg_free(struct apk_package *pkg)
 		free(pkg->description);
 	if (pkg->license)
 		free(pkg->license);
+	if (pkg->arch)
+		free(pkg->arch);
 	free(pkg);
 }
 
@@ -903,6 +909,10 @@ int apk_pkg_write_index_entry(struct apk_package *info,
 	apk_blob_push_blob(&bbuf, APK_BLOB_STR(info->name->name));
 	apk_blob_push_blob(&bbuf, APK_BLOB_STR("\nV:"));
 	apk_blob_push_blob(&bbuf, APK_BLOB_STR(info->version));
+	if (info->arch != NULL) {
+		apk_blob_push_blob(&bbuf, APK_BLOB_STR("\nA:"));
+		apk_blob_push_blob(&bbuf, APK_BLOB_STR(info->arch));
+	}
 	apk_blob_push_blob(&bbuf, APK_BLOB_STR("\nS:"));
 	apk_blob_push_uint(&bbuf, info->size, 10);
 	apk_blob_push_blob(&bbuf, APK_BLOB_STR("\nI:"));
-- 
cgit v1.2.3-70-g09d2