On Sun, Mar 29, 2009 at 4:19 PM, Dan McGee <dpmcgee@gmail.com> wrote:
On Sun, Mar 29, 2009 at 3:50 PM, changaco <changaco@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@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); }