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>