Date: Sun, 25 Feb 2001 03:56:26 -0500 From: Garrett Rooney <rooneg@electricjellyfish.net> To: Jordan Hubbard <jkh@osd.bsdi.com> Cc: ports@freebsd.org, jhk@freebsd.org, sobomax@freebsd.org, gad@freebsd.org Subject: Re: [patch] which package functionality for pkg_info Message-ID: <20010225035626.H52692@electricjellyfish.net> In-Reply-To: <20010224234820P.jkh@osd.bsdi.com>; from jkh@osd.bsdi.com on Sat, Feb 24, 2001 at 11:48:20PM -0800 References: <20010225001624.A41801@electricjellyfish.net> <20010224234016X.jkh@osd.bsdi.com> <20010224234820P.jkh@osd.bsdi.com>
next in thread | previous in thread | raw e-mail | index | archive | help
--0F1p//8PRICkK4MW Content-Type: text/plain; charset=us-ascii Content-Disposition: inline here's an updated patch, which gives us back some of the functionality i was trying to get from realpath(3). it recognizes a relative path by checking for a / at the beginning of the filename, and if it isn't there, it assumes the simple case and just tacks the current working directory on to the beginning of the file. perhaps something more robust, taking into account extra /'s, .., and . is in order, but it's 4:00 in the morning, and my laundry is finally dry, so i'm going to sleep ;-) -- 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. --0F1p//8PRICkK4MW Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="pkg_info.patch" Index: info.h =================================================================== RCS file: /usr/local/cvs/src/usr.sbin/pkg_install/info/info.h,v retrieving revision 1.17 diff -u -r1.17 info.h --- info.h 2001/02/08 17:43:59 1.17 +++ info.h 2001/02/25 08:04:46 @@ -1,4 +1,4 @@ -/* $FreeBSD$ */ +/* $FreeBSD: src/usr.sbin/pkg_install/info/info.h,v 1.17 2001/02/08 17:43:59 sobomax Exp $ */ /* * FreeBSD install - a package for the installation and maintainance @@ -58,6 +58,7 @@ extern char *InfoPrefix; extern char PlayPen[]; extern char *CheckPkg; +extern char *CheckFile; extern match_t MatchType; extern void show_file(char *, char *); Index: main.c =================================================================== RCS file: /usr/local/cvs/src/usr.sbin/pkg_install/info/main.c,v retrieving revision 1.29 diff -u -r1.29 main.c --- main.c 2001/02/08 17:44:00 1.29 +++ main.c 2001/02/25 08:04:46 @@ -28,7 +28,7 @@ "$FreeBSD$"; #endif -static char Options[] = "acdDe:fgGhiIkl:LmopqrRst:vx"; +static char Options[] = "acdDe:fgGhiIkl:LmopqrRst:vw:x"; int Flags = 0; match_t MatchType = MATCH_GLOB; @@ -36,6 +36,7 @@ char *InfoPrefix = ""; char PlayPen[FILENAME_MAX]; char *CheckPkg = NULL; +char *CheckFile = NULL; static void usage __P((void)); @@ -148,6 +149,10 @@ CheckPkg = optarg; break; + case 'w': + CheckFile = optarg; + break; + case 'h': case '?': default: @@ -185,7 +190,7 @@ } /* If no packages, yelp */ - if (pkgs == start && MatchType != MATCH_ALL && !CheckPkg) + if (pkgs == start && MatchType != MATCH_ALL && !CheckPkg && !CheckFile) warnx("missing package name(s)"), usage(); *pkgs = NULL; return pkg_perform(start); @@ -196,7 +201,7 @@ { fprintf(stderr, "%s\n%s\n%s\n", "usage: pkg_info [-cdDfiIkLmopqrRsv] [-e package] [-l prefix]", - " [-t template] [pkg-name ...]", + " [-t template] [-w filename] [pkg-name ...]", " pkg_info -a [flags]"); exit(1); } Index: perform.c =================================================================== RCS file: /usr/local/cvs/src/usr.sbin/pkg_install/info/perform.c,v retrieving revision 1.34 diff -u -r1.34 perform.c --- perform.c 2001/02/08 17:44:00 1.34 +++ perform.c 2001/02/25 08:47:43 @@ -27,6 +27,10 @@ #include "info.h" #include <sys/types.h> +#include <sys/param.h> +#include <sys/stat.h> +#include <stdlib.h> +#include <errno.h> #include <err.h> #include <glob.h> #include <fts.h> @@ -36,6 +40,8 @@ static int fname_cmp(const FTSENT **, const FTSENT **); static int pkg_do(char *); static int rexs_match(char **, char *); +static int find_pkg(char *, char *); +static int cmp_path(const char *, const char *, const char *); int pkg_perform(char **pkgs) @@ -55,6 +61,8 @@ snprintf(buf, FILENAME_MAX, "%s/%s", tmp, CheckPkg); return abs(access(buf, R_OK)); /* Not reached */ + } else if (CheckFile) { + return find_pkg(tmp, CheckFile); } switch (MatchType) { @@ -352,4 +360,137 @@ regfree(&rex); return retval; +} + +/* comparison to see if two paths we're on matches the one we're looking for. */ +static int +cmp_path(const char *target, const char *current, const char *cwd) { + + char *fixed_path; + char *temp; + char *itr1; + char *itr2; + int cwd_len, current_len, total_len, rval; + + cwd_len = strlen(cwd); + current_len = strlen(current); + total_len = cwd_len + current_len + 2; + temp = calloc(total_len, sizeof(char *)); + fixed_path = calloc(total_len, sizeof(char *)); + if (temp == NULL || fixed_path == NULL) { + errx(2, "out of memory\n"); + } + strncpy(temp, cwd, cwd_len); + strncat(temp, "/", 1); + strncat(temp, current, current_len); + + /* make sure there's no multiple /'s, since some plists seem to have them + * and it could screw up our strncmp. */ + for (itr1 = temp, itr2 = fixed_path; *itr1 != '\0'; itr1++) { + *itr2 = *itr1; + if (*itr2 == '/') { + if (*(itr1 + 1) != '/') + itr2++; + } else + itr2++; + } + + if (!strncmp(target, fixed_path, strlen(target))) + rval = 1; + else + rval = 0; + free(temp); + free(fixed_path); + return rval; +} + +/* look through package dbs in db_dir and find which package installed file */ +static int +find_pkg(char *db_dir, char *file) +{ + FTS *ftsp; + FTSENT *entp; + char *dir[2]; + char *res_file; + struct stat st; + + if (stat(file, &st) == -1) + errx(2, strerror(errno)); + + /* if file doesn't start with a /, it's a relative path. this will handle + * something simple (pkg_info -w foo/bar) but it doesn't try and deal with + * .. or . or extra slashes. */ + if (strncmp(file, "/", 1)) { + char *buf; + char *curdir; + int file_len, dir_len; + + buf = calloc(MAXPATHLEN, sizeof(char)); + curdir = getcwd(buf, MAXPATHLEN); + + file_len = strlen(file); + dir_len = strlen(curdir); + + res_file = calloc(file_len + dir_len + 2, sizeof(char)); + if (res_file == NULL) + errx(2, strerror(errno)); + + strncpy(res_file, curdir, dir_len); + strncat(res_file, "/", 1); + strncat(res_file, file, file_len); + + free(buf); + } else + res_file = file; + + dir[0] = db_dir; + dir[1] = NULL; + + ftsp = fts_open(dir, FTS_LOGICAL | FTS_NOCHDIR | FTS_NOSTAT, fname_cmp); + + if (ftsp != NULL) { + while((entp = fts_read(ftsp)) != NULL) { + if (entp->fts_level == 1 && entp->fts_info == FTS_D) { + Package pkg; + PackingList itr; + FILE *fp; + char buf[FILENAME_MAX]; + char *cwd = NULL; + + bzero(buf, FILENAME_MAX); + strncpy(buf, entp->fts_path, strlen(entp->fts_path)); + strncat(buf, "/", 1); + strncat(buf, CONTENTS_FNAME, strlen(CONTENTS_FNAME)); + + fp = fopen(buf, "r"); + if (fp) { + read_plist(&pkg, fp); + for (itr = pkg.head; itr != pkg.tail; itr = itr->next) { + if (itr->type == PLIST_CWD) { + cwd = itr->name; + } else if (itr->type == PLIST_FILE) { + if (cmp_path(res_file, itr->name, cwd)) { + fprintf(stdout, + "%s is from package %s\n", + CheckFile, + entp->fts_name); + if (strncmp(file, "/", 1)) + free(res_file); + free_plist(&pkg); + fclose(fp); + fts_close(ftsp); + return 1; + } + } + } + free_plist(&pkg); + fclose(fp); + } + } + } + } + if (strncmp(file, "/", 1)) + free(res_file); + fts_close(ftsp); + return 0; } Index: pkg_info.1 =================================================================== RCS file: /usr/local/cvs/src/usr.sbin/pkg_install/info/pkg_info.1,v retrieving revision 1.37 diff -u -r1.37 pkg_info.1 --- pkg_info.1 2001/02/20 21:57:19 1.37 +++ pkg_info.1 2001/02/25 08:04:46 @@ -25,10 +25,11 @@ .Nd a utility for displaying information on software packages .Sh SYNOPSIS .Nm -.Op Fl cdDfgGiIkLmopqrRsvx +.Op Fl cdDfgGiIkLmopqrRsvwx .Op Fl e Ar package .Op Fl l Ar prefix .Op Fl t Ar template +.Op Fl w Ar filename .Op Ar pkg-name ... .Nm .Fl a @@ -105,6 +106,10 @@ .Nm automatically expands shell glob patterns in the .Ar pkg-name ) . +.It Fl w +For the specified +.Ar filename +argument, show which package(s) it belongs to. .It Fl x Treat the .Ar pkg-name --0F1p//8PRICkK4MW-- 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?20010225035626.H52692>