Module Name: src
Committed By: wiz
Date: Wed Dec 2 13:53:50 UTC 2020
Modified Files:
src/external/bsd/pkg_install/dist/add: perform.c
src/external/bsd/pkg_install/dist/admin: check.c main.c pkg_admin.1
src/external/bsd/pkg_install/dist/create: perform.c pl.c
src/external/bsd/pkg_install/dist/info: perform.c
src/external/bsd/pkg_install/dist/lib: iterate.c lib.h license.c
pkgdb.c plist.c version.h vulnerabilities-file.c
Log Message:
merge pkg_install after import of 20201202 version
To generate a diff of this commit:
cvs rdiff -u -r1.6 -r1.7 src/external/bsd/pkg_install/dist/add/perform.c
cvs rdiff -u -r1.3 -r1.4 src/external/bsd/pkg_install/dist/admin/check.c
cvs rdiff -u -r1.5 -r1.6 src/external/bsd/pkg_install/dist/admin/main.c \
src/external/bsd/pkg_install/dist/admin/pkg_admin.1
cvs rdiff -u -r1.2 -r1.3 src/external/bsd/pkg_install/dist/create/perform.c
cvs rdiff -u -r1.3 -r1.4 src/external/bsd/pkg_install/dist/create/pl.c
cvs rdiff -u -r1.2 -r1.3 src/external/bsd/pkg_install/dist/info/perform.c
cvs rdiff -u -r1.2 -r1.3 src/external/bsd/pkg_install/dist/lib/iterate.c \
src/external/bsd/pkg_install/dist/lib/pkgdb.c
cvs rdiff -u -r1.9 -r1.10 src/external/bsd/pkg_install/dist/lib/lib.h \
src/external/bsd/pkg_install/dist/lib/license.c
cvs rdiff -u -r1.3 -r1.4 src/external/bsd/pkg_install/dist/lib/plist.c \
src/external/bsd/pkg_install/dist/lib/vulnerabilities-file.c
cvs rdiff -u -r1.15 -r1.16 src/external/bsd/pkg_install/dist/lib/version.h
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/external/bsd/pkg_install/dist/add/perform.c
diff -u src/external/bsd/pkg_install/dist/add/perform.c:1.6 src/external/bsd/pkg_install/dist/add/perform.c:1.7
--- src/external/bsd/pkg_install/dist/add/perform.c:1.6 Sun Mar 25 04:04:36 2018
+++ src/external/bsd/pkg_install/dist/add/perform.c Wed Dec 2 13:53:50 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: perform.c,v 1.6 2018/03/25 04:04:36 sevan Exp $ */
+/* $NetBSD: perform.c,v 1.7 2020/12/02 13:53:50 wiz Exp $ */
#if HAVE_CONFIG_H
#include "config.h"
#endif
@@ -6,7 +6,7 @@
#if HAVE_SYS_CDEFS_H
#include <sys/cdefs.h>
#endif
-__RCSID("$NetBSD: perform.c,v 1.6 2018/03/25 04:04:36 sevan Exp $");
+__RCSID("$NetBSD: perform.c,v 1.7 2020/12/02 13:53:50 wiz Exp $");
/*-
* Copyright (c) 2003 Grant Beattie <[email protected]>
@@ -450,7 +450,7 @@ check_other_installed(struct pkg_task *p
return -1;
}
*iter = '\0';
- pkg->other_version = find_best_matching_installed_pkg(pkgbase);
+ pkg->other_version = find_best_matching_installed_pkg(pkgbase, 0);
free(pkgbase);
if (pkg->other_version == NULL)
return 0;
@@ -505,10 +505,12 @@ check_other_installed(struct pkg_task *p
continue;
if (pkg_match(p->name, pkg->pkgname) == 1)
continue; /* Both match, ok. */
- warnx("Dependency of %s fulfilled by %s, but not by %s",
- iter, pkg->other_version, pkg->pkgname);
- if (!ForceDepending)
+ if (!ForceDepending) {
+ warnx("Dependency of %s fulfilled by %s, "
+ "but not by %s", iter, pkg->other_version,
+ pkg->pkgname);
status = -1;
+ }
break;
}
free_plist(&plist);
@@ -979,7 +981,8 @@ run_install_script(struct pkg_task *pkg,
setenv(PKG_REFCOUNT_DBDIR_VNAME, config_pkg_refcount_dbdir, 1);
if (Verbose)
- printf("Running install with PRE-INSTALL for %s.\n", pkg->pkgname);
+ printf("Running install with %s for %s.\n", argument,
+ pkg->pkgname);
if (Fake)
return 0;
@@ -1102,6 +1105,40 @@ check_implicit_conflict(struct pkg_task
return status;
}
+/*
+ * Install a required dependency and verify its installation.
+ */
+static int
+install_depend_pkg(const char *dep)
+{
+ /* XXX check cyclic dependencies? */
+ if (Fake || NoRecord) {
+ if (!Force) {
+ warnx("Missing dependency %s\n", dep);
+ return 1;
+ }
+ warnx("Missing dependency %s, continuing", dep);
+ }
+
+ if (pkg_do(dep, 1, 0)) {
+ if (!ForceDepends) {
+ warnx("Can't install dependency %s", dep);
+ return 1;
+ }
+ warnx("Can't install dependency %s, continuing", dep);
+ }
+
+ if (find_best_matching_installed_pkg(dep, 0) == NULL) {
+ if (!ForceDepends) {
+ warnx("Just installed dependency %s disappeared", dep);
+ return 1;
+ }
+ warnx("Missing dependency %s ignored", dep);
+ }
+
+ return 0;
+}
+
static int
check_dependencies(struct pkg_task *pkg)
{
@@ -1112,6 +1149,9 @@ check_dependencies(struct pkg_task *pkg)
status = 0;
+ /*
+ * Recursively handle dependencies, installing as required.
+ */
for (p = pkg->plist.head; p != NULL; p = p->next) {
if (p->type == PLIST_IGNORE) {
p = p->next;
@@ -1119,43 +1159,27 @@ check_dependencies(struct pkg_task *pkg)
} else if (p->type != PLIST_PKGDEP)
continue;
- best_installed = find_best_matching_installed_pkg(p->name);
-
- if (best_installed == NULL) {
- /* XXX check cyclic dependencies? */
- if (Fake || NoRecord) {
- if (!Force) {
- warnx("Missing dependency %s\n",
- p->name);
- status = -1;
- break;
- }
- warnx("Missing dependency %s, continuing",
- p->name);
- continue;
- }
- if (pkg_do(p->name, 1, 0)) {
- if (ForceDepends) {
- warnx("Can't install dependency %s, "
- "continuing", p->name);
- continue;
- } else {
- warnx("Can't install dependency %s",
- p->name);
- status = -1;
- break;
- }
- }
- best_installed = find_best_matching_installed_pkg(p->name);
- if (best_installed == NULL && ForceDepends) {
- warnx("Missing dependency %s ignored", p->name);
- continue;
- } else if (best_installed == NULL) {
- warnx("Just installed dependency %s disappeared", p->name);
+ if (find_best_matching_installed_pkg(p->name, 0) == NULL) {
+ if (install_depend_pkg(p->name) != 0) {
status = -1;
break;
}
}
+ }
+
+ /*
+ * Now that all dependencies have been processed we can find the best
+ * matches for pkg_register_depends() to store in our +REQUIRED_BY.
+ */
+ for (p = pkg->plist.head; p != NULL; p = p->next) {
+ if (p->type == PLIST_IGNORE) {
+ p = p->next;
+ continue;
+ } else if (p->type != PLIST_PKGDEP)
+ continue;
+
+ best_installed = find_best_matching_installed_pkg(p->name, 0);
+
for (i = 0; i < pkg->dep_length; ++i) {
if (strcmp(best_installed, pkg->dependencies[i]) == 0)
break;
Index: src/external/bsd/pkg_install/dist/admin/check.c
diff -u src/external/bsd/pkg_install/dist/admin/check.c:1.3 src/external/bsd/pkg_install/dist/admin/check.c:1.4
--- src/external/bsd/pkg_install/dist/admin/check.c:1.3 Sun Jan 12 21:31:03 2020
+++ src/external/bsd/pkg_install/dist/admin/check.c Wed Dec 2 13:53:50 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: check.c,v 1.3 2020/01/12 21:31:03 christos Exp $ */
+/* $NetBSD: check.c,v 1.4 2020/12/02 13:53:50 wiz Exp $ */
#ifdef HAVE_NBTOOL_CONFIG_H
#include "nbtool_config.h"
@@ -11,7 +11,7 @@
#include <sys/cdefs.h>
#endif
#endif
-__RCSID("$NetBSD: check.c,v 1.3 2020/01/12 21:31:03 christos Exp $");
+__RCSID("$NetBSD: check.c,v 1.4 2020/12/02 13:53:50 wiz Exp $");
/*-
* Copyright (c) 1999-2008 The NetBSD Foundation, Inc.
@@ -81,7 +81,7 @@ __RCSID("$NetBSD: check.c,v 1.3 2020/01/
static int checkpattern_fn(const char *, void *);
/*
- * Assumes CWD is in /var/db/pkg/<pkg>!
+ * Assumes CWD is in the database directory ($PREFIX/pkgdb/<pkg>)!
*/
static void
check1pkg(const char *pkgdir, int *filecnt, int *pkgcnt)
Index: src/external/bsd/pkg_install/dist/admin/main.c
diff -u src/external/bsd/pkg_install/dist/admin/main.c:1.5 src/external/bsd/pkg_install/dist/admin/main.c:1.6
--- src/external/bsd/pkg_install/dist/admin/main.c:1.5 Sun Jan 12 21:31:03 2020
+++ src/external/bsd/pkg_install/dist/admin/main.c Wed Dec 2 13:53:50 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: main.c,v 1.5 2020/01/12 21:31:03 christos Exp $ */
+/* $NetBSD: main.c,v 1.6 2020/12/02 13:53:50 wiz Exp $ */
#ifdef HAVE_NBTOOL_CONFIG_H
#include "nbtool_config.h"
@@ -11,7 +11,7 @@
#include <sys/cdefs.h>
#endif
#endif
-__RCSID("$NetBSD: main.c,v 1.5 2020/01/12 21:31:03 christos Exp $");
+__RCSID("$NetBSD: main.c,v 1.6 2020/12/02 13:53:50 wiz Exp $");
/*-
* Copyright (c) 1999-2019 The NetBSD Foundation, Inc.
@@ -94,6 +94,25 @@ struct pkgdb_count {
size_t packages;
};
+/*
+ * A hashed list of +REQUIRED_BY entries.
+ */
+struct reqd_by_entry {
+ char *pkgname;
+ SLIST_ENTRY(reqd_by_entry) entries;
+};
+SLIST_HEAD(reqd_by_entry_head, reqd_by_entry);
+
+/*
+ * A hashed list of packages that contain +REQUIRED_BY entries.
+ */
+struct pkg_reqd_by {
+ char *pkgname;
+ struct reqd_by_entry_head required_by[PKG_HASH_SIZE];
+ SLIST_ENTRY(pkg_reqd_by) entries;
+};
+SLIST_HEAD(pkg_reqd_by_head, pkg_reqd_by);
+
static const char Options[] = "C:K:SVbd:qs:v";
int quiet, verbose;
@@ -284,37 +303,79 @@ remove_required_by(const char *pkgname,
}
static void
-add_required_by(const char *pattern, const char *required_by)
+add_required_by(const char *pattern, const char *pkgname, struct pkg_reqd_by_head *hash)
{
- char *best_installed, *path;
- int fd;
- size_t len;
+ struct pkg_reqd_by_head *phead;
+ struct pkg_reqd_by *pkg;
+ struct reqd_by_entry_head *ehead;
+ struct reqd_by_entry *entry;
+ char *best_installed;
+ int i;
- best_installed = find_best_matching_installed_pkg(pattern);
+ best_installed = find_best_matching_installed_pkg(pattern, 1);
if (best_installed == NULL) {
- warnx("Dependency %s of %s unresolved", pattern, required_by);
+ warnx("Dependency %s of %s unresolved", pattern, pkgname);
return;
}
- path = pkgdb_pkg_file(best_installed, REQUIRED_BY_FNAME);
- free(best_installed);
+ /*
+ * Find correct reqd_by head based on hash of best_installed, which is
+ * the package in question that we are adding +REQUIRED_BY entries for.
+ */
+ phead = &hash[PKG_HASH_ENTRY(best_installed)];
- if ((fd = open(path, O_WRONLY | O_APPEND | O_CREAT, 0644)) == -1)
- errx(EXIT_FAILURE, "Cannot write to %s", path);
- free(path);
-
- len = strlen(required_by);
- if (write(fd, required_by, len) != (ssize_t)len ||
- write(fd, "\n", 1) != 1 ||
- close(fd) == -1)
- errx(EXIT_FAILURE, "Cannot write to %s", path);
-}
+ /*
+ * Look for an existing entry in this hash list.
+ */
+ SLIST_FOREACH(pkg, phead, entries) {
+ if (strcmp(pkg->pkgname, best_installed) == 0) {
+
+ /*
+ * Found an entry, now see if it already has a
+ * +REQUIRED_BY entry recorded for this pkgname,
+ * and if not then add it.
+ */
+ ehead = &pkg->required_by[PKG_HASH_ENTRY(pkgname)];
+ SLIST_FOREACH(entry, ehead, entries) {
+ if (strcmp(entry->pkgname, pkgname) == 0)
+ break;
+ }
+
+ if (entry == NULL) {
+ entry = xmalloc(sizeof(*entry));
+ entry->pkgname = xstrdup(pkgname);
+ SLIST_INSERT_HEAD(ehead, entry, entries);
+ }
+ break;
+ }
+ }
+
+ /*
+ * Create new package containing its first +REQUIRED_BY entry.
+ */
+ if (pkg == NULL) {
+ pkg = xmalloc(sizeof(*pkg));
+ pkg->pkgname = xstrdup(best_installed);
+ for (i = 0; i < PKG_HASH_SIZE; i++)
+ SLIST_INIT(&pkg->required_by[i]);
+
+ ehead = &pkg->required_by[PKG_HASH_ENTRY(pkgname)];
+ entry = xmalloc(sizeof(*entry));
+ entry->pkgname = xstrdup(pkgname);
+ SLIST_INSERT_HEAD(ehead, entry, entries);
+
+ SLIST_INSERT_HEAD(phead, pkg, entries);
+ }
+
+ free(best_installed);
+}
static int
add_depends_of(const char *pkgname, void *cookie)
{
FILE *fp;
+ struct pkg_reqd_by_head *h = cookie;
plist_t *p;
package_t plist;
char *path;
@@ -329,7 +390,7 @@ add_depends_of(const char *pkgname, void
for (p = plist.head; p; p = p->next) {
if (p->type == PLIST_PKGDEP)
- add_required_by(p->name, pkgname);
+ add_required_by(p->name, pkgname, h);
}
free_plist(&plist);
@@ -340,10 +401,53 @@ add_depends_of(const char *pkgname, void
static void
rebuild_tree(void)
{
- if (iterate_pkg_db(remove_required_by, NULL) == -1)
+ FILE *fp;
+ struct pkg_reqd_by_head pkgs[PKG_HASH_SIZE];
+ struct pkg_reqd_by *p;
+ struct reqd_by_entry *e;
+ int fd, i, j;
+ char *path;
+
+ for (i = 0; i < PKG_HASH_SIZE; i++)
+ SLIST_INIT(&pkgs[i]);
+
+ /*
+ * First, calculate all of the +REQUIRED_BY entries and store in our
+ * pkgs hashed list.
+ */
+ if (iterate_pkg_db(add_depends_of, &pkgs) == -1)
errx(EXIT_FAILURE, "cannot iterate pkgdb");
- if (iterate_pkg_db(add_depends_of, NULL) == -1)
+
+ /*
+ * Now we can remove all existing +REQUIRED_BY files.
+ */
+ if (iterate_pkg_db(remove_required_by, NULL) == -1)
errx(EXIT_FAILURE, "cannot iterate pkgdb");
+
+ /*
+ * Finally, write out all the new +REQUIRED_BY files.
+ */
+ for (i = 0; i < PKG_HASH_SIZE; i++) {
+ SLIST_FOREACH(p, &pkgs[i], entries) {
+ path = pkgdb_pkg_file(p->pkgname, REQUIRED_BY_FNAME);
+
+ if ((fd = open(path, O_WRONLY | O_APPEND | O_CREAT,
+ 0644)) == -1)
+ errx(EXIT_FAILURE, "cannot write to %s", path);
+
+ if ((fp = fdopen(fd, "a")) == NULL)
+ errx(EXIT_FAILURE, "cannot open %s", path);
+
+ for (j = 0; j < PKG_HASH_SIZE; j++) {
+ SLIST_FOREACH(e, &p->required_by[j], entries)
+ fprintf(fp, "%s\n", e->pkgname);
+ }
+ if (fclose(fp) == EOF) {
+ remove(path);
+ errx(EXIT_FAILURE, "cannot close %s", path);
+ }
+ }
+ }
}
int
Index: src/external/bsd/pkg_install/dist/admin/pkg_admin.1
diff -u src/external/bsd/pkg_install/dist/admin/pkg_admin.1:1.5 src/external/bsd/pkg_install/dist/admin/pkg_admin.1:1.6
--- src/external/bsd/pkg_install/dist/admin/pkg_admin.1:1.5 Sun Oct 13 21:56:14 2019
+++ src/external/bsd/pkg_install/dist/admin/pkg_admin.1 Wed Dec 2 13:53:50 2020
@@ -1,4 +1,4 @@
-.\" $NetBSD: pkg_admin.1,v 1.5 2019/10/13 21:56:14 joerg Exp $
+.\" $NetBSD: pkg_admin.1,v 1.6 2020/12/02 13:53:50 wiz Exp $
.\"
.\" Copyright (c) 1999-2019 The NetBSD Foundation, Inc.
.\" All rights reserved.
@@ -28,7 +28,7 @@
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
.\" POSSIBILITY OF SUCH DAMAGE.
.\"
-.Dd October 8, 2019
+.Dd August 22, 2020
.Dt PKG_ADMIN 1
.Os
.Sh NAME
@@ -295,9 +295,9 @@ See
.Xr pkg_install.conf 5
for options, that can also be specified using the environment.
.Sh FILES
-.Bl -tag -width /var/db/pkg/pkgdb.byfile.db -compact
-.It Pa /var/db/pkg/pkgdb.byfile.db
-.It Pa /var/db/pkg/\*[Lt]pkg\*[Gt]/+CONTENTS
+.Bl -tag -width @PREFIX@/pkgdb/pkgdb.byfile.db -compact
+.It Pa @PREFIX@/pkgdb/pkgdb.byfile.db
+.It Pa @PREFIX@/pkgdb/\*[Lt]pkg\*[Gt]/+CONTENTS
.El
.Sh SEE ALSO
.Xr pkg_add 1 ,
Index: src/external/bsd/pkg_install/dist/create/perform.c
diff -u src/external/bsd/pkg_install/dist/create/perform.c:1.2 src/external/bsd/pkg_install/dist/create/perform.c:1.3
--- src/external/bsd/pkg_install/dist/create/perform.c:1.2 Thu Apr 20 13:18:23 2017
+++ src/external/bsd/pkg_install/dist/create/perform.c Wed Dec 2 13:53:50 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: perform.c,v 1.2 2017/04/20 13:18:23 joerg Exp $ */
+/* $NetBSD: perform.c,v 1.3 2020/12/02 13:53:50 wiz Exp $ */
#if HAVE_CONFIG_H
#include "config.h"
@@ -7,7 +7,7 @@
#if HAVE_SYS_CDEFS_H
#include <sys/cdefs.h>
#endif
-__RCSID("$NetBSD: perform.c,v 1.2 2017/04/20 13:18:23 joerg Exp $");
+__RCSID("$NetBSD: perform.c,v 1.3 2020/12/02 13:53:50 wiz Exp $");
/*
* FreeBSD install - a package for the installation and maintainance
@@ -68,7 +68,7 @@ register_depends(package_t *plist, char
cp = strsep(&deps, " \t\n");
if (*cp) {
char *best_installed;
- best_installed = find_best_matching_installed_pkg(cp);
+ best_installed = find_best_matching_installed_pkg(cp, 1);
if (best_installed != NULL) {
add_plist(plist, PLIST_BLDDEP, best_installed);
if (Verbose && !PlistOnly && build_only)
Index: src/external/bsd/pkg_install/dist/create/pl.c
diff -u src/external/bsd/pkg_install/dist/create/pl.c:1.3 src/external/bsd/pkg_install/dist/create/pl.c:1.4
--- src/external/bsd/pkg_install/dist/create/pl.c:1.3 Sun Jan 12 21:31:03 2020
+++ src/external/bsd/pkg_install/dist/create/pl.c Wed Dec 2 13:53:50 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: pl.c,v 1.3 2020/01/12 21:31:03 christos Exp $ */
+/* $NetBSD: pl.c,v 1.4 2020/12/02 13:53:50 wiz Exp $ */
#ifdef HAVE_NBTOOL_CONFIG_H
#include "nbtool_config.h"
@@ -11,7 +11,7 @@
#include <sys/cdefs.h>
#endif
#endif
-__RCSID("$NetBSD: pl.c,v 1.3 2020/01/12 21:31:03 christos Exp $");
+__RCSID("$NetBSD: pl.c,v 1.4 2020/12/02 13:53:50 wiz Exp $");
/*
* FreeBSD install - a package for the installation and maintainance
Index: src/external/bsd/pkg_install/dist/info/perform.c
diff -u src/external/bsd/pkg_install/dist/info/perform.c:1.2 src/external/bsd/pkg_install/dist/info/perform.c:1.3
--- src/external/bsd/pkg_install/dist/info/perform.c:1.2 Thu Apr 20 13:18:23 2017
+++ src/external/bsd/pkg_install/dist/info/perform.c Wed Dec 2 13:53:50 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: perform.c,v 1.2 2017/04/20 13:18:23 joerg Exp $ */
+/* $NetBSD: perform.c,v 1.3 2020/12/02 13:53:50 wiz Exp $ */
#if HAVE_CONFIG_H
#include "config.h"
@@ -7,7 +7,7 @@
#if HAVE_SYS_CDEFS_H
#include <sys/cdefs.h>
#endif
-__RCSID("$NetBSD: perform.c,v 1.2 2017/04/20 13:18:23 joerg Exp $");
+__RCSID("$NetBSD: perform.c,v 1.3 2020/12/02 13:53:50 wiz Exp $");
/*-
* Copyright (c) 2008 Joerg Sonnenberger <[email protected]>.
@@ -566,13 +566,13 @@ CheckForBestPkg(const char *pkgname)
{
char *pattern, *best_match;
- best_match = find_best_matching_installed_pkg(pkgname);
+ best_match = find_best_matching_installed_pkg(pkgname, 1);
if (best_match == NULL) {
if (ispkgpattern(pkgname))
return 1;
pattern = xasprintf("%s-[0-9]*", pkgname);
- best_match = find_best_matching_installed_pkg(pattern);
+ best_match = find_best_matching_installed_pkg(pattern, 1);
free(pattern);
}
Index: src/external/bsd/pkg_install/dist/lib/iterate.c
diff -u src/external/bsd/pkg_install/dist/lib/iterate.c:1.2 src/external/bsd/pkg_install/dist/lib/iterate.c:1.3
--- src/external/bsd/pkg_install/dist/lib/iterate.c:1.2 Thu Apr 20 13:18:23 2017
+++ src/external/bsd/pkg_install/dist/lib/iterate.c Wed Dec 2 13:53:50 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: iterate.c,v 1.2 2017/04/20 13:18:23 joerg Exp $ */
+/* $NetBSD: iterate.c,v 1.3 2020/12/02 13:53:50 wiz Exp $ */
/*-
* Copyright (c) 2007 Joerg Sonnenberger <[email protected]>.
@@ -45,6 +45,34 @@
#include "lib.h"
/*
+ * We define a couple of different caches to hold frequently accessed data.
+ *
+ * Firstly, we cache the results of readdir() on the package database directory
+ * when using iterate_pkg_db_cached(). This helps a lot during recursive calls
+ * and avoids exponential system calls, but is not suitable for situations
+ * where the database directory may be updated, for example during installs.
+ * In those situations the regular iterate_pkg_db() must be used.
+ *
+ * Secondly, we have a cache for matches of pattern lookups, avoiding expensive
+ * pkg_match() calls each time.
+ */
+struct pkg_db_list {
+ char *pkgname;
+ SLIST_ENTRY(pkg_db_list) entries;
+};
+SLIST_HEAD(pkg_db_list_head, pkg_db_list);
+
+struct pkg_match_list {
+ char *pattern;
+ char *pkgname;
+ SLIST_ENTRY(pkg_match_list) entries;
+};
+SLIST_HEAD(pkg_match_list_head, pkg_match_list);
+
+static struct pkg_db_list_head pkg_list_cache;
+static struct pkg_match_list_head pkg_match_cache[PKG_HASH_SIZE];
+
+/*
* Generic iteration function:
* - get new entries from srciter, stop on NULL
* - call matchiter for those entries, stop on non-null return value.
@@ -167,6 +195,72 @@ iterate_pkg_db(int (*matchiter)(const ch
return retval;
}
+struct pkg_db_iter_arg {
+ struct pkg_db_list_head head;
+ struct pkg_db_list *list;
+};
+
+static const char *
+pkg_db_iter_cached(void *cookie)
+{
+ struct pkg_db_iter_arg *arg = cookie;
+
+ if (arg->list == NULL)
+ arg->list = SLIST_FIRST(&arg->head);
+ else
+ arg->list = SLIST_NEXT(arg->list, entries);
+
+ if (arg->list != NULL)
+ return arg->list->pkgname;
+
+ return NULL;
+}
+
+/*
+ * Call matchiter for every installed package, using cached data to
+ * significantly increase performance during recursive calls.
+ *
+ * This is not suitable for every situation, for example when finding new
+ * matches after package installation/removal. In those situations the
+ * regular iterate_pkg_db() must be used.
+ */
+static int
+iterate_pkg_db_cached(int (*matchiter)(const char *, void *), void *cookie)
+{
+ DIR *dirp;
+ struct pkg_db_iter_arg arg;
+ struct pkg_db_list *pkg;
+ const char *pkgdir;
+ int retval;
+
+ if (SLIST_EMPTY(&pkg_list_cache)) {
+ SLIST_INIT(&pkg_list_cache);
+
+ if ((dirp = opendir(pkgdb_get_dir())) == NULL) {
+ if (errno == ENOENT)
+ return 0; /* Empty pkgdb */
+ return -1;
+ }
+
+ while ((pkgdir = pkg_db_iter(dirp)) != NULL) {
+ pkg = xmalloc(sizeof(struct pkg_db_list));
+ pkg->pkgname = xstrdup(pkgdir);
+ SLIST_INSERT_HEAD(&pkg_list_cache, pkg, entries);
+ }
+
+ if (closedir(dirp) == -1)
+ return -1;
+ }
+
+ arg.head = pkg_list_cache;
+ arg.list = NULL;
+
+ retval = iterate_pkg_generic_src(matchiter, cookie,
+ pkg_db_iter_cached, &arg);
+
+ return retval;
+}
+
static int
match_by_basename(const char *pkg, void *cookie)
{
@@ -189,7 +283,7 @@ match_by_pattern(const char *pkg, void *
{
const char *pattern = cookie;
- return pkg_match(pattern, pkg);
+ return pkg_match(pattern, pkg);
}
struct add_matching_arg {
@@ -287,20 +381,55 @@ match_best_installed(const char *pkg, vo
/*
* Returns a copy of the name of best matching package.
* If no package matched the pattern or an error occured, return NULL.
+ *
+ * If use_cached is set, return a cached match entry if it exists, and also use
+ * the iterate_pkg_db cache, otherwise clear any matching cache entry and use
+ * regular iterate_pkg_db().
*/
char *
-find_best_matching_installed_pkg(const char *pattern)
+find_best_matching_installed_pkg(const char *pattern, int use_cached)
{
struct best_installed_match_arg arg;
+ struct pkg_match_list *pkg;
+ int idx = PKG_HASH_ENTRY(pattern), rv;
+
+ if (pattern == NULL)
+ return NULL;
+
+ SLIST_FOREACH(pkg, &pkg_match_cache[idx], entries) {
+ if (strcmp(pattern, pkg->pattern) == 0) {
+ if (use_cached)
+ return xstrdup(pkg->pkgname);
+ SLIST_REMOVE(&pkg_match_cache[idx], pkg,
+ pkg_match_list, entries);
+ free(pkg->pattern);
+ free(pkg->pkgname);
+ free(pkg);
+ break;
+ }
+ }
arg.pattern = pattern;
arg.best_current_match = NULL;
- if (iterate_pkg_db(match_best_installed, &arg) == -1) {
+ if (use_cached)
+ rv = iterate_pkg_db_cached(match_best_installed, &arg);
+ else
+ rv = iterate_pkg_db(match_best_installed, &arg);
+
+ if (rv == -1) {
warnx("could not process pkgdb");
return NULL;
}
+ if (arg.best_current_match != NULL) {
+ pkg = xmalloc(sizeof(struct pkg_match_list));
+ pkg->pattern = xstrdup(pattern);
+ pkg->pkgname = xstrdup(arg.best_current_match);
+ SLIST_INSERT_HEAD(&pkg_match_cache[idx],
+ pkg, entries);
+ }
+
return arg.best_current_match;
}
@@ -317,7 +446,7 @@ match_and_call(const char *pkg, void *co
if (pkg_match(arg->pattern, pkg) == 1) {
return (*arg->call_fn)(pkg, arg->cookie);
- } else
+ } else
return 0;
}
@@ -460,7 +589,7 @@ match_file_and_call(const char *filename
if (ret == 1)
return (*arg->call_fn)(filename, arg->cookie);
- else
+ else
return 0;
}
Index: src/external/bsd/pkg_install/dist/lib/pkgdb.c
diff -u src/external/bsd/pkg_install/dist/lib/pkgdb.c:1.2 src/external/bsd/pkg_install/dist/lib/pkgdb.c:1.3
--- src/external/bsd/pkg_install/dist/lib/pkgdb.c:1.2 Thu Apr 20 13:18:23 2017
+++ src/external/bsd/pkg_install/dist/lib/pkgdb.c Wed Dec 2 13:53:50 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: pkgdb.c,v 1.2 2017/04/20 13:18:23 joerg Exp $ */
+/* $NetBSD: pkgdb.c,v 1.3 2020/12/02 13:53:50 wiz Exp $ */
#if HAVE_CONFIG_H
#include "config.h"
@@ -7,7 +7,7 @@
#if HAVE_SYS_CDEFS_H
#include <sys/cdefs.h>
#endif
-__RCSID("$NetBSD: pkgdb.c,v 1.2 2017/04/20 13:18:23 joerg Exp $");
+__RCSID("$NetBSD: pkgdb.c,v 1.3 2020/12/02 13:53:50 wiz Exp $");
/*-
* Copyright (c) 1999-2010 The NetBSD Foundation, Inc.
@@ -70,12 +70,9 @@ __RCSID("$NetBSD: pkgdb.c,v 1.2 2017/04/
* Where we put logging information by default if PKG_DBDIR is unset.
*/
#ifndef DEF_LOG_DIR
-#define DEF_LOG_DIR "/var/db/pkg"
+#define DEF_LOG_DIR PREFIX "/pkgdb"
#endif
-/* just in case we change the environment variable name */
-#define PKG_DBDIR "PKG_DBDIR"
-
static DB *pkgdbp;
static char pkgdb_dir_default[] = DEF_LOG_DIR;
static char *pkgdb_dir = pkgdb_dir_default;
@@ -303,8 +300,21 @@ pkgdb_refcount_dir(void)
const char *
pkgdb_get_dir(void)
{
+ /* Except for the return at this end, this code is for
+ migration from the previous location /var/db/pkg to the new
+ default (December 2020). */
+
+ struct stat sb;
+ if (strcmp(pkgdb_dir, DEF_LOG_DIR) == 0 &&
+ stat(pkgdb_dir, &sb) == -1 && errno == ENOENT &&
+ stat("/var/db/pkg", &sb) == 0) {
+ errx(EXIT_FAILURE,
+ "The default PKG_DBDIR has changed, but this installation still uses the old one.\n"
+ "Please move the database and re-run this command:\n"
+ "\tmv /var/db/pkg " DEF_LOG_DIR);
+ }
- return pkgdb_dir;
+ return pkgdb_dir;
}
/*
Index: src/external/bsd/pkg_install/dist/lib/lib.h
diff -u src/external/bsd/pkg_install/dist/lib/lib.h:1.9 src/external/bsd/pkg_install/dist/lib/lib.h:1.10
--- src/external/bsd/pkg_install/dist/lib/lib.h:1.9 Sun Mar 25 04:04:36 2018
+++ src/external/bsd/pkg_install/dist/lib/lib.h Wed Dec 2 13:53:50 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: lib.h,v 1.9 2018/03/25 04:04:36 sevan Exp $ */
+/* $NetBSD: lib.h,v 1.10 2020/12/02 13:53:50 wiz Exp $ */
/* from FreeBSD Id: lib.h,v 1.25 1997/10/08 07:48:03 charnier Exp */
@@ -231,6 +231,25 @@ typedef struct _lpkg_t {
TAILQ_HEAD(_lpkg_head_t, _lpkg_t);
typedef struct _lpkg_head_t lpkg_head_t;
+/*
+ * To improve performance when handling lists containing a large number of
+ * packages, it can be beneficial to use hashed lookups to avoid excessive
+ * strcmp() calls when searching for existing entries.
+ *
+ * The simple hashing function below uses the first 3 characters of either a
+ * pattern match or package name (as they are guaranteed to exist).
+ *
+ * Based on pkgsrc package names across the tree, this can still result in
+ * somewhat uneven distribution due to high numbers of packages beginning with
+ * "p5-", "php", "py-" etc, and so there are diminishing returns when trying to
+ * use a hash size larger than around 16 or so.
+ */
+#define PKG_HASH_SIZE 16
+#define PKG_HASH_ENTRY(x) (((unsigned char)(x)[0] \
+ + (unsigned char)(x)[1] * 257 \
+ + (unsigned char)(x)[2] * 65537) \
+ & (PKG_HASH_SIZE - 1))
+
struct pkg_vulnerabilities {
size_t entries;
char **vulnerability;
@@ -251,7 +270,7 @@ int some_installed_package_conflicts_wit
/* Prototypes */
/* Misc */
-void show_version(void);
+void show_version(void) __attribute__ ((noreturn));
int fexec(const char *, ...);
int fexec_skipempty(const char *, ...);
int fcexec(const char *, const char *, ...);
@@ -287,7 +306,7 @@ int iterate_pkg_db(int (*)(const char *,
int add_installed_pkgs_by_basename(const char *, lpkg_head_t *);
int add_installed_pkgs_by_pattern(const char *, lpkg_head_t *);
-char *find_best_matching_installed_pkg(const char *);
+char *find_best_matching_installed_pkg(const char *, int);
char *find_best_matching_file(const char *, const char *, int, int);
int match_installed_pkgs(const char *, int (*)(const char *, void *), void *);
int match_local_files(const char *, int, int, const char *, int (*cb)(const char *, void *), void *);
Index: src/external/bsd/pkg_install/dist/lib/license.c
diff -u src/external/bsd/pkg_install/dist/lib/license.c:1.9 src/external/bsd/pkg_install/dist/lib/license.c:1.10
--- src/external/bsd/pkg_install/dist/lib/license.c:1.9 Sun Oct 13 21:56:14 2019
+++ src/external/bsd/pkg_install/dist/lib/license.c Wed Dec 2 13:53:50 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: license.c,v 1.9 2019/10/13 21:56:14 joerg Exp $ */
+/* $NetBSD: license.c,v 1.10 2020/12/02 13:53:50 wiz Exp $ */
/*-
* Copyright (c) 2009 Joerg Sonnenberger <[email protected]>.
@@ -46,6 +46,7 @@
#define HASH_SIZE 521
const char *default_acceptable_licenses =
+ "afl-3.0 "
"apache-1.1 apache-2.0 "
"arphic-public "
"artistic artistic-2.0 "
Index: src/external/bsd/pkg_install/dist/lib/plist.c
diff -u src/external/bsd/pkg_install/dist/lib/plist.c:1.3 src/external/bsd/pkg_install/dist/lib/plist.c:1.4
--- src/external/bsd/pkg_install/dist/lib/plist.c:1.3 Mon Sep 7 00:36:53 2020
+++ src/external/bsd/pkg_install/dist/lib/plist.c Wed Dec 2 13:53:50 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: plist.c,v 1.3 2020/09/07 00:36:53 christos Exp $ */
+/* $NetBSD: plist.c,v 1.4 2020/12/02 13:53:50 wiz Exp $ */
#if HAVE_CONFIG_H
#include "config.h"
@@ -7,7 +7,7 @@
#if HAVE_SYS_CDEFS_H
#include <sys/cdefs.h>
#endif
-__RCSID("$NetBSD: plist.c,v 1.3 2020/09/07 00:36:53 christos Exp $");
+__RCSID("$NetBSD: plist.c,v 1.4 2020/12/02 13:53:50 wiz Exp $");
/*
* FreeBSD install - a package for the installation and maintainance
@@ -700,7 +700,7 @@ delete_with_parents(const char *fname, B
if (remove(fname)) {
if (!ign_err && (!ign_nonempty || errno != ENOTEMPTY))
- warnx("Couldn't remove %s", fname);
+ warn("Couldn't remove %s", fname);
return 0;
}
cp = xstrdup(fname);
Index: src/external/bsd/pkg_install/dist/lib/vulnerabilities-file.c
diff -u src/external/bsd/pkg_install/dist/lib/vulnerabilities-file.c:1.3 src/external/bsd/pkg_install/dist/lib/vulnerabilities-file.c:1.4
--- src/external/bsd/pkg_install/dist/lib/vulnerabilities-file.c:1.3 Sun Mar 25 04:04:36 2018
+++ src/external/bsd/pkg_install/dist/lib/vulnerabilities-file.c Wed Dec 2 13:53:50 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: vulnerabilities-file.c,v 1.3 2018/03/25 04:04:36 sevan Exp $ */
+/* $NetBSD: vulnerabilities-file.c,v 1.4 2020/12/02 13:53:50 wiz Exp $ */
/*-
* Copyright (c) 2008, 2010 Joerg Sonnenberger <[email protected]>.
@@ -38,7 +38,7 @@
#if HAVE_SYS_CDEFS_H
#include <sys/cdefs.h>
#endif
-__RCSID("$NetBSD: vulnerabilities-file.c,v 1.3 2018/03/25 04:04:36 sevan Exp $");
+__RCSID("$NetBSD: vulnerabilities-file.c,v 1.4 2020/12/02 13:53:50 wiz Exp $");
#if HAVE_SYS_STAT_H
#include <sys/stat.h>
@@ -77,6 +77,7 @@ static const char pgp_msg_end[] = "-----
static const char pkcs7_begin[] = "-----BEGIN PKCS7-----\n";
static const char pkcs7_end[] = "-----END PKCS7-----\n";
+#ifndef BOOTSTRAP
static struct archive *
prepare_raw_file(void)
{
@@ -90,6 +91,7 @@ prepare_raw_file(void)
archive_read_support_format_raw(a);
return a;
}
+#endif
static void
verify_signature_pkcs7(const char *input)
Index: src/external/bsd/pkg_install/dist/lib/version.h
diff -u src/external/bsd/pkg_install/dist/lib/version.h:1.15 src/external/bsd/pkg_install/dist/lib/version.h:1.16
--- src/external/bsd/pkg_install/dist/lib/version.h:1.15 Sun Oct 13 21:56:14 2019
+++ src/external/bsd/pkg_install/dist/lib/version.h Wed Dec 2 13:53:50 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: version.h,v 1.15 2019/10/13 21:56:14 joerg Exp $ */
+/* $NetBSD: version.h,v 1.16 2020/12/02 13:53:50 wiz Exp $ */
/*
* Copyright (c) 2001 Thomas Klausner. All rights reserved.
@@ -27,6 +27,6 @@
#ifndef _INST_LIB_VERSION_H_
#define _INST_LIB_VERSION_H_
-#define PKGTOOLS_VERSION 20191008
+#define PKGTOOLS_VERSION 20200828
#endif /* _INST_LIB_VERSION_H_ */