From owner-freebsd-ports Fri Mar 23 16:52:31 2001 Delivered-To: freebsd-ports@freebsd.org Received: from isris.pair.com (isris.pair.com [209.68.2.39]) by hub.freebsd.org (Postfix) with SMTP id AA90E37B71A for ; Fri, 23 Mar 2001 16:52:20 -0800 (PST) (envelope-from rooneg@isris.pair.com) Received: (qmail 71260 invoked by uid 3130); 24 Mar 2001 00:52:19 -0000 Date: Fri, 23 Mar 2001 19:52:19 -0500 From: Garrett Rooney To: Maxim Sobolev Cc: Jordan Hubbard , 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> References: <20010323173301.A52371@electricjellyfish.net> <200103232350.f2NNo5H01267@vic.sabbo.net> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="PEIAKu/WMn1b1Hv9" Content-Disposition: inline User-Agent: Mutt/1.2.5i In-Reply-To: <200103232350.f2NNo5H01267@vic.sabbo.net>; from sobomax@freebsd.org on Sat, Mar 24, 2001 at 01:50:00AM +0200 Sender: owner-freebsd-ports@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.org --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