summaryrefslogtreecommitdiffstats
path: root/usr.sbin/pkg_install/lib
diff options
context:
space:
mode:
authorsobomax <sobomax@FreeBSD.org>2002-05-14 21:42:37 +0000
committersobomax <sobomax@FreeBSD.org>2002-05-14 21:42:37 +0000
commitbac8396cc90f34d617b583831e7a5902146b56b9 (patch)
treed8b1633a3ddd015d49630a6bac619312b1306625 /usr.sbin/pkg_install/lib
parenteb68e3aae2dbda29ad3463cd0ad85dcb6ce4158a (diff)
downloadFreeBSD-src-bac8396cc90f34d617b583831e7a5902146b56b9.zip
FreeBSD-src-bac8396cc90f34d617b583831e7a5902146b56b9.tar.gz
- Make use of DEPOROGINs (if there are any) when installing package;
- fix few bogosities here and there; - move some common routines into the library. MFC after: 2 weeks
Diffstat (limited to 'usr.sbin/pkg_install/lib')
-rw-r--r--usr.sbin/pkg_install/lib/deps.c15
-rw-r--r--usr.sbin/pkg_install/lib/lib.h2
-rw-r--r--usr.sbin/pkg_install/lib/match.c146
3 files changed, 139 insertions, 24 deletions
diff --git a/usr.sbin/pkg_install/lib/deps.c b/usr.sbin/pkg_install/lib/deps.c
index cf366f0..4ebb2cf 100644
--- a/usr.sbin/pkg_install/lib/deps.c
+++ b/usr.sbin/pkg_install/lib/deps.c
@@ -84,7 +84,6 @@ int
chkifdepends(const char *pkgname1, const char *pkgname2)
{
char *cp1, *cp2;
- char pkgdir[FILENAME_MAX];
int errcode;
struct reqr_by_entry *rb_entry;
struct reqr_by_head *rb_list;
@@ -98,8 +97,7 @@ chkifdepends(const char *pkgname1, const char *pkgname2)
errcode = 0;
/* Check that pkgname2 is actually installed */
- snprintf(pkgdir, sizeof(pkgdir), "%s/%s", LOG_DIR, pkgname2);
- if (!isdir(pkgdir))
+ if (!isinstalledpkg(pkgname2))
goto exit;
errcode = requiredby(pkgname2, &rb_list, FALSE, TRUE);
@@ -142,7 +140,7 @@ int
requiredby(const char *pkgname, struct reqr_by_head **list, Boolean strict, Boolean filter)
{
FILE *fp;
- char fbuf[FILENAME_MAX], fname[FILENAME_MAX], pkgdir[FILENAME_MAX];
+ char fbuf[FILENAME_MAX], fname[FILENAME_MAX];
int retval;
struct reqr_by_entry *rb_entry;
static struct reqr_by_head rb_list = STAILQ_HEAD_INITIALIZER(rb_list);
@@ -155,14 +153,14 @@ requiredby(const char *pkgname, struct reqr_by_head **list, Boolean strict, Bool
free(rb_entry);
}
- snprintf(fname, sizeof(fname), "%s/%s", LOG_DIR, pkgname);
- if (!isdir(fname)) {
+ if (!isinstalledpkg(pkgname)) {
if (strict == TRUE)
warnx("no such package '%s' installed", pkgname);
return -1;
}
- snprintf(fname, sizeof(fname), "%s/%s", fname, REQUIRED_BY_FNAME);
+ snprintf(fname, sizeof(fname), "%s/%s/%s", LOG_DIR, pkgname,
+ REQUIRED_BY_FNAME);
fp = fopen(fname, "r");
if (fp == NULL) {
/* Probably pkgname doesn't have any packages that depend on it */
@@ -175,8 +173,7 @@ requiredby(const char *pkgname, struct reqr_by_head **list, Boolean strict, Bool
while (fgets(fbuf, sizeof(fbuf), fp) != NULL) {
if (fbuf[strlen(fbuf) - 1] == '\n')
fbuf[strlen(fbuf) - 1] = '\0';
- snprintf(pkgdir, sizeof(pkgdir), "%s/%s", LOG_DIR, fbuf);
- if (filter == TRUE && !isdir(pkgdir)) {
+ if (filter == TRUE && !isinstalledpkg(fbuf)) {
if (strict == TRUE)
warnx("package '%s' is recorded in the '%s' but isn't "
"actually installed", fbuf, fname);
diff --git a/usr.sbin/pkg_install/lib/lib.h b/usr.sbin/pkg_install/lib/lib.h
index 181c3a2..5a11712 100644
--- a/usr.sbin/pkg_install/lib/lib.h
+++ b/usr.sbin/pkg_install/lib/lib.h
@@ -193,6 +193,8 @@ int pkg_perform(char **);
/* Query installed packages */
char **matchinstalled(match_t, char **, int *);
+char **matchbyorigin(const char *, int *);
+int isinstalledpkg(const char *name);
/* Dependencies */
int sortdeps(char **);
diff --git a/usr.sbin/pkg_install/lib/match.c b/usr.sbin/pkg_install/lib/match.c
index 5671406..fd96f3f 100644
--- a/usr.sbin/pkg_install/lib/match.c
+++ b/usr.sbin/pkg_install/lib/match.c
@@ -38,6 +38,7 @@ struct store {
};
static int rex_match(const char *, const char *);
+struct store *storecreate(struct store *);
static int storeappend(struct store *, const char *);
static int fname_cmp(const FTSENT **, const FTSENT **);
@@ -63,22 +64,12 @@ matchinstalled(match_t MatchType, char **patterns, int *retval)
FTSENT *f;
Boolean *lmatched;
+ store = storecreate(store);
if (store == NULL) {
- store = malloc(sizeof *store);
- if (store == NULL) {
- warnx("%s(): malloc() failed", __func__);
- if (retval != NULL)
- *retval = 1;
- return NULL;
- }
- store->currlen = 0;
- store->store = NULL;
- } else
- if (store->store != NULL)
- /* Free previously allocated memory */
- for (i = 0; store->store[i] != NULL; i++)
- free(store->store[i]);
- store->used = 0;
+ if (retval != NULL)
+ *retval = 1;
+ return NULL;
+ }
if (retval != NULL)
*retval = 0;
@@ -163,6 +154,101 @@ matchinstalled(match_t MatchType, char **patterns, int *retval)
}
/*
+ * Synopsis is similar to matchinstalled(), but use origin
+ * as a key for matching packages.
+ */
+char **
+matchbyorigin(const char *origin, int *retval)
+{
+ char **installed;
+ int i;
+ static struct store *store = NULL;
+
+ store = storecreate(store);
+ if (store == NULL) {
+ if (retval != NULL)
+ *retval = 1;
+ return NULL;
+ }
+
+ if (retval != NULL)
+ *retval = 0;
+
+ installed = matchinstalled(MATCH_ALL, NULL, retval);
+ if (installed == NULL)
+ return NULL;
+
+ for (i = 0; installed[i] != NULL; i++) {
+ FILE *fp;
+ char *cp, tmp[PATH_MAX];
+ int cmd;
+
+ snprintf(tmp, PATH_MAX, "%s/%s", LOG_DIR, installed[i]);
+ /*
+ * SPECIAL CASE: ignore empty dirs, since we can can see them
+ * during port installation.
+ */
+ if (isemptydir(tmp))
+ continue;
+ snprintf(tmp, PATH_MAX, "%s/%s", tmp, CONTENTS_FNAME);
+ fp = fopen(tmp, "r");
+ if (fp == NULL) {
+ warn("%s", tmp);
+ if (retval != NULL)
+ *retval = 1;
+ return NULL;
+ }
+
+ cmd = -1;
+ while (fgets(tmp, sizeof(tmp), fp)) {
+ int len = strlen(tmp);
+
+ while (len && isspace(tmp[len - 1]))
+ tmp[--len] = '\0';
+ if (!len)
+ continue;
+ cp = tmp;
+ if (tmp[0] != CMD_CHAR)
+ continue;
+ cmd = plist_cmd(tmp + 1, &cp);
+ if (cmd == PLIST_ORIGIN) {
+ if (strcmp(origin, cp) == 0)
+ storeappend(store, installed[i]);
+ break;
+ }
+ }
+ if (cmd != PLIST_ORIGIN)
+ warnx("package %s has no origin recorded", installed[i]);
+ fclose(fp);
+ }
+
+ if (store->used == 0)
+ return NULL;
+ else
+ return store->store;
+}
+
+/*
+ * Return TRUE if the specified package is installed,
+ * or FALSE otherwise.
+ */
+int
+isinstalledpkg(const char *name)
+{
+ char buf[FILENAME_MAX];
+
+ snprintf(buf, sizeof(buf), "%s/%s", LOG_DIR, name);
+ if (!isdir(buf) || access(buf, R_OK) == FAIL)
+ return FALSE;
+
+ snprintf(buf, sizeof(buf), "%s/%s", buf, CONTENTS_FNAME);
+ if (!isfile(buf) || access(buf, R_OK) == FAIL)
+ return FALSE;
+
+ return TRUE;
+}
+
+/*
* Returns 1 if specified pkgname matches RE pattern.
* Otherwise returns 0 if doesn't match or -1 if RE
* engine reported an error (usually invalid syntax).
@@ -194,6 +280,36 @@ rex_match(const char *pattern, const char *pkgname)
return retval;
}
+/*
+ * Create an empty store, optionally deallocating
+ * any previously allocated space if store != NULL.
+ */
+struct store *
+storecreate(struct store *store)
+{
+ int i;
+
+ if (store == NULL) {
+ store = malloc(sizeof *store);
+ if (store == NULL) {
+ warnx("%s(): malloc() failed", __func__);
+ return NULL;
+ }
+ store->currlen = 0;
+ store->store = NULL;
+ } else
+ if (store->store != NULL)
+ /* Free previously allocated memory */
+ for (i = 0; store->store[i] != NULL; i++)
+ free(store->store[i]);
+ store->used = 0;
+
+ return store;
+}
+
+/*
+ * Append specified element to the provided store.
+ */
static int
storeappend(struct store *store, const char *item)
{
OpenPOWER on IntegriCloud