Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 23 Mar 2001 19:52:19 -0500
From:      Garrett Rooney <rooneg@electricjellyfish.net>
To:        Maxim Sobolev <sobomax@freebsd.org>
Cc:        Jordan Hubbard <jkh@osd.bsdi.com>, ports@freebsd.org
Subject:   Re: cvs commit: src/usr.sbin/pkg_install/info info.h main.c perform.c         pkg_info.1 show.c src/usr.sbin/pkg_install/lib depOR
Message-ID:  <20010323195218.A68799@electricjellyfish.net>
In-Reply-To: <200103232350.f2NNo5H01267@vic.sabbo.net>; from sobomax@freebsd.org on Sat, Mar 24, 2001 at 01:50:00AM %2B0200
References:  <20010323173301.A52371@electricjellyfish.net> <200103232350.f2NNo5H01267@vic.sabbo.net>

next in thread | previous in thread | raw e-mail | index | archive | help

--PEIAKu/WMn1b1Hv9
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

On Sat, Mar 24, 2001 at 01:50:00AM +0200, Maxim Sobolev wrote:
> Following piece of code should solve this problem. It basically does
> what the realpath(3) does, but doesn't try to resolve symlinks, which
> as far as I unrestood is the main problem here. Actually it could
> be modified to take two components (cwd and relative pathname), so
> we will handle ../ and ./ in PLISTS properly.

Very nice Maxim, that does everything i was thinking of but hadn't gotten
around to yet ;-)

Attached is a patch to use your code in cmp_path() (to handle odd things in
the PLISTS) and find_pkg() to resolve the file specified on the command line.

-garrett

-- 
garrett rooney                     Unix was not designed to stop you from 
rooneg@electricjellyfish.net       doing stupid things, because that would  
http://electricjellyfish.net/      stop you from doing clever things.

--PEIAKu/WMn1b1Hv9
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="pkg_info.diff"

Index: perform.c
===================================================================
RCS file: /usr/local/cvs/src/usr.sbin/pkg_install/info/perform.c,v
retrieving revision 1.37
diff -u -r1.37 perform.c
--- perform.c	2001/03/23 18:45:24	1.37
+++ perform.c	2001/03/24 00:47:55
@@ -243,13 +243,55 @@
 }
 
 /*
+ * resolve a path, removing all .'s, ..'s, and extraneous /'s, as realpath() 
+ * would, but without resolving symlinks, because that can potentially screw 
+ * up our comparisons later.
+ */
+char *
+resolve_path(const char *pathname)
+{
+    char *cwd, *tmp, *tmp1;
+    char *resolved_path;
+    int len;
+
+    if (pathname[0] != '/') {
+	cwd = getcwd(NULL, MAXPATHLEN);
+	asprintf(&resolved_path, "%s/%s/", cwd, pathname);
+	free(cwd);
+    } else
+	asprintf(&resolved_path, "%s/", pathname);
+
+    if (resolved_path == NULL)
+	errx(2, NULL);
+
+    while ((tmp = strstr(resolved_path, "//")) != NULL)
+	strcpy(tmp, tmp + 1);
+ 
+    while ((tmp = strstr(resolved_path, "/./")) != NULL)
+	strcpy(tmp, tmp + 2);
+ 
+    while ((tmp = strstr(resolved_path, "/../")) != NULL) {
+	*tmp = '\0';
+	if ((tmp1 = strrchr(resolved_path, '/')) == NULL)
+	    tmp1 = resolved_path;
+	strcpy(tmp1, tmp + 3);
+    }
+
+    len = strlen(resolved_path);
+    if (len > 1 && resolved_path[len - 1] == '/')
+	resolved_path[len - 1] = '\0';
+
+    return resolved_path;
+}
+
+/*
  * Comparison to see if the path we're on matches the
  * one we are looking for.
  */
 static int
 cmp_path(const char *target, const char *current, const char *cwd) 
 {
-    char *loc, *temp;
+    char *loc, *temp, *resolved;
     int rval;
 
     asprintf(&temp, "%s/%s", cwd, current);
@@ -257,18 +299,18 @@
         errx(2, NULL);
 
     /*
-     * Make sure there's no multiple /'s, since some plists
-     * seem to have them and it could screw up our strncmp.
+     * Make sure there's no multiple /'s or other weird things in the PLIST, 
+     * since some plists seem to have them and it could screw up our strncmp.
      */
-    while ((loc = strstr(temp, "//")) != NULL)
-	strcpy(loc, loc + 1);
+    resolved = resolve_path(temp);
 
-    if (strcmp(target, temp) == 0)
+    if (strcmp(target, resolved) == 0)
 	rval = 1;
     else
 	rval = 0;
 
     free(temp);
+    free(resolved);
     return rval;
 }
 
@@ -300,23 +342,10 @@
 		wp->skip = TRUE;
 	    }
 	} else if (wp->file[0] != '/') {
-	    /*
-	     * If it is a file, and it doesn't start with a /, then it's a 
-	     * relative path.  in order to give us some chance of getting a 
-	     * successful match, tack the current working directory on the 
-	     * beginning.  this won't work for filenames that include .. or . 
-	     * or extra /'s, but it's better than nothing).
-	     */
-	    char *curdir, *tmp;
-
-	    curdir = getcwd(NULL, PATH_MAX);
-	    if (curdir == NULL)
-		err(2, NULL);
-
-	    asprintf(&tmp, "%s/%s", curdir, wp->file);
-	    if (tmp == NULL)
-		err(2, NULL);
-
+	    char *tmp;
+	    
+	    tmp = resolve_path(wp->file);
+	    
 	    if (!isfile(tmp)) {
 		warnx("%s: file cannot be found", tmp);
 		wp->skip = TRUE;
@@ -324,7 +353,6 @@
 		strlcpy(wp->file, tmp, PATH_MAX);
 
 	    free(tmp);
-	    free(curdir);
 	}
     }
 

--PEIAKu/WMn1b1Hv9--

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-ports" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20010323195218.A68799>