[pacman-dev] [PATCH v3] Allow querying directory ownership
Andrew Gregory
andrew.gregory.8 at gmail.com
Tue May 22 11:22:21 EDT 2012
From: Andrew Gregory <andrew.gregory.8 at gmail.com>
---
I did this as a patch against your working branch since it requires
changes outside the scope of your original patch. This adds a check
that all files/directories are within root before we bother looking for
an owner which removes the need for a special check just for '/'. I
didn't test this extensively, but it handled `./pacman -Qo /
firefox /usr/bin/firefox /tmp /tmp/` correctly.
src/pacman/query.c | 51 +++++++++++++++++++++++++++------------------------
src/pacman/util.c | 4 ++++
2 files changed, 31 insertions(+), 24 deletions(-)
diff --git a/src/pacman/query.c b/src/pacman/query.c
index 67dd11c..d99d5df 100644
--- a/src/pacman/query.c
+++ b/src/pacman/query.c
@@ -109,7 +109,7 @@ static int query_fileowner(alpm_list_t *targets)
{
int ret = 0;
char path[PATH_MAX];
- const char *root;
+ char *root;
size_t rootlen;
alpm_list_t *t;
alpm_db_t *db_local;
@@ -124,9 +124,15 @@ 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);
+ /* I don't know if we can assume that root doesn't contain symlinks,
+ * if not we should go ahead and resolve it */
+ root = strdup(resolve_path(alpm_option_get_root(config->handle)));
rootlen = strlen(root);
- if(rootlen + 1 > PATH_MAX) {
+ if(root[rootlen - 1] != '/' && rootlen + 1 < PATH_MAX){
+ strcat(root, "/");
+ rootlen++;
+ }
+ if(rootlen + 1 > PATH_MAX || root[rootlen - 1] != '/') {
/* we are in trouble here */
pm_printf(ALPM_LOG_ERROR, _("path too long: %s%s\n"), root, "");
return 1;
@@ -177,32 +183,28 @@ static int query_fileowner(alpm_list_t *targets)
bname_len = strlen(bname);
dname = mdirname(filename);
- /* for files in '/', there is no directory name to match */
- if(strcmp(dname, "") == 0) {
- rpath = NULL;
- } else {
- rpath = resolve_path(dname);
+ rpath = resolve_path(dname);
- if(!rpath) {
- pm_printf(ALPM_LOG_ERROR, _("cannot determine real path for '%s': %s\n"),
- filename, strerror(errno));
- free(dname);
- ret++;
- goto cleanup;
- }
+ if(!rpath) {
+ pm_printf(ALPM_LOG_ERROR, _("cannot determine real path for '%s': %s\n"),
+ dname, strerror(errno));
+ free(dname);
+ ret++;
+ goto cleanup;
}
free(dname);
+ if(strstr(root, rpath) && *bname == '\0') {
+ /* path is either outside root or *is* root */
+ pm_printf(ALPM_LOG_ERROR, _("cannot determine ownership of file outside root directory\n"));
+ ret++;
+ goto cleanup;
+ }
+
if(isdir) {
- if(!rpath) {
- pm_printf(ALPM_LOG_ERROR, _("cannot determine ownership of root directory\n"));
- ret++;
- goto cleanup;
- } else {
- rpath_len = strlen(rpath);
- rpath_bname = mbasename(rpath);
- rpath_bname_len = strlen(rpath_bname);
- }
+ rpath_len = strlen(rpath);
+ rpath_bname = mbasename(rpath);
+ rpath_bname_len = strlen(rpath_bname);
}
for(i = packages; i && (!found || isdir); i = alpm_list_next(i)) {
@@ -276,6 +278,7 @@ cleanup:
free(filename);
free(rpath);
}
+ free(root);
return ret;
}
diff --git a/src/pacman/util.c b/src/pacman/util.c
index 7f7f6a7..1914b70 100644
--- a/src/pacman/util.c
+++ b/src/pacman/util.c
@@ -242,6 +242,10 @@ char *mdirname(const char *path)
ret = strdup(path);
last = strrchr(ret, '/');
+ if(last == ret){
+ free(ret);
+ return strdup("/");
+ }
if(last != NULL) {
/* we found a '/', so terminate our string */
*last = '\0';
--
1.7.10.2
More information about the pacman-dev
mailing list