[pacman-dev] [PATCH] [RFC] Only extract new db entries

Allan McRae allan at archlinux.org
Fri Oct 9 13:11:27 EDT 2009


This is an incomplete patch that I need some help finishing.  The
idea is to only extract folders for new packages into the package
database and then clean up the old directories.  This is essentially
implementing Xyne's "rebase" script within pacman.

So far I have got:
1. Only remove all db entries if using "-Syy"
2. Generate list of directories in db
3. ???
4. Clean up directories not found in new db.

Step 3 needs to check if an directory in the sync db archive is in the
current database. If it is not, then extract its files.  If it is,
then remove it from the list of directories that will be removed in
step 4.

This is where I am confused on how best to proceed.  The archive will
be open to read a list of files, so calling _aplm_unpack for a single
file would seem a waste.  I am not sure how to continue.

Signed-off-by: Allan McRae <allan at archlinux.org>
---
 lib/libalpm/be_files.c |   60 ++++++++++++++++++++++++++++++++++++++++++-----
 1 files changed, 53 insertions(+), 7 deletions(-)

diff --git a/lib/libalpm/be_files.c b/lib/libalpm/be_files.c
index 21533ef..5e5a5fa 100644
--- a/lib/libalpm/be_files.c
+++ b/lib/libalpm/be_files.c
@@ -181,6 +181,9 @@ int SYMEXPORT alpm_db_update(int force, pmdb_t *db)
 	time_t newmtime = 0, lastupdate = 0;
 	const char *dbpath;
 	size_t len;
+	DIR *dbdir;
+	struct dirent *ent = NULL;
+	alpm_list_t *dbdirlist;
 
 	int ret;
 
@@ -229,36 +232,79 @@ int SYMEXPORT alpm_db_update(int force, pmdb_t *db)
 		return(-1);
 	} else {
 		const char *syncdbpath = _alpm_db_path(db);
-		/* remove the old dir */
-		if(_alpm_rmrf(syncdbpath) != 0) {
-			_alpm_log(PM_LOG_ERROR, _("could not remove database %s\n"), db->treename);
-			RET_ERR(PM_ERR_DB_REMOVE, -1);
+
+		/* remove the old dir if forcing update */
+		if(force) {
+			if(_alpm_rmrf(syncdbpath) != 0) {
+				_alpm_log(PM_LOG_ERROR, _("could not remove database %s\n"), db->treename);
+				RET_ERR(PM_ERR_DB_REMOVE, -1);
+			}
 		}
 
-		/* Cache needs to be rebuilt */
-		_alpm_db_free_pkgcache(db);
+		/* create list of directories in db */
+		dbdir = opendir(syncdbpath);
+		if (dbdir != NULL) {
+			while((ent = readdir(dbdir)) != NULL) {
+				const char *name = ent->d_name
+				if(strcmp(name, ".") == 0 || strcmp(name, "..") == 0) {
+					continue;
+				}
+
+				/* stat the entry, make sure it's a directory */
+				snprintf(path, PATH_MAX, "%s%s", dbpath, name);
+				if(stat(path, &sbuf) != 0 || !S_ISDIR(sbuf.st_mode)) {
+					continue;
+				}
+
+				dbdirlist = _alpm_list_add(dbdirlist, name)
+			}
+		}
+		close(dbdir);
 
 		/* form the path to the db location */
 		len = strlen(dbpath) + strlen(db->treename) + strlen(DBEXT) + 1;
 		MALLOC(dbfilepath, len, RET_ERR(PM_ERR_MEMORY, -1));
 		sprintf(dbfilepath, "%s%s" DBEXT, dbpath, db->treename);
 
-		/* uncompress the sync database */
+		/* TODO - extract new entries from the sync database */
+		/* Remove old entries from dbdirlist as we go */
 		checkdbdir(db);
+
+/* old code to be replaced
 		ret = _alpm_unpack(dbfilepath, syncdbpath, NULL);
 		if(ret) {
 			free(dbfilepath);
 			RET_ERR(PM_ERR_SYSTEM, -1);
 		}
+*/
+
 		unlink(dbfilepath);
 		free(dbfilepath);
 
+		/* remove old directories from dbdir */
+		for (i = dbdirlist; i; i = i->next) {
+			const char *name = i->data;
+			len = strlen(dbpath) + strlen(db->treename) + strlen(DBEXT) + 1;
+			MALLOC(olddbdir, len, RET_ERR(PM_ERR_MEMORY, -1));
+			snprintf(olddbdir, PATH_MAX, "%s/%s", syncdbpath, name);
+			if(_alpm_rmrf(olddbdir) != 0) {
+				_alpm_log(PM_LOG_ERROR, _("could not remove database directory %s\n"), olddbdir);
+				free(olddbdir);
+				RET_ERR(PM_ERR_DB_REMOVE, -1);
+			}
+			free(olddbdir);
+		}
+		FREELIST(dbdirlist);
+
 		/* if we have a new mtime, set the DB last update value */
 		if(newmtime) {
 			_alpm_log(PM_LOG_DEBUG, "sync: new mtime for %s: %ju\n",
 					db->treename, (uintmax_t)newmtime);
 			setlastupdate(db, newmtime);
 		}
+
+		/* Cache needs to be rebuilt */
+		_alpm_db_free_pkgcache(db);
 	}
 
 	return(0);
-- 
1.6.4.4



More information about the pacman-dev mailing list