summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAaron Griffin <aaron@archlinux.org>2007-01-31 07:48:06 +0100
committerAaron Griffin <aaron@archlinux.org>2007-01-31 07:48:06 +0100
commit0adceabe137fb4647f27916733124599b913a750 (patch)
tree9e248893a6b13e919bcba84b95708932931ec529
parent670319c2fb41f5ce5b446ad52bf2d8ddcf8c1548 (diff)
downloadpacman-0adceabe137fb4647f27916733124599b913a750.tar.gz
pacman-0adceabe137fb4647f27916733124599b913a750.tar.xz
Fix corrupt DB entry handling when loading package entries.
* scan loops no longer abort on corrupt entries * reloading a cache package (and discovering it corrupt) no longer prints 2 messages and uses the pre-build "remove from package cache" function NOTE: The TODOs in there are important for later w.r.t. cleaning up corrupt DB entries but there are some logical complexities with doing so, so I'm holding off for now.
-rw-r--r--lib/libalpm/be_files.c111
-rw-r--r--lib/libalpm/cache.c5
2 files changed, 61 insertions, 55 deletions
diff --git a/lib/libalpm/be_files.c b/lib/libalpm/be_files.c
index 5b54c79c..4de86523 100644
--- a/lib/libalpm/be_files.c
+++ b/lib/libalpm/be_files.c
@@ -114,7 +114,7 @@ pmpkg_t *_alpm_db_scan(pmdb_t *db, char *target, pmdbinfrq_t inforeq)
char name[PKG_FULLNAME_LEN];
char *ptr = NULL;
int found = 0;
- pmpkg_t *pkg;
+ pmpkg_t *pkg = NULL;
ALPM_LOG_FUNC;
@@ -122,64 +122,71 @@ pmpkg_t *_alpm_db_scan(pmdb_t *db, char *target, pmdbinfrq_t inforeq)
RET_ERR(PM_ERR_DB_NULL, NULL);
}
- if(target != NULL) {
- /* search for a specific package (by name only) */
- rewinddir(db->handle);
- while(!found && (ent = readdir(db->handle)) != NULL) {
- if(!strcmp(ent->d_name, ".") || !strcmp(ent->d_name, "..")) {
- 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;
- }
- STRNCPY(name, ent->d_name, PKG_FULLNAME_LEN);
- /* truncate the string at the second-to-last hyphen, */
- /* which will give us the package name */
- if((ptr = rindex(name, '-'))) {
- *ptr = '\0';
+ /* 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) {
+ if(!strcmp(ent->d_name, ".") || !strcmp(ent->d_name, "..")) {
+ 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;
+ }
+ STRNCPY(name, ent->d_name, PKG_FULLNAME_LEN);
+ /* 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)) {
+ found = 1;
+ }
}
- if((ptr = rindex(name, '-'))) {
- *ptr = '\0';
+ if(!found) {
+ return(NULL);
}
- if(!strcmp(name, target)) {
- found = 1;
+ } else {
+ /* normal iteration */
+ int isdir = 0;
+ while(!isdir) {
+ ent = readdir(db->handle);
+ if(ent == NULL) {
+ return(NULL);
+ }
+ if(!strcmp(ent->d_name, ".") || !strcmp(ent->d_name, "..")) {
+ 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(!found) {
+
+ pkg = _alpm_pkg_new(NULL, NULL);
+ if(pkg == NULL) {
return(NULL);
}
- } else {
- /* normal iteration */
- int isdir = 0;
- while(!isdir) {
- ent = readdir(db->handle);
- if(ent == NULL) {
- return(NULL);
- }
- if(!strcmp(ent->d_name, ".") || !strcmp(ent->d_name, "..")) {
- 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(_alpm_pkg_splitname(ent->d_name, pkg->name, pkg->version, 0) == -1) {
+ _alpm_log(PM_LOG_ERROR, _("invalid name for dabatase entry '%s'"), ent->d_name);
+ return(NULL);
+ }
+ if(_alpm_db_read(db, inforeq, pkg) == -1) {
+ /* TODO removed corrupt entry from the FS here */
+ FREEPKG(pkg);
}
- }
-
- pkg = _alpm_pkg_new(NULL, NULL);
- if(pkg == NULL) {
- return(NULL);
- }
- if(_alpm_pkg_splitname(ent->d_name, pkg->name, pkg->version, 0) == -1) {
- _alpm_log(PM_LOG_ERROR, _("invalid name for dabatase entry '%s'"), ent->d_name);
- return(NULL);
- }
- if(_alpm_db_read(db, inforeq, pkg) == -1) {
- FREEPKG(pkg);
}
return(pkg);
diff --git a/lib/libalpm/cache.c b/lib/libalpm/cache.c
index 41b23c36..e7c58a19 100644
--- a/lib/libalpm/cache.c
+++ b/lib/libalpm/cache.c
@@ -121,9 +121,8 @@ int _alpm_db_ensure_pkgcache(pmdb_t *db, pmdbinfrq_t infolevel)
pmpkg_t *pkg = (pmpkg_t *)p->data;
if(infolevel != INFRQ_NONE && !(pkg->infolevel & infolevel)) {
if(_alpm_db_read(db, infolevel, pkg) == -1) {
- _alpm_log(PM_LOG_ERROR, _("failed to read package '%s-%s', removing from package cache"),
- pkg->name, pkg->version);
- p = alpm_list_remove_node(p);
+ /* TODO should we actually remove from the filesystem here as well? */
+ _alpm_db_remove_pkgfromcache(db, pkg);
} else {
reloaded = 1;
}