FAQ Search Today's Posts Mark Forums Read
» Video Reviews

» Linux Archive

Linux-archive is a website aiming to archive linux email lists and to make them easily accessible for linux users/developers.


» Sponsor

» Partners

» Sponsor

Go Back   Linux Archive > ArchLinux > ArchLinux Pacman Development

 
 
LinkBack Thread Tools
 
Old 01-07-2012, 04:28 PM
Dan McGee
 
Default testdb: check local database for duplicate files

This adds an additional check step to find files in the local database
that claim to be owned by more than one package at once, which is
definitely not a supported setup.

Signed-off-by: Dan McGee <dan@archlinux.org>
---
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 4f6bfed..c12aee0 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
", miss->target,
- depstring);
+ printf("missing %s dependency for %s
", 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
",
+ 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);
--
1.7.8.1
 

Thread Tools




All times are GMT. The time now is 03:29 AM.

VBulletin, Copyright ©2000 - 2014, Jelsoft Enterprises Ltd.
Content Relevant URLs by vBSEO ©2007, Crawlability, Inc.
Copyright 2007 - 2008, www.linux-archive.org