From 7c0348fa499f55968764fef4c7bb3d3d7245932b Mon Sep 17 00:00:00 2001
From: Charly COSTE <[email protected]>
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 <[email protected]>
---
 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 [email protected] 
 1 Go d'espace de stockage, anti-spam et anti-virus intégrés.
_______________________________________________
pacman-dev mailing list
[email protected]
http://www.archlinux.org/mailman/listinfo/pacman-dev

Reply via email to