summaryrefslogtreecommitdiffstats
path: root/usr.sbin/pkg_install/info/perform.c
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/info/perform.c
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/info/perform.c')
-rw-r--r--usr.sbin/pkg_install/info/perform.c160
1 files changed, 155 insertions, 5 deletions
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;
+}
OpenPOWER on IntegriCloud