summaryrefslogtreecommitdiff
path: root/lib/libalpm/be_files.c
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/be_files.c
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/be_files.c')
-rw-r--r--lib/libalpm/be_files.c111
1 files changed, 59 insertions, 52 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);