[pacman-dev] [PATCH] New feature: files verification
changaco
changaco at laposte.net
Sat Mar 28 09:52:59 EDT 2009
>From 7c0348fa499f55968764fef4c7bb3d3d7245932b Mon Sep 17 00:00:00 2001
From: Charly COSTE <changaco at laposte.net>
Date: Sat, 28 Mar 2009 12:36:23 +0100
Subject: [PATCH] New feature: files verification
A new option "-Qy" which checks if the files owned by a/some/all package(s) really are on the system (i.e. not accidentally deleted). http://bugs.archlinux.org/task/13877
Signed-off-by: Charly COSTE <changaco at laposte.net>
---
src/pacman/conf.h | 1 +
src/pacman/pacman.c | 6 +++-
src/pacman/query.c | 87 +++++++++++++++++++++++++++++++++++++++++++++-----
3 files changed, 84 insertions(+), 10 deletions(-)
diff --git a/src/pacman/conf.h b/src/pacman/conf.h
index 466d983..01a1828 100644
--- a/src/pacman/conf.h
+++ b/src/pacman/conf.h
@@ -50,6 +50,7 @@ typedef struct __config_t {
unsigned short op_q_search;
unsigned short op_q_changelog;
unsigned short op_q_upgrade;
+ unsigned short op_q_verify;
unsigned short op_s_clean;
unsigned short op_s_downloadonly;
diff --git a/src/pacman/pacman.c b/src/pacman/pacman.c
index 59916d6..e1d13a4 100644
--- a/src/pacman/pacman.c
+++ b/src/pacman/pacman.c
@@ -360,6 +360,7 @@ static int parseargs(int argc, char *argv[])
{"verbose", no_argument, 0, 'v'},
{"downloadonly", no_argument, 0, 'w'},
{"refresh", no_argument, 0, 'y'},
+ {"verify", no_argument, 0, 'y'},
{"noconfirm", no_argument, 0, 1000},
{"config", required_argument, 0, 1001},
{"ignore", required_argument, 0, 1002},
@@ -510,7 +511,10 @@ static int parseargs(int argc, char *argv[])
config->flags |= PM_TRANS_FLAG_DOWNLOADONLY;
config->flags |= PM_TRANS_FLAG_NOCONFLICTS;
break;
- case 'y': (config->op_s_sync)++; break;
+ case 'y':
+ (config->op_s_sync)++;
+ config->op_q_verify = 1;
+ break;
case '?': return(1);
default: return(1);
}
diff --git a/src/pacman/query.c b/src/pacman/query.c
index 0d48638..2a7dba5 100644
--- a/src/pacman/query.c
+++ b/src/pacman/query.c
@@ -334,10 +334,70 @@ static void display(pmpkg_t *pkg)
}
}
+// We loop through the packages and for each packages we loop through files to check if they exist
+static void verify(alpm_list_t *pkgs)
+{
+ alpm_list_t *i, *files, *file, *pkgs2repair;
+ pmpkg_t *pkg;
+ struct stat stFileInfo;
+ int pkgs_n = alpm_list_count(pkgs);
+ int j = 0, k = 0;
+ for(i = pkgs; i; i = alpm_list_next(i)) {
+ j++;
+ pkg = alpm_list_getdata(i);
+ char *pkgname = alpm_pkg_get_name(pkg);
+ if(filter(pkg)) {
+ files = alpm_pkg_get_files(pkg);
+ for(file = files; file; file = alpm_list_next(file)){
+ char *x = alpm_list_getdata(file);
+ char *f = malloc (strlen(x)+2);
+ strcpy(f,"/");
+ strcat(f, x);
+ k++;
+ if(strncmp(f, "/tmp", 4)==0){
+ continue; // ignore files in /tmp
+ }
+ if(lstat(f,&stFileInfo) == 0) { // we use lstat to prevent errors from symbolic links
+ if(!config->quiet){
+ fprintf(stderr, "\rfile n°%i (package %i/%i): OK", k, j, pkgs_n); fflush(stdout);
+ }
+ }
+ else {
+ if(config->quiet){
+ fprintf(stderr, "%s %s\n", pkgname, f); fflush(stdout);
+ } else {
+ fprintf(stderr, "\rfile n°%i (package %i/%i): Missing file owned by \"%s\": %s\n", k, j, pkgs_n, pkgname, f); fflush(stdout);
+ }
+ if(alpm_list_find_ptr(pkgs2repair, pkgname) == NULL) {
+ pkgs2repair = alpm_list_add(pkgs2repair, pkgname);
+ }
+ }
+ }
+ }
+ }
+ if(!config->quiet){
+ fprintf(stderr, "\n");
+ }
+ if(alpm_list_count(pkgs2repair) > 0) {
+ if(!config->quiet){
+ fprintf(stderr, "Damaged packages: ");
+ }
+ for(i = pkgs2repair; i; i = alpm_list_next(i)) {
+ fprintf(stdout, "%s ", alpm_list_getdata(i));
+ }
+ } else {
+ if(!config->quiet){
+ fprintf(stderr, "No damaged packages.");
+ }
+ }
+ fprintf(stdout, "\n");
+ fflush(stdout);
+}
+
int pacman_query(alpm_list_t *targets)
{
int ret = 0;
- alpm_list_t *i;
+ alpm_list_t *i, *pkgs;
/* First: operations that do not require targets */
@@ -363,18 +423,20 @@ int pacman_query(alpm_list_t *targets)
}
/* operations on all packages in the local DB
- * valid: no-op (plain -Q), list, info
+ * valid: no-op (plain -Q), list, info, verify
* invalid: isfile, owns */
if(targets == NULL) {
if(config->op_q_isfile || config->op_q_owns) {
pm_printf(PM_LOG_ERROR, _("no targets specified (use -h for help)\n"));
return(1);
- }
-
- for(i = alpm_db_get_pkgcache(db_local); i; i = alpm_list_next(i)) {
- pmpkg_t *pkg = alpm_list_getdata(i);
- if(filter(pkg)) {
- display(pkg);
+ } else if(config->op_q_verify) {
+ verify(alpm_db_get_pkgcache(db_local));
+ } else {
+ for(i = alpm_db_get_pkgcache(db_local); i; i = alpm_list_next(i)) {
+ pmpkg_t *pkg = alpm_list_getdata(i);
+ if(filter(pkg)) {
+ display(pkg);
+ }
}
}
return(0);
@@ -389,7 +451,7 @@ int pacman_query(alpm_list_t *targets)
}
/* operations on named packages in the local DB
- * valid: no-op (plain -Q), list, info */
+ * valid: no-op (plain -Q), list, info, verify */
for(i = targets; i; i = alpm_list_next(i)) {
char *strname = alpm_list_getdata(i);
pmpkg_t *pkg = NULL;
@@ -406,8 +468,12 @@ int pacman_query(alpm_list_t *targets)
continue;
}
+
if(filter(pkg)) {
display(pkg);
+ if(config->op_q_verify){
+ pkgs = alpm_list_add(pkgs, pkg);
+ }
}
if(config->op_q_isfile) {
@@ -415,6 +481,9 @@ int pacman_query(alpm_list_t *targets)
pkg = NULL;
}
}
+ if(config->op_q_verify){
+ verify(pkgs);
+ }
return(ret);
}
--
1.6.2.1
Créez votre adresse électronique prenom.nom at laposte.net
1 Go d'espace de stockage, anti-spam et anti-virus intégrés.
More information about the pacman-dev
mailing list