Skip site navigation (1)Skip section navigation (2)
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>