summaryrefslogtreecommitdiffstats
path: root/usr.sbin/pkg_install
diff options
context:
space:
mode:
authorsobomax <sobomax@FreeBSD.org>2001-03-23 18:45:24 +0000
committersobomax <sobomax@FreeBSD.org>2001-03-23 18:45:24 +0000
commitaf0ef4a0618c8bc04852f5517a94e7bb9cf23a79 (patch)
tree7199089cfce7e2607cf0b53bfce882718f758082 /usr.sbin/pkg_install
parente22250630ad78bc0b2b6b8f7b7eef84c54dcc10a (diff)
downloadFreeBSD-src-af0ef4a0618c8bc04852f5517a94e7bb9cf23a79.zip
FreeBSD-src-af0ef4a0618c8bc04852f5517a94e7bb9cf23a79.tar.gz
- Add which(1)-like functionality into pkg_info;
- fix a harmless bug in match_installed() function introduced in my last commit; - uniformely reorder includes across files. Submitted by: Garrett Rooney <rooneg@electricjellyfish.net> Not objected by: jkh, -ports
Diffstat (limited to 'usr.sbin/pkg_install')
-rw-r--r--usr.sbin/pkg_install/info/info.h11
-rw-r--r--usr.sbin/pkg_install/info/main.c29
-rw-r--r--usr.sbin/pkg_install/info/perform.c160
-rw-r--r--usr.sbin/pkg_install/info/pkg_info.19
-rw-r--r--usr.sbin/pkg_install/info/show.c1
-rw-r--r--usr.sbin/pkg_install/lib/deps.c1
-rw-r--r--usr.sbin/pkg_install/lib/exec.c49
-rw-r--r--usr.sbin/pkg_install/lib/lib.h2
-rw-r--r--usr.sbin/pkg_install/lib/match.c21
-rw-r--r--usr.sbin/pkg_install/lib/msg.c2
-rw-r--r--usr.sbin/pkg_install/lib/pen.c2
-rw-r--r--usr.sbin/pkg_install/lib/str.c19
12 files changed, 283 insertions, 23 deletions
diff --git a/usr.sbin/pkg_install/info/info.h b/usr.sbin/pkg_install/info/info.h
index 2356a7e..8db99ed 100644
--- a/usr.sbin/pkg_install/info/info.h
+++ b/usr.sbin/pkg_install/info/info.h
@@ -23,6 +23,8 @@
#ifndef _INST_INFO_H_INCLUDE
#define _INST_INFO_H_INCLUDE
+#include <sys/queue.h>
+
#ifndef MAXINDEXSIZE
#define MAXINDEXSIZE 59
#endif
@@ -47,12 +49,21 @@
#define SHOW_ORIGIN 0x2000
#define SHOW_CKSUM 0x4000
+struct which_entry {
+ TAILQ_ENTRY(which_entry) next;
+ char file[PATH_MAX];
+ char package[PATH_MAX];
+ Boolean skip;
+};
+TAILQ_HEAD(which_head, which_entry);
+
extern int Flags;
extern Boolean Quiet;
extern char *InfoPrefix;
extern char PlayPen[];
extern char *CheckPkg;
extern match_t MatchType;
+extern struct which_head *whead;
extern void show_file(char *, char *);
extern void show_plist(char *, Package *, plist_t);
diff --git a/usr.sbin/pkg_install/info/main.c b/usr.sbin/pkg_install/info/main.c
index aa39a5f..ac99584 100644
--- a/usr.sbin/pkg_install/info/main.c
+++ b/usr.sbin/pkg_install/info/main.c
@@ -19,16 +19,16 @@
*
*/
-#include <err.h>
#include "lib.h"
#include "info.h"
+#include <err.h>
#ifndef lint
static const char rcsid[] =
"$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 @@ Boolean Quiet = FALSE;
char *InfoPrefix = "";
char PlayPen[FILENAME_MAX];
char *CheckPkg = NULL;
+struct which_head *whead;
static void usage __P((void));
@@ -46,6 +47,11 @@ main(int argc, char **argv)
char **pkgs, **start;
char *pkgs_split;
+ whead = malloc(sizeof(struct which_head));
+ if (whead == NULL)
+ err(2, NULL);
+ TAILQ_INIT(whead);
+
pkgs = start = argv;
if (argc == 1) {
MatchType = MATCH_ALL;
@@ -148,6 +154,20 @@ main(int argc, char **argv)
CheckPkg = optarg;
break;
+ case 'W':
+ {
+ struct which_entry *entp;
+
+ entp = calloc(1, sizeof(struct which_entry));
+ if (entp == NULL)
+ err(2, NULL);
+
+ strlcpy(entp->file, optarg, PATH_MAX);
+ entp->skip = FALSE;
+ TAILQ_INSERT_TAIL(whead, entp, next);
+ break;
+ }
+
case 'h':
case '?':
default:
@@ -185,7 +205,8 @@ main(int argc, char **argv)
}
/* If no packages, yelp */
- if (pkgs == start && MatchType != MATCH_ALL && !CheckPkg)
+ if (pkgs == start && MatchType != MATCH_ALL && !CheckPkg &&
+ TAILQ_EMPTY(whead))
warnx("missing package name(s)"), usage();
*pkgs = NULL;
return pkg_perform(start);
@@ -196,7 +217,7 @@ usage()
{
fprintf(stderr, "%s\n%s\n%s\n",
"usage: pkg_info [-cdDfGiIkLmopqrRsvx] [-e package] [-l prefix]",
- " [-t template] [pkg-name ...]",
+ " [-t template] [-W filename] [pkg-name ...]",
" pkg_info -a [flags]");
exit(1);
}
diff --git a/usr.sbin/pkg_install/info/perform.c b/usr.sbin/pkg_install/info/perform.c
index 4d3d50e..6b111a5 100644
--- a/usr.sbin/pkg_install/info/perform.c
+++ b/usr.sbin/pkg_install/info/perform.c
@@ -25,12 +25,12 @@ static const char rcsid[] =
#include "lib.h"
#include "info.h"
-
-#include <sys/types.h>
#include <err.h>
#include <signal.h>
static int pkg_do(char *);
+static int find_pkg(char *, struct which_head *);
+static int cmp_path(const char *, const char *, const char *);
int
pkg_perform(char **pkgs)
@@ -42,16 +42,19 @@ pkg_perform(char **pkgs)
signal(SIGINT, cleanup);
+ tmp = getenv(PKG_DBDIR);
+ if (!tmp)
+ tmp = DEF_LOG_DIR;
+
/* Overriding action? */
if (CheckPkg) {
char buf[FILENAME_MAX];
- tmp = getenv(PKG_DBDIR);
- if (!tmp)
- tmp = DEF_LOG_DIR;
snprintf(buf, FILENAME_MAX, "%s/%s", tmp, CheckPkg);
return abs(access(buf, R_OK));
/* Not reached */
+ } else if (!TAILQ_EMPTY(whead)) {
+ return find_pkg(tmp, whead);
}
if (MatchType != MATCH_EXACT) {
@@ -239,3 +242,150 @@ cleanup(int sig)
exit(1);
}
+/*
+ * 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;
+ int rval;
+
+ asprintf(&temp, "%s/%s", cwd, current);
+ if (temp == NULL)
+ errx(2, NULL);
+
+ /*
+ * Make sure there's no multiple /'s, since some plists
+ * seem to have them and it could screw up our strncmp.
+ */
+ while ((loc = strstr(temp, "//")) != NULL)
+ strcpy(loc, loc + 1);
+
+ if (strcmp(target, temp) == 0)
+ rval = 1;
+ else
+ rval = 0;
+
+ free(temp);
+ return rval;
+}
+
+/*
+ * Look through package dbs in db_dir and find which
+ * packages installed the files in which_list.
+ */
+static int
+find_pkg(char *db_dir, struct which_head *which_list)
+{
+ char **installed;
+ int errcode, i;
+ struct which_entry *wp;
+
+ TAILQ_FOREACH(wp, which_list, next) {
+ /* If it's not a file, we'll see if it's an executable. */
+ if (isfile(wp->file) == FALSE) {
+ if (strchr(wp->file, '/') == NULL) {
+ char *tmp;
+ tmp = vpipe("/usr/bin/which %s", wp->file);
+ if (tmp == NULL) {
+ warnx("%s: file is not in PATH", wp->file);
+ wp->skip = TRUE;
+ } else
+ strlcpy(wp->file, tmp, PATH_MAX);
+ free(tmp);
+ } else {
+ warnx("%s: file cannot be found", wp->file);
+ 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);
+
+ if (!isfile(tmp)) {
+ warnx("%s: file cannot be found", tmp);
+ wp->skip = TRUE;
+ } else
+ strlcpy(wp->file, tmp, PATH_MAX);
+
+ free(tmp);
+ free(curdir);
+ }
+ }
+
+ installed = matchinstalled(MATCH_ALL, NULL, &errcode);
+ if (installed == NULL)
+ return errcode;
+
+ for (i = 0; installed[i] != NULL; i++) {
+ FILE *fp;
+ Package pkg;
+ PackingList itr;
+ char *cwd = NULL;
+ char tmp[PATH_MAX];
+
+ snprintf(tmp, PATH_MAX, "%s/%s/%s", db_dir, installed[i],
+ CONTENTS_FNAME);
+ fp = fopen(tmp, "r");
+ if (fp == NULL) {
+ warn("%s", tmp);
+ return 1;
+ }
+
+ pkg.head = pkg.tail = NULL;
+ read_plist(&pkg, fp);
+ fclose(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) {
+ TAILQ_FOREACH(wp, which_list, next) {
+ if (wp->skip == TRUE)
+ continue;
+ if (!cmp_path(wp->file, itr->name, cwd))
+ continue;
+ if (wp->package[0] != '\0') {
+ warnx("Both %s and %s claim to have installed %s\n",
+ wp->package, installed[i], wp->file);
+ } else {
+ strlcpy(wp->package, installed[i], PATH_MAX);
+ }
+ }
+ }
+ }
+ free_plist(&pkg);
+ }
+
+ TAILQ_FOREACH(wp, which_list, next) {
+ if (wp->package[0] != '\0') {
+ if (Quiet)
+ puts(wp->package);
+ else
+ printf("%s was installed by package %s\n", \
+ wp->file, wp->package);
+ }
+ }
+ while (!TAILQ_EMPTY(which_list)) {
+ wp = TAILQ_FIRST(which_list);
+ TAILQ_REMOVE(which_list, wp, next);
+ free(wp);
+ }
+
+ free(which_list);
+ return 0;
+}
diff --git a/usr.sbin/pkg_install/info/pkg_info.1 b/usr.sbin/pkg_install/info/pkg_info.1
index bda409c..7a13fc6 100644
--- a/usr.sbin/pkg_install/info/pkg_info.1
+++ b/usr.sbin/pkg_install/info/pkg_info.1
@@ -29,6 +29,7 @@
.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,14 @@ when selecting packages to be displayed (by default
.Nm
automatically expands shell glob patterns in the
.Ar pkg-name ) .
+.It Fl W
+For the specified
+.Ar filename
+argument show which package it belongs to. If the file is not in the
+current directory, and does not have an absolute path, then the
+.Ev PATH
+is searched using
+.Xr which 1 .
.It Fl x
Treat the
.Ar pkg-name
diff --git a/usr.sbin/pkg_install/info/show.c b/usr.sbin/pkg_install/info/show.c
index 463c1b6..24800c4 100644
--- a/usr.sbin/pkg_install/info/show.c
+++ b/usr.sbin/pkg_install/info/show.c
@@ -25,7 +25,6 @@ static const char rcsid[] =
#include "lib.h"
#include "info.h"
-
#include <err.h>
#include <stdlib.h>
#include <sys/types.h>
diff --git a/usr.sbin/pkg_install/lib/deps.c b/usr.sbin/pkg_install/lib/deps.c
index 4c06da8..84d5c47 100644
--- a/usr.sbin/pkg_install/lib/deps.c
+++ b/usr.sbin/pkg_install/lib/deps.c
@@ -25,7 +25,6 @@ static const char rcsid[] =
*/
#include "lib.h"
-
#include <err.h>
#include <stdio.h>
diff --git a/usr.sbin/pkg_install/lib/exec.c b/usr.sbin/pkg_install/lib/exec.c
index 4ed452e..dbb4625 100644
--- a/usr.sbin/pkg_install/lib/exec.c
+++ b/usr.sbin/pkg_install/lib/exec.c
@@ -23,8 +23,8 @@ static const char rcsid[] =
*
*/
-#include <err.h>
#include "lib.h"
+#include <err.h>
/*
* Unusual system() substitute. Accepts format string and args,
@@ -60,3 +60,50 @@ printf("Executing %s\n", cmd);
return ret;
}
+char *
+vpipe(const char *fmt, ...)
+{
+ FILE *fp;
+ char *cmd, *rp;
+ int maxargs;
+ va_list args;
+
+ rp = malloc(MAXPATHLEN);
+ if (!rp) {
+ warnx("vpipe can't alloc buffer space");
+ return NULL;
+ }
+ maxargs = sysconf(_SC_ARG_MAX);
+ maxargs -= 32; /* some slop for the sh -c */
+ cmd = alloca(maxargs);
+ if (!cmd) {
+ warnx("vpipe can't alloc arg space");
+ return NULL;
+ }
+
+ va_start(args, fmt);
+ if (vsnprintf(cmd, maxargs, fmt, args) > maxargs) {
+ warnx("vsystem args are too long");
+ return NULL;
+ }
+#ifdef DEBUG
+ fprintf(stderr, "Executing %s\n", cmd);
+#endif
+ fflush(NULL);
+ fp = popen(cmd, "r");
+ if (fp == NULL) {
+ warnx("popen() failed");
+ return NULL;
+ }
+ get_string(rp, MAXPATHLEN, fp);
+#ifdef DEBUG
+ fprintf(stderr, "Returned %s\n", rp);
+#endif
+ va_end(args);
+ if (pclose(fp) || (strlen(rp) == 0)) {
+ free(rp);
+ return NULL;
+ }
+ return rp;
+}
+
diff --git a/usr.sbin/pkg_install/lib/lib.h b/usr.sbin/pkg_install/lib/lib.h
index 0ed6899..3ab1b63 100644
--- a/usr.sbin/pkg_install/lib/lib.h
+++ b/usr.sbin/pkg_install/lib/lib.h
@@ -112,6 +112,7 @@ typedef struct _pack Package;
/* Prototypes */
/* Misc */
int vsystem(const char *, ...);
+char *vpipe(const char *, ...);
void cleanup(int);
char *make_playpen(char *, size_t);
char *where_playpen(void);
@@ -126,6 +127,7 @@ void nuke_suffix(char *);
void str_lowercase(char *);
char *basename_of(char *);
char *strconcat(char *, char *);
+char *get_string(char *, int, FILE *);
/* File */
Boolean fexists(char *);
diff --git a/usr.sbin/pkg_install/lib/match.c b/usr.sbin/pkg_install/lib/match.c
index 2bcae2a..f3dc999 100644
--- a/usr.sbin/pkg_install/lib/match.c
+++ b/usr.sbin/pkg_install/lib/match.c
@@ -24,7 +24,6 @@ static const char rcsid[] =
*/
#include "lib.h"
-
#include <err.h>
#include <fnmatch.h>
#include <fts.h>
@@ -97,14 +96,18 @@ matchinstalled(match_t MatchType, char **patterns, int *retval)
}
/* Count number of patterns */
- for (len = 0; patterns[len]; len++) {}
- lmatched = alloca(sizeof(*lmatched) * len);
- if (lmatched == NULL) {
- warnx("%s(): alloca() failed", __FUNCTION__);
- if (retval != NULL)
- *retval = 1;
- return NULL;
- }
+ if (patterns != NULL) {
+ for (len = 0; patterns[len]; len++) {}
+ lmatched = alloca(sizeof(*lmatched) * len);
+ if (lmatched == NULL) {
+ warnx("%s(): alloca() failed", __FUNCTION__);
+ if (retval != NULL)
+ *retval = 1;
+ return NULL;
+ }
+ } else
+ len = 0;
+
for (i = 0; i < len; i++)
lmatched[i] = FALSE;
diff --git a/usr.sbin/pkg_install/lib/msg.c b/usr.sbin/pkg_install/lib/msg.c
index 068d305..5f954ca 100644
--- a/usr.sbin/pkg_install/lib/msg.c
+++ b/usr.sbin/pkg_install/lib/msg.c
@@ -24,9 +24,9 @@ static const char rcsid[] =
*
*/
+#include "lib.h"
#include <err.h>
#include <paths.h>
-#include "lib.h"
/* Die a relatively simple death */
void
diff --git a/usr.sbin/pkg_install/lib/pen.c b/usr.sbin/pkg_install/lib/pen.c
index 687d6bb..62465bf 100644
--- a/usr.sbin/pkg_install/lib/pen.c
+++ b/usr.sbin/pkg_install/lib/pen.c
@@ -23,8 +23,8 @@ static const char rcsid[] =
*
*/
-#include <err.h>
#include "lib.h"
+#include <err.h>
#include <sys/signal.h>
#include <sys/param.h>
#include <sys/mount.h>
diff --git a/usr.sbin/pkg_install/lib/str.c b/usr.sbin/pkg_install/lib/str.c
index 67a5e64..c5f11a2 100644
--- a/usr.sbin/pkg_install/lib/str.c
+++ b/usr.sbin/pkg_install/lib/str.c
@@ -109,3 +109,22 @@ str_lowercase(char *str)
++str;
}
}
+
+char *
+get_string(char *str, int max, FILE *fp)
+{
+ int len;
+
+ if (!str)
+ return NULL;
+ str[0] = '\0';
+ while (fgets(str, max, fp)) {
+ len = strlen(str);
+ while (len && isspace(str[len - 1]))
+ str[--len] = '\0';
+ if (len)
+ return str;
+ }
+ return NULL;
+}
+
OpenPOWER on IntegriCloud