From f671147282e0f5c6a2e05c8cb7a0d5b72ef8cb61 Mon Sep 17 00:00:00 2001 From: Xavier Chantry Date: Mon, 12 May 2008 18:56:14 -0500 Subject: Fix rewinddir regression by cleaning up db_scan Commit 046003844739416ff6d168dd2dec76490adb0727 caused a regression when rereading the pkgcache after updating the on-disk databases. A rewinddir call was errantly removed. Instead of replacing the call to rewindir, clean up this whole mess. db_scan is used only once and with target == NULL so there was actually half the code of db_scan which was unused. This is gone now and replaced by a single new db_populate function. Dan: add_sorted ended up being 3x slower than one msort at the end, so I changed back to that. I also made one pointer variable const and merged this whole patch with my original fix for the rewinddir issue. Signed-off-by: Xavier Chantry Signed-off-by: Dan McGee --- lib/libalpm/be_files.c | 106 +++++++++++++++---------------------------------- lib/libalpm/cache.c | 20 +++------- lib/libalpm/db.h | 2 +- 3 files changed, 37 insertions(+), 91 deletions(-) (limited to 'lib/libalpm') diff --git a/lib/libalpm/be_files.c b/lib/libalpm/be_files.c index 1e59055c..256a7d0c 100644 --- a/lib/libalpm/be_files.c +++ b/lib/libalpm/be_files.c @@ -177,8 +177,8 @@ int SYMEXPORT alpm_db_update(int force, pmdb_t *db) for(lp = _alpm_db_get_pkgcache(db); lp; lp = lp->next) { pmpkg_t *pkg = lp->data; if(pkg && _alpm_db_remove(db, pkg) == -1) { - _alpm_log(PM_LOG_ERROR, _("could not remove database entry %s%s\n"), db->treename, - alpm_pkg_get_name(pkg)); + _alpm_log(PM_LOG_ERROR, _("could not remove database entry %s%s\n"), + db->treename, pkg->name); RET_ERR(PM_ERR_DB_REMOVE, -1); } } @@ -273,104 +273,60 @@ static int splitname(const char *target, pmpkg_t *pkg) return(0); } -pmpkg_t *_alpm_db_scan(pmdb_t *db, const char *target) +int _alpm_db_populate(pmdb_t *db) { + int count = 0; struct dirent *ent = NULL; struct stat sbuf; char path[PATH_MAX]; - char *ptr = NULL; - int found = 0; - pmpkg_t *pkg = NULL; ALPM_LOG_FUNC; - if(db == NULL) { - RET_ERR(PM_ERR_DB_NULL, NULL); - } - - /* We loop here until we read a valid package. When an iteration of this loop - * fails, it means alpm_db_read failed to read a valid package, so we'll read - * the next so as not to abort whole-db operations early - */ - while(!pkg) { - if(target != NULL) { - /* search for a specific package (by name only) */ - rewinddir(db->handle); - while(!found && (ent = readdir(db->handle)) != NULL) { - char *name; - - if(strcmp(ent->d_name, ".") == 0 || strcmp(ent->d_name, "..") == 0) { - continue; - } - /* stat the entry, make sure it's a directory */ - snprintf(path, PATH_MAX, "%s/%s", db->path, ent->d_name); - if(stat(path, &sbuf) || !S_ISDIR(sbuf.st_mode)) { - continue; - } + ASSERT(db != NULL, RET_ERR(PM_ERR_DB_NULL, -1)); - STRDUP(name, ent->d_name, return(NULL)); - - /* truncate the string at the second-to-last hyphen, */ - /* which will give us the package name */ - if((ptr = rindex(name, '-'))) { - *ptr = '\0'; - } - if((ptr = rindex(name, '-'))) { - *ptr = '\0'; - } - if(strcmp(name, target) == 0) { - found = 1; - } - FREE(name); - } + rewinddir(db->handle); + while((ent = readdir(db->handle)) != NULL) { + const char *name = ent->d_name; + pmpkg_t *pkg; - if(!found) { - return(NULL); - } - } else { /* target == NULL, full scan */ - int isdir = 0; - while(!isdir) { - ent = readdir(db->handle); - if(ent == NULL) { - return(NULL); - } - if(strcmp(ent->d_name, ".") == 0 || strcmp(ent->d_name, "..") == 0) { - isdir = 0; - continue; - } - /* stat the entry, make sure it's a directory */ - snprintf(path, PATH_MAX, "%s/%s", db->path, ent->d_name); - if(!stat(path, &sbuf) && S_ISDIR(sbuf.st_mode)) { - isdir = 1; - } - } + if(strcmp(name, ".") == 0 || strcmp(name, "..") == 0) { + continue; + } + /* stat the entry, make sure it's a directory */ + snprintf(path, PATH_MAX, "%s/%s", db->path, name); + if(stat(path, &sbuf) != 0 || !S_ISDIR(sbuf.st_mode)) { + continue; } pkg = _alpm_pkg_new(NULL, NULL); if(pkg == NULL) { - _alpm_log(PM_LOG_DEBUG, "db scan could not find package: %s\n", target); - return(NULL); + return(-1); } /* split the db entry name */ - if(splitname(ent->d_name, pkg) != 0) { + if(splitname(name, pkg) != 0) { _alpm_log(PM_LOG_ERROR, _("invalid name for database entry '%s'\n"), - ent->d_name); - alpm_pkg_free(pkg); - pkg = NULL; + name); + _alpm_pkg_free(pkg); continue; } /* explicitly read with only 'BASE' data, accessors will handle the rest */ if(_alpm_db_read(db, pkg, INFRQ_BASE) == -1) { - /* TODO removed corrupt entry from the FS here */ + _alpm_log(PM_LOG_ERROR, _("corrupted database entry '%s'\n"), name); _alpm_pkg_free(pkg); - } else { - pkg->origin = PKG_FROM_CACHE; - pkg->origin_data.db = db; + continue; } + pkg->origin = PKG_FROM_CACHE; + 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); + db->pkgcache = alpm_list_add(db->pkgcache, pkg); + count++; } - return(pkg); + db->pkgcache = alpm_list_msort(db->pkgcache, count, _alpm_pkg_cmp); + return(count); } int _alpm_db_read(pmdb_t *db, pmpkg_t *info, pmdbinfrq_t inforeq) diff --git a/lib/libalpm/cache.c b/lib/libalpm/cache.c index d65b63b3..b140476c 100644 --- a/lib/libalpm/cache.c +++ b/lib/libalpm/cache.c @@ -40,31 +40,21 @@ */ int _alpm_db_load_pkgcache(pmdb_t *db) { - pmpkg_t *info; - int count = 0; - ALPM_LOG_FUNC; if(db == NULL) { return(-1); } - _alpm_db_free_pkgcache(db); _alpm_log(PM_LOG_DEBUG, "loading package cache for repository '%s'\n", - db->treename); - - while((info = _alpm_db_scan(db, NULL)) != NULL) { - _alpm_log(PM_LOG_FUNCTION, "adding '%s' to package cache for db '%s'\n", - alpm_pkg_get_name(info), db->treename); - info->origin = PKG_FROM_CACHE; - info->origin_data.db = db; - /* add to the collection */ - db->pkgcache = alpm_list_add(db->pkgcache, info); - count++; + db->treename); + if(_alpm_db_populate(db) == -1) { + _alpm_log(PM_LOG_DEBUG, + "failed to load package cache for repository '%s'\n", db->treename); + return(-1); } - db->pkgcache = alpm_list_msort(db->pkgcache, count, _alpm_pkg_cmp); return(0); } diff --git a/lib/libalpm/db.h b/lib/libalpm/db.h index d500953c..eb0af1ae 100644 --- a/lib/libalpm/db.h +++ b/lib/libalpm/db.h @@ -58,7 +58,7 @@ pmdb_t *_alpm_db_register_sync(const char *treename); /* be.c, backend specific calls */ int _alpm_db_open(pmdb_t *db); void _alpm_db_close(pmdb_t *db); -pmpkg_t *_alpm_db_scan(pmdb_t *db, const char *target); +int _alpm_db_populate(pmdb_t *db); int _alpm_db_read(pmdb_t *db, pmpkg_t *info, pmdbinfrq_t inforeq); int _alpm_db_write(pmdb_t *db, pmpkg_t *info, pmdbinfrq_t inforeq); int _alpm_db_remove(pmdb_t *db, pmpkg_t *info); -- cgit v1.2.3-24-g4f1b