diff options
author | Andrew Gregory <andrew.gregory.8@gmail.com> | 2012-07-26 07:01:50 +0200 |
---|---|---|
committer | Dan McGee <dan@archlinux.org> | 2012-09-18 15:24:02 +0200 |
commit | 140c76d3288b41773411534638305dc8b5928951 (patch) | |
tree | 3130ea4083808311daed3ab0d0763e6b1344e8ee | |
parent | 9648887481c7ad56ef9f7eb2d2810eb6ec32b5be (diff) | |
download | pacman-140c76d3288b41773411534638305dc8b5928951.tar.gz pacman-140c76d3288b41773411534638305dc8b5928951.tar.xz |
query_fileowner: resolve root early
Resolving root early prevents later calls to realpath from having to do the
work of actually resolving any symlinks in root.
Signed-off-by: Andrew Gregory <andrew.gregory.8@gmail.com>
Signed-off-by: Dan McGee <dan@archlinux.org>
-rw-r--r-- | src/pacman/query.c | 34 |
1 files changed, 25 insertions, 9 deletions
diff --git a/src/pacman/query.c b/src/pacman/query.c index 725e35d9..176f91c2 100644 --- a/src/pacman/query.c +++ b/src/pacman/query.c @@ -94,7 +94,6 @@ static int query_fileowner(alpm_list_t *targets) { int ret = 0; char path[PATH_MAX]; - const char *root; size_t rootlen; alpm_list_t *t; alpm_db_t *db_local; @@ -108,14 +107,24 @@ static int query_fileowner(alpm_list_t *targets) /* Set up our root path buffer. We only need to copy the location of root in * once, then we can just overwrite whatever file was there on the previous * iteration. */ - 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, ""); + + /* resolve root now so any symlinks in it will only have to be resolved once */ + if(!realpath(alpm_option_get_root(config->handle), path)) { + pm_printf(ALPM_LOG_ERROR, _("cannot determine real path for '%s': %s\n"), + path, strerror(errno)); return 1; } - strcpy(path, root); + + /* make sure there's enough room to append the package file to path */ + rootlen = strlen(path); + if(rootlen + 2 > PATH_MAX) { + pm_printf(ALPM_LOG_ERROR, _("path too long: %s%s\n"), path, ""); + return 1; + } + + /* append trailing '/' removed by realpath */ + path[rootlen++] = '/'; + path[rootlen] = '\0'; db_local = alpm_get_localdb(config->handle); @@ -201,7 +210,7 @@ static int query_fileowner(alpm_list_t *targets) } if(rootlen + 1 + strlen(pkgfile) > PATH_MAX) { - pm_printf(ALPM_LOG_ERROR, _("path too long: %s%s\n"), root, pkgfile); + pm_printf(ALPM_LOG_ERROR, _("path too long: %s%s\n"), path, pkgfile); continue; } /* concatenate our file and the root path */ @@ -210,8 +219,15 @@ static int query_fileowner(alpm_list_t *targets) pdname = mdirname(path); ppath = realpath(pdname, NULL); free(pdname); + path[rootlen] = '\0'; /* reset path for error messages */ + + if(!ppath) { + pm_printf(ALPM_LOG_ERROR, _("cannot determine real path for '%s': %s\n"), + pdname, strerror(errno)); + continue; + } - if(ppath && strcmp(ppath, rpath) == 0) { + if(strcmp(ppath, rpath) == 0) { print_query_fileowner(filename, info); found = 1; free(ppath); |