[pacman-dev] [PATCH] New feature: files verification

Dan McGee dpmcgee at gmail.com
Sun Mar 29 18:22:15 EDT 2009


On Sun, Mar 29, 2009 at 4:19 PM, Dan McGee <dpmcgee at gmail.com> wrote:
> On Sun, Mar 29, 2009 at 3:50 PM, changaco <changaco at laposte.net> wrote:
>
>> Here's the new patch:

I made a few changes of my own to your patch, I'll throw them in below
just as an FYI.

The biggest change was killing snprintf() as that was the bottleneck
when looping files. This is now fast as heck when all file inodes are
in the kernel cache. I also converted your // comments to the /* */
style, which is all we use in the codebase.

dmcgee at galway ~/projects/pacman (master)
$ time ./src/pacman/.libs/lt-pacman -Qk
filesystem: Missing file /var/games/
Check complete: 181758 files (693 packages)
Damaged packages: filesystem

real	0m0.583s
user	0m0.113s
sys	0m0.413s

$ git diff | cat
diff --git a/src/pacman/query.c b/src/pacman/query.c
index 6ec58f5..db29fe0 100644
--- a/src/pacman/query.c
+++ b/src/pacman/query.c
@@ -342,13 +342,27 @@ static void check_display_progress(int j, int
pkgs_n, const char *pkgname){
 	fflush(stderr);
 }

-// We loop through the packages and for each packages we loop through
files to check if they exist
+/* Loop through the packages. For each package,
+ * loop through files to check if they exist. */
 static void check(alpm_list_t *pkgs)
 {
 	alpm_list_t *i, *files, *file, *damaged = NULL;
 	pmpkg_t *pkg;
-	int pkgs_n = alpm_list_count(pkgs);
-	int j = 0, allfiles = 0;
+	const char *root;
+	int pkgs_n, j = 0, allfiles = 0;
+	size_t rootlen;
+	char f[PATH_MAX];
+
+	pkgs_n = alpm_list_count(pkgs);
+	root = alpm_option_get_root();
+	rootlen = strlen(root);
+	if(rootlen + 1 > PATH_MAX) {
+		/* we are in trouble here */
+		pm_printf(PM_LOG_ERROR, _("root path too long\n"));
+		return;
+	}
+	strcpy(f, root);
+
 	for(i = pkgs; i; i = alpm_list_next(i)) {
 		j++;
 		pkg = alpm_list_getdata(i);
@@ -361,13 +375,14 @@ static void check(alpm_list_t *pkgs)
 			for(file = files; file; file = alpm_list_next(file)){
 				struct stat st;
 				char *x = alpm_list_getdata(file);
-				char f[PATH_MAX];
-				snprintf(f, PATH_MAX, "%s%s", alpm_option_get_root(), x);
-				allfiles++;
-				if(strncmp(f, "/tmp", 4)==0){
-					continue; // ignore files in /tmp
+				if(rootlen + 1 + strlen(x) > PATH_MAX) {
+					pm_printf(PM_LOG_WARNING, _("file path too long\n"));
+					continue;
 				}
-				if(lstat(f,&st) != 0) { // we use lstat to prevent errors from
symbolic links
+				strcpy(f + rootlen, x);
+				allfiles++;
+				/* use lstat to prevent errors from symlinks */
+				if(lstat(f, &st) != 0) {
 					if(config->quiet) {
 						fprintf(stderr, "%s %s\n", pkgname, f);
 						fflush(stderr);
@@ -377,7 +392,7 @@ static void check(alpm_list_t *pkgs)
 						fflush(stderr);
 					}
 					if(alpm_list_find_ptr(damaged, pkgname) == NULL) {
-						damaged = alpm_list_add(damaged, (void*)pkgname);
+						damaged = alpm_list_add(damaged, (char*)pkgname);
 					}
 				}
 			}
@@ -385,7 +400,8 @@ static void check(alpm_list_t *pkgs)
 	}
 	if(!config->quiet) {
 		char message[getcols()];
-		int len = snprintf(message, getcols(), "\r%s: %i %s (%i %s)\n",
_("Check complete"), allfiles, _("files"), pkgs_n, _("packages"));
+		int len = snprintf(message, getcols(), "\r%s: %i %s (%i %s)\n",
+				_("Check complete"), allfiles, _("files"), pkgs_n, _("packages"));
 		fprintf(stderr, "\r%s %*s", message, getcols()-len-1, " ");
 		fflush(stderr);
 	}
@@ -401,7 +417,7 @@ static void check(alpm_list_t *pkgs)
 		fflush(stdout);
 	}

-	FREELIST(damaged);
+	alpm_list_free(damaged);
 }

 int pacman_query(alpm_list_t *targets)
@@ -482,8 +498,7 @@ int pacman_query(alpm_list_t *targets)
 		if(filter(pkg)) {
 			if(config->op_q_check){
 				pkgs = alpm_list_add(pkgs, pkg);
-			}
-			else{
+			} else {
 				display(pkg);
 			}
 		}
@@ -493,11 +508,12 @@ int pacman_query(alpm_list_t *targets)
 			pkg = NULL;
 		}
 	}
+
 	if(config->op_q_check){
 		check(pkgs);
+		alpm_list_free(pkgs);
 	}

-	FREELIST(pkgs);

 	return(ret);
 }


More information about the pacman-dev mailing list