summaryrefslogtreecommitdiffstats
path: root/lib/libalpm
diff options
context:
space:
mode:
authorAaron Griffin <aaron@archlinux.org>2007-01-31 06:48:06 +0000
committerAaron Griffin <aaron@archlinux.org>2007-01-31 06:48:06 +0000
commit0adceabe137fb4647f27916733124599b913a750 (patch)
tree9e248893a6b13e919bcba84b95708932931ec529 /lib/libalpm
parent670319c2fb41f5ce5b446ad52bf2d8ddcf8c1548 (diff)
downloadpacman-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.
Diffstat (limited to 'lib/libalpm')
-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;
}