diff options
-rw-r--r-- | src/util/testdb.c | 85 |
1 files changed, 78 insertions, 7 deletions
diff --git a/src/util/testdb.c b/src/util/testdb.c index 4f6bfed5..c12aee04 100644 --- a/src/util/testdb.c +++ b/src/util/testdb.c @@ -92,7 +92,7 @@ static int check_localdb_files(void) return ret; } -static int checkdeps(alpm_list_t *pkglist) +static int check_deps(alpm_list_t *pkglist) { alpm_list_t *data, *i; int ret = 0; @@ -101,8 +101,7 @@ static int checkdeps(alpm_list_t *pkglist) for(i = data; i; i = alpm_list_next(i)) { alpm_depmissing_t *miss = i->data; char *depstring = alpm_dep_compute_string(miss->depend); - printf("missing dependency for %s : %s\n", miss->target, - depstring); + printf("missing %s dependency for %s\n", depstring, miss->target); free(depstring); ret++; } @@ -110,7 +109,7 @@ static int checkdeps(alpm_list_t *pkglist) return ret; } -static int checkconflicts(alpm_list_t *pkglist) +static int check_conflicts(alpm_list_t *pkglist) { alpm_list_t *data, *i; int ret = 0; @@ -126,6 +125,77 @@ static int checkconflicts(alpm_list_t *pkglist) return ret; } +struct fileitem { + alpm_file_t *file; + alpm_pkg_t *pkg; +}; + +static int fileitem_cmp(const void *p1, const void *p2) +{ + const struct fileitem * fi1 = p1; + const struct fileitem * fi2 = p2; + return strcmp(fi1->file->name, fi2->file->name); +} + +static int check_filelists(alpm_list_t *pkglist) +{ + alpm_list_t *i; + int ret = 0; + size_t list_size = 4096; + size_t offset = 0, j; + struct fileitem *all_files; + struct fileitem *prev_fileitem = NULL; + + all_files = malloc(list_size * sizeof(struct fileitem)); + + for(i = pkglist; i; i = i->next) { + alpm_pkg_t *pkg = i->data; + alpm_filelist_t *filelist = alpm_pkg_get_files(pkg); + for(j = 0; j < filelist->count; j++) { + alpm_file_t *file = filelist->files + j; + /* only add files, not directories, to our big list */ + if(file->name[strlen(file->name) - 1] == '/') { + continue; + } + + /* do we need to reallocate and grow our array? */ + if(offset >= list_size) { + struct fileitem *new_files; + new_files = realloc(all_files, list_size * 2 * sizeof(struct fileitem)); + if(!new_files) { + free(all_files); + return 1; + } + all_files = new_files; + list_size *= 2; + } + + /* we can finally add it to the list */ + all_files[offset].file = file; + all_files[offset].pkg = pkg; + offset++; + } + } + + /* now sort the list so we can find duplicates */ + qsort(all_files, offset, sizeof(struct fileitem), fileitem_cmp); + + /* do a 'uniq' style check on the list */ + for(j = 0; j < offset; j++) { + struct fileitem *fileitem = all_files + j; + if(prev_fileitem && fileitem_cmp(prev_fileitem, fileitem) == 0) { + printf("file owned by %s and %s: %s\n", + alpm_pkg_get_name(prev_fileitem->pkg), + alpm_pkg_get_name(fileitem->pkg), + fileitem->file->name); + } + prev_fileitem = fileitem; + } + + free(all_files); + return ret; +} + static int check_localdb(void) { int ret = 0; @@ -139,8 +209,9 @@ static int check_localdb(void) db = alpm_option_get_localdb(handle); pkglist = alpm_db_get_pkgcache(db); - ret += checkdeps(pkglist); - ret += checkconflicts(pkglist); + ret += check_deps(pkglist); + ret += check_conflicts(pkglist); + ret += check_filelists(pkglist); return ret; } @@ -163,7 +234,7 @@ static int check_syncdbs(alpm_list_t *dbnames) pkglist = alpm_db_get_pkgcache(db); syncpkglist = alpm_list_join(syncpkglist, alpm_list_copy(pkglist)); } - ret += checkdeps(syncpkglist); + ret += check_deps(syncpkglist); cleanup: alpm_list_free(syncpkglist); |