From 5e61f077357de1767efada259aeb824bcbfe0086 Mon Sep 17 00:00:00 2001
From: Allan McRae <allan@archlinux.org>
Date: Sat, 9 Oct 2010 23:31:29 +1000
Subject: Populate sync db from archive

Read in list of packages for sync db from tar archive.

Breaks reading in _alpm_sync_db_read and a lot of pactests (which
is expected as they do not handle sync db in archives...).

Signed-off-by: Allan McRae <allan@archlinux.org>
---
 lib/libalpm/be_local.c |  1 +
 lib/libalpm/be_sync.c  | 58 ++++++++++++++++++++++++++++----------------------
 lib/libalpm/db.c       | 10 +++++++--
 3 files changed, 42 insertions(+), 27 deletions(-)

(limited to 'lib/libalpm')

diff --git a/lib/libalpm/be_local.c b/lib/libalpm/be_local.c
index d5378cfb..05bd47cf 100644
--- a/lib/libalpm/be_local.c
+++ b/lib/libalpm/be_local.c
@@ -358,6 +358,7 @@ int _alpm_local_db_populate(pmdb_t *db)
 	}
 	while((ent = readdir(dbdir)) != NULL) {
 		const char *name = ent->d_name;
+
 		pmpkg_t *pkg;
 
 		if(strcmp(name, ".") == 0 || strcmp(name, "..") == 0) {
diff --git a/lib/libalpm/be_sync.c b/lib/libalpm/be_sync.c
index 5c929bdb..1a4efd09 100644
--- a/lib/libalpm/be_sync.c
+++ b/lib/libalpm/be_sync.c
@@ -23,6 +23,7 @@
 #include <errno.h>
 #include <dirent.h>
 #include <ctype.h>
+#include <locale.h>
 
 /* libarchive */
 #include <archive.h>
@@ -500,40 +501,53 @@ cleanup:
 	return(0);
 }
 
-
 int _alpm_sync_db_populate(pmdb_t *db)
 {
 	int count = 0;
-	struct dirent *ent = NULL;
-	const char *dbpath;
-	DIR *dbdir;
+	struct archive *archive;
+	struct archive_entry *entry;
+	const char * archive_path;
 
 	ALPM_LOG_FUNC;
 
 	ASSERT(db != NULL, RET_ERR(PM_ERR_DB_NULL, -1));
 
-	dbpath = _alpm_db_path(db);
-	dbdir = opendir(dbpath);
-	if(dbdir == NULL) {
-		return(0);
+	if((archive = archive_read_new()) == NULL)
+		RET_ERR(PM_ERR_LIBARCHIVE, 1);
+
+	archive_read_support_compression_all(archive);
+	archive_read_support_format_all(archive);
+
+	if(archive_read_open_filename(archive, _alpm_db_path(db),
+				ARCHIVE_DEFAULT_BYTES_PER_BLOCK) != ARCHIVE_OK) {
+		_alpm_log(PM_LOG_ERROR, _("could not open %s: %s\n"), _alpm_db_path(db),
+				archive_error_string(archive));
+		RET_ERR(PM_ERR_PKG_OPEN, 1);
 	}
-	while((ent = readdir(dbdir)) != NULL) {
-		const char *name = ent->d_name;
+
+	while(archive_read_next_header(archive, &entry) == ARCHIVE_OK) {
+		const struct stat *st;
+		const char *name;
 		pmpkg_t *pkg;
 
-		if(strcmp(name, ".") == 0 || strcmp(name, "..") == 0) {
-			continue;
-		}
-		if(!is_dir(dbpath, ent)) {
+		st = archive_entry_stat(entry);
+
+		/* only parse directory names */
+		if(S_ISREG(st->st_mode)) {
+			/* we have desc or depends or something else */
 			continue;
 		}
 
+		archive_path = archive_entry_pathname(entry);
+
 		pkg = _alpm_pkg_new();
 		if(pkg == NULL) {
-			closedir(dbdir);
+			archive_read_finish(archive);
 			return(-1);
 		}
-		/* split the db entry name */
+
+		name = archive_entry_pathname(entry);
+
 		if(splitname(name, pkg) != 0) {
 			_alpm_log(PM_LOG_ERROR, _("invalid name for database entry '%s'\n"),
 					name);
@@ -548,17 +562,10 @@ int _alpm_sync_db_populate(pmdb_t *db)
 			continue;
 		}
 
-		/* explicitly read with only 'BASE' data, accessors will handle the rest */
-		if(_alpm_sync_db_read(db, pkg, INFRQ_BASE) == -1) {
-			_alpm_log(PM_LOG_ERROR, _("corrupted database entry '%s'\n"), name);
-			_alpm_pkg_free(pkg);
-			continue;
-		}
-
 		pkg->origin = PKG_FROM_SYNCDB;
 		pkg->ops = &sync_pkg_ops;
-
 		pkg->origin_data.db = db;
+
 		/* add to the collection */
 		_alpm_log(PM_LOG_FUNCTION, "adding '%s' to package cache for db '%s'\n",
 				pkg->name, db->treename);
@@ -566,8 +573,9 @@ int _alpm_sync_db_populate(pmdb_t *db)
 		count++;
 	}
 
-	closedir(dbdir);
 	db->pkgcache = alpm_list_msort(db->pkgcache, count, _alpm_pkg_cmp);
+	archive_read_finish(archive);
+
 	return(count);
 }
 
diff --git a/lib/libalpm/db.c b/lib/libalpm/db.c
index 2e6bf31b..1adf549b 100644
--- a/lib/libalpm/db.c
+++ b/lib/libalpm/db.c
@@ -414,10 +414,10 @@ const char *_alpm_db_path(pmdb_t *db)
 			CALLOC(db->_path, 1, pathsize, RET_ERR(PM_ERR_MEMORY, NULL));
 			sprintf(db->_path, "%s%s/", dbpath, db->treename);
 		} else {
-			pathsize = strlen(dbpath) + 5 + strlen(db->treename) + 2;
+			pathsize = strlen(dbpath) + 5 + strlen(db->treename) + 4;
 			CALLOC(db->_path, 1, pathsize, RET_ERR(PM_ERR_MEMORY, NULL));
 			/* all sync DBs now reside in the sync/ subdir of the dbpath */
-			sprintf(db->_path, "%ssync/%s/", dbpath, db->treename);
+			sprintf(db->_path, "%ssync/%s.db", dbpath, db->treename);
 		}
 		_alpm_log(PM_LOG_DEBUG, "database path for tree %s set to %s\n",
 				db->treename, db->_path);
@@ -766,6 +766,12 @@ int splitname(const char *target, pmpkg_t *pkg)
 	STRDUP(tmp, target, RET_ERR(PM_ERR_MEMORY, -1));
 	p = tmp + strlen(tmp);
 
+	/* remove any trailing '/' */
+	while (*(p - 1) == '/') {
+	  --p;
+	  *p = '\0';
+	}
+
 	/* do the magic parsing- find the beginning of the version string
 	 * by doing two iterations of same loop to lop off two hyphens */
 	for(q = --p; *q && *q != '-'; q--);
-- 
cgit v1.2.3-70-g09d2