[pacman-dev] [PATCH] [RFC] Only extract new db entries
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@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
participants (1)
-
Allan McRae