summaryrefslogtreecommitdiff
path: root/lib/libalpm/be_files.c
diff options
context:
space:
mode:
authorXavier Chantry <shiningxc@gmail.com>2008-05-12 18:56:14 -0500
committerDan McGee <dan@archlinux.org>2008-05-13 18:44:13 -0500
commitf671147282e0f5c6a2e05c8cb7a0d5b72ef8cb61 (patch)
tree8327c79236e6eea95e929f3f6a37266f44f743e3 /lib/libalpm/be_files.c
parentae5ef3b90fcad0627d450f0be6ea04dbea2019e2 (diff)
downloadpacman-f671147282e0f5c6a2e05c8cb7a0d5b72ef8cb61.tar.xz
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 <shiningxc@gmail.com> Signed-off-by: Dan McGee <dan@archlinux.org>
Diffstat (limited to 'lib/libalpm/be_files.c')
-rw-r--r--lib/libalpm/be_files.c106
1 files changed, 31 insertions, 75 deletions
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)