From owner-freebsd-ports Sun Feb 25 0:56:36 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 1AF9537B503 for ; Sun, 25 Feb 2001 00:56:27 -0800 (PST) (envelope-from rooneg@isris.pair.com) Received: (qmail 58184 invoked by uid 3130); 25 Feb 2001 08:56:26 -0000 Date: Sun, 25 Feb 2001 03:56:26 -0500 From: Garrett Rooney To: Jordan Hubbard 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> References: <20010225001624.A41801@electricjellyfish.net> <20010224234016X.jkh@osd.bsdi.com> <20010224234820P.jkh@osd.bsdi.com> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="0F1p//8PRICkK4MW" Content-Disposition: inline User-Agent: Mutt/1.2.5i In-Reply-To: <20010224234820P.jkh@osd.bsdi.com>; from jkh@osd.bsdi.com on Sat, Feb 24, 2001 at 11:48:20PM -0800 Sender: owner-freebsd-ports@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.org --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 +#include +#include +#include +#include #include #include #include @@ -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