[pacman-dev] [PATCH] FS#8798 - Allow -Qo to perform a functional 'which'

Jatheendra jatheendra at gmail.com
Wed Nov 5 11:13:32 EST 2008


Hi all,

This is a simple patch to add a "which" like functionality to pacman
-Qo[Bug FS#8798]. This is my first patch ,so any constructive
criticism is most welcome.

Thanks,
Shankar

---
 src/pacman/query.c |   62 +++++++++++++++++++++++++++++++++++++++++++++++----
 1 files changed, 57 insertions(+), 5 deletions(-)

diff --git a/src/pacman/query.c b/src/pacman/query.c
index 0d48638..fb3bb92 100644
--- a/src/pacman/query.c
+++ b/src/pacman/query.c
@@ -55,6 +55,43 @@ static char *resolve_path(const char* file)
 	return(str);
 }

+/* check if filename exists in PATH */
+static int search_path(char *filename, struct stat * bufptr)
+{
+	char *envpath, *path, *fullname;
+	int len;
+
+	if ((envpath = getenv("PATH")) == NULL) {
+		return(-1);
+	}
+
+	if ((envpath = strdup(envpath)) == NULL) {
+		return(-1);
+	}
+	
+	fullname = calloc(PATH_MAX+1, sizeof(char));
+
+	while ((path = strsep(&envpath, ":")) != NULL) {
+			len = strlen(path);
+
+			/* strip trailing '/' */
+			while (path[len-1] == '/') {
+					path[--len] = '\0';
+			}
+			
+			snprintf(fullname, PATH_MAX+1, "%s/%s", path, filename);
+
+			if(stat(fullname,bufptr) == 0) {
+				strncpy(filename,fullname,PATH_MAX+1);
+				free(fullname);
+				return(0);
+			}
+	}
+	free(fullname);
+	return(-1);
+}
+
+
 static int query_fileowner(alpm_list_t *targets)
 {
 	int ret = 0;
@@ -66,21 +103,35 @@ static int query_fileowner(alpm_list_t *targets)
 		return(1);
 	}

+	char *filename = calloc(PATH_MAX+1, sizeof(char));
+
 	for(t = targets; t; t = alpm_list_next(t)) {
 		int found = 0;
-		char *filename = alpm_list_getdata(t);
+		strncpy(filename,alpm_list_getdata(t),PATH_MAX+1);
+
 		char *bname, *dname, *rpath;
 		const char *root;
 		struct stat buf;
 		alpm_list_t *i, *j;

 		if(stat(filename, &buf) == -1) {
-			pm_fprintf(stderr, PM_LOG_ERROR, _("failed to read file '%s': %s\n"),
-					filename, strerror(errno));
-			ret++;
-			continue;
+			/*  if it is not a path but a program name, then check in PATH */
+			if(strchr(filename,'/') == NULL) {
+				if((search_path(filename,&buf)) == -1) {
+					pm_fprintf(stderr, PM_LOG_ERROR, _("failed to read file '%s': %s\n"),
+							filename, strerror(errno));
+					ret++;
+					continue;
+				}
+			} else {
+				pm_fprintf(stderr, PM_LOG_ERROR, _("failed to read file '%s': %s\n"),
+						filename, strerror(errno));
+				ret++;
+				continue;
+			}
 		}

+
 		if(S_ISDIR(buf.st_mode)) {
 			pm_fprintf(stderr, PM_LOG_ERROR,
 				_("cannot determine ownership of a directory\n"));
@@ -140,6 +191,7 @@ static int query_fileowner(alpm_list_t *targets)
 		free(rpath);
 	}

+	free(filename);
 	return ret;
 }

-- 
1.6.0.2



More information about the pacman-dev mailing list