From 327c272bb4540cee396f7e83ff98899876363a79 Mon Sep 17 00:00:00 2001 From: Allan McRae Date: Fri, 4 May 2012 13:56:55 +1000 Subject: Basic running of pacman -Qkk to check mtree files If a package has an mtree file, using pacman -Qkk will read that file and use it to perform more in depth package checking. Currently this only checks for file presence. Signed-off-by: Allan McRae --- src/pacman/check.c | 69 ++++++++++++++++++++++++++++++++++++++++++++++++++++- src/pacman/check.h | 3 ++- src/pacman/pacman.c | 2 +- src/pacman/query.c | 6 ++++- 4 files changed, 76 insertions(+), 4 deletions(-) diff --git a/src/pacman/check.c b/src/pacman/check.c index eec12c33..d35d93b0 100644 --- a/src/pacman/check.c +++ b/src/pacman/check.c @@ -44,7 +44,7 @@ static int check_file_exists(const char *pkgname, const char * filepath, } /* Loop through the files of the package to check if they exist. */ -int check(alpm_pkg_t *pkg) +int check_pkg_fast(alpm_pkg_t *pkg) { const char *root, *pkgname; size_t errors = 0; @@ -88,4 +88,71 @@ int check(alpm_pkg_t *pkg) return (errors != 0 ? 1 : 0); } +/* Loop though files in a package and perform full file property checking. */ +int check_pkg_full(alpm_pkg_t *pkg) +{ + const char *root, *pkgname; + size_t errors = 0; + size_t rootlen; + char filepath[PATH_MAX]; + struct archive *mtree; + struct archive_entry *entry = NULL; + size_t file_count = 0; + + root = alpm_option_get_root(config->handle); + rootlen = strlen(root); + if(rootlen + 1 > PATH_MAX) { + /* we are in trouble here */ + pm_printf(ALPM_LOG_ERROR, _("path too long: %s%s\n"), root, ""); + return 1; + } + strcpy(filepath, root); + + pkgname = alpm_pkg_get_name(pkg); + mtree = alpm_pkg_mtree_open(pkg); + if(mtree == NULL) { + /* TODO: check error to confirm failure due to no mtree file */ + if(!config->quiet) { + printf(_("%s: no mtree file\n"), pkgname); + } + return 0; + } + + while(alpm_pkg_mtree_next(pkg, mtree, &entry) == ARCHIVE_OK) { + struct stat st; + const char *path = archive_entry_pathname(entry); + + /* TODO: ignoring special files for the moment */ + if(*path == '.') { + continue; + } + + file_count++; + + if(rootlen + 1 + strlen(path) > PATH_MAX) { + pm_printf(ALPM_LOG_WARNING, _("path too long: %s%s\n"), root, path); + continue; + } + strcpy(filepath + rootlen, path); + + if(check_file_exists(pkgname, filepath, &st) == 1) { + errors++; + continue; + } + + /* TODO: check file properties */ + } + + alpm_pkg_mtree_close(pkg, mtree); + + if(!config->quiet) { + printf(_n("%s: %jd total file, ", "%s: %jd total files, ", + (unsigned long)file_count), pkgname, (intmax_t)file_count); + printf(_n("%jd altered file\n", "%jd altered files\n", + (unsigned long)errors), (intmax_t)errors); + } + + return (errors != 0 ? 1 : 0); +} + /* vim: set ts=2 sw=2 noet: */ diff --git a/src/pacman/check.h b/src/pacman/check.h index b107a7f5..f71637c4 100644 --- a/src/pacman/check.h +++ b/src/pacman/check.h @@ -22,7 +22,8 @@ #include -int check(alpm_pkg_t *pkg); +int check_pkg_fast(alpm_pkg_t *pkg); +int check_pkg_full(alpm_pkg_t *pkg); #endif /* _PM_CHECK_H */ diff --git a/src/pacman/pacman.c b/src/pacman/pacman.c index a25bbf84..29a489b4 100644 --- a/src/pacman/pacman.c +++ b/src/pacman/pacman.c @@ -460,7 +460,7 @@ static int parsearg_query(int opt) case 'e': config->op_q_explicit = 1; break; case 'g': (config->group)++; break; case 'i': (config->op_q_info)++; break; - case 'k': config->op_q_check = 1; break; + case 'k': (config->op_q_check)++; break; case 'l': config->op_q_list = 1; break; case 'm': config->op_q_foreign = 1; break; case 'n': config->op_q_native = 1; break; diff --git a/src/pacman/query.c b/src/pacman/query.c index f2d5f007..d8d0fc53 100644 --- a/src/pacman/query.c +++ b/src/pacman/query.c @@ -411,7 +411,11 @@ static int display(alpm_pkg_t *pkg) dump_pkg_changelog(pkg); } if(config->op_q_check) { - ret = check(pkg); + if(config->op_q_check == 1) { + ret = check_pkg_fast(pkg); + } else { + ret = check_pkg_full(pkg); + } } if(!config->op_q_info && !config->op_q_list && !config->op_q_changelog && !config->op_q_check) { -- cgit v1.2.3-70-g09d2