Radish alpha
H
rad:z3QDZAW2FAfuLvihrhiyDC9fAD8G9
HardenedBSD Package Manager
Radicle
Git
pkgbase: add a pkgbase structure & functions
Baptiste Daroussin committed 1 year ago
commit 8805cf59fa561fc87a72f72cd29e6b83641adc5d
parent a7148a7
6 files changed +161 -101
modified libpkg/Makefile.autosetup
@@ -37,7 +37,7 @@ SRCS= backup_lib.c \
	pkg_abi_macho.c \
	binfmt_macho.c \
	ssh.c \
-
	system_shlibs.c \
+
	pkgbase.c \
	pkg_arch.c \
	pkg_cudf.c \
	pkg_jobs_universe.c  pkg_printf.c \
modified libpkg/libpkg.ver
@@ -202,6 +202,10 @@ global:
	pkg_vfprintf;
	pkg_vprintf;
	pkg_vsnprintf;
+
	pkgbase_free;
+
	pkgbase_new;
+
	pkgbase_provide;
+
	pkgbase_provide_shlib;
	pkgdb_access;
	pkgdb_access2;
	pkgdb_add_annotation;
modified libpkg/pkg.h.in
@@ -128,6 +128,8 @@ struct pkg_plugin;

struct pkg_manifest_parser;

+
struct pkg_base;
+

typedef struct ucl_object_s pkg_object;
typedef void * pkg_iter;

@@ -1731,6 +1733,10 @@ struct pkg_stringlist_iterator *pkg_stringlist_iterator(struct pkg_stringlist *l
const char *pkg_stringlist_next(struct pkg_stringlist_iterator *it);
struct pkg_el *pkg_get_element(struct pkg *p, pkg_attr a);
pkg_kvl_t *pkg_external_libs_version(void);
+
struct pkgbase *pkgbase_new(struct pkgdb *db);
+
bool pkgbase_provide_shlib(struct pkgbase *, const char *shlib);
+
bool pkgbase_provide(struct pkgbase *, const char *shlib);
+
void pkgbase_free(struct pkgbase *);

static inline void
pkg_get_s(struct pkg *p, pkg_attr a, const char **val)
added libpkg/pkgbase.c
@@ -0,0 +1,143 @@
+
/*-
+
 * Copyright (c) 1998 John D. Polstra
+
 * Copyright (c) 2012 Matthew Seaman <matthew@FreeBSD.org>
+
 * Copyright (c) 2024 The FreeBSD Foundation
+
 *
+
 * This software was developed in part by Isaac Freund <ifreund@freebsdfoundation.org>
+
 * under sponsorship from the FreeBSD Foundation.
+
 *
+
 * SPDX-License-Identifier: BSD-2-Clause
+
 */
+

+
#include <assert.h>
+
#include <ctype.h>
+
#include <dirent.h>
+
#include <errno.h>
+
#include <string.h>
+

+
#include "pkg.h"
+
#include "pkghash.h"
+
#include "private/event.h"
+
#include "private/pkg.h"
+
#include "private/pkgdb.h"
+
#include "xmalloc.h"
+

+
struct pkgbase {
+
	struct pkghash *system_shlibs;
+
	/*
+
	 * unused yet but will be in the future when we will start using
+
	 * provides/requires in pkgbase
+
	 */
+
	struct pkghash *provides;
+
};
+

+
static int
+
scan_dir_for_shlibs(pkghash **shlib_list, const char *dir,
+
    enum pkg_shlib_flags flags)
+
{
+
	DIR *dirp= opendir(dir);
+
	if (dirp == NULL) {
+
		if (errno == ENOENT) {
+
			return (EPKG_OK);
+
		}
+
		pkg_errno("Failed to open '%s' to scan for shared libraries", dir);
+
		return (EPKG_FATAL);
+
	}
+

+
	struct dirent *dp;
+
	while ((dp = readdir(dirp)) != NULL) {
+
		/* Only regular files and sym-links. On some
+
		   filesystems d_type is not set, on these the d_type
+
		   field will be DT_UNKNOWN. */
+
		if (dp->d_type != DT_REG && dp->d_type != DT_LNK &&
+
		    dp->d_type != DT_UNKNOWN)
+
			continue;
+

+
		int len = strlen(dp->d_name);
+
		/* Name can't be shorter than "libx.so" */
+
		if (len < 7 || strncmp(dp->d_name, "lib", 3) != 0)
+
			continue;
+

+
		const char *vers = dp->d_name + len;
+
		while (vers > dp->d_name &&
+
		       (isdigit(*(vers-1)) || *(vers-1) == '.'))
+
			vers--;
+
		if (vers == dp->d_name + len) {
+
			if (strncmp(vers - 3, ".so", 3) != 0)
+
				continue;
+
		} else if (vers < dp->d_name + 3 ||
+
		    strncmp(vers - 3, ".so.", 4) != 0)
+
			continue;
+

+
		/* We have a valid shared library name. */
+
		char *full = pkg_shlib_name_with_flags(dp->d_name, flags);
+
		pkghash_safe_add(*shlib_list, full, NULL, NULL);
+
		free(full);
+
	}
+

+
	closedir(dirp);
+

+
	return (EPKG_OK);
+
}
+

+
static struct {
+
	const char *dir;
+
	enum pkg_shlib_flags flags;
+
} system_shlib_table[] = {
+
	{"/lib", PKG_SHLIB_FLAGS_NONE },
+
	{"/usr/lib", PKG_SHLIB_FLAGS_NONE },
+
	{"/usr/lib32", PKG_SHLIB_FLAGS_COMPAT_32 },
+
};
+

+
int
+
scan_system_shlibs(pkghash **system_shlibs, const char *rootdir)
+
{
+
	for (int i = 0; i < NELEM(system_shlib_table); i++) {
+
		char *dir;
+
		if (rootdir != NULL) {
+
			xasprintf(&dir, "%s%s", rootdir, system_shlib_table[i].dir);
+
		} else {
+
			dir = xstrdup(system_shlib_table[i].dir);
+
		}
+
		int ret = scan_dir_for_shlibs(system_shlibs, dir, system_shlib_table[i].flags);
+
		free(dir);
+
		if (ret != EPKG_OK) {
+
			return (ret);
+
		}
+
	}
+

+
	return (EPKG_OK);
+
}
+

+
struct pkgbase *
+
pkgbase_new(struct pkgdb *db)
+
{
+
	struct pkgbase *pb = xcalloc(1, sizeof(*pb));
+

+
	if (!pkgdb_file_exists(db, "/usr/bin/uname"))
+
		scan_system_shlibs(&pb->system_shlibs, ctx.pkg_rootdir);
+

+
	return (pb);
+
}
+

+
void
+
pkgbase_free(struct pkgbase *pb)
+
{
+
	if (pb == NULL)
+
		return;
+
	pkghash_destroy(pb->system_shlibs);
+
	pkghash_destroy(pb->provides);
+
	free(pb);
+
}
+

+
bool
+
pkgbase_provide_shlib(struct pkgbase *pb, const char *shlib)
+
{
+
	return (pkghash_get(pb->system_shlibs, shlib) != NULL);
+
}
+

+
bool
+
pkgbase_provide(struct pkgbase *pb, const char *provide)
+
{
+
	return (pkghash_get(pb->provides, provide) != NULL);
+
}
deleted libpkg/system_shlibs.c
@@ -1,100 +0,0 @@
-
/*-
-
 * Copyright (c) 1998 John D. Polstra
-
 * Copyright (c) 2012 Matthew Seaman <matthew@FreeBSD.org>
-
 * Copyright (c) 2024 The FreeBSD Foundation
-
 *
-
 * This software was developed in part by Isaac Freund <ifreund@freebsdfoundation.org>
-
 * under sponsorship from the FreeBSD Foundation.
-
 *
-
 * SPDX-License-Identifier: BSD-2-Clause
-
 */
-

-
#include <assert.h>
-
#include <ctype.h>
-
#include <dirent.h>
-
#include <errno.h>
-
#include <string.h>
-

-
#include "pkg.h"
-
#include "pkghash.h"
-
#include "private/event.h"
-
#include "private/pkg.h"
-
#include "xmalloc.h"
-

-
static int
-
scan_dir_for_shlibs(pkghash **shlib_list, const char *dir,
-
    enum pkg_shlib_flags flags)
-
{
-
	DIR *dirp= opendir(dir);
-
	if (dirp == NULL) {
-
		if (errno == ENOENT) {
-
			return (EPKG_OK);
-
		}
-
		pkg_errno("Failed to open '%s' to scan for shared libraries", dir);
-
		return (EPKG_FATAL);
-
	}
-

-
	struct dirent *dp;
-
	while ((dp = readdir(dirp)) != NULL) {
-
		/* Only regular files and sym-links. On some
-
		   filesystems d_type is not set, on these the d_type
-
		   field will be DT_UNKNOWN. */
-
		if (dp->d_type != DT_REG && dp->d_type != DT_LNK &&
-
		    dp->d_type != DT_UNKNOWN)
-
			continue;
-

-
		int len = strlen(dp->d_name);
-
		/* Name can't be shorter than "libx.so" */
-
		if (len < 7 || strncmp(dp->d_name, "lib", 3) != 0)
-
			continue;
-

-
		const char *vers = dp->d_name + len;
-
		while (vers > dp->d_name &&
-
		       (isdigit(*(vers-1)) || *(vers-1) == '.'))
-
			vers--;
-
		if (vers == dp->d_name + len) {
-
			if (strncmp(vers - 3, ".so", 3) != 0)
-
				continue;
-
		} else if (vers < dp->d_name + 3 ||
-
		    strncmp(vers - 3, ".so.", 4) != 0)
-
			continue;
-

-
		/* We have a valid shared library name. */
-
		char *full = pkg_shlib_name_with_flags(dp->d_name, flags);
-
		pkghash_safe_add(*shlib_list, full, NULL, NULL);
-
		free(full);
-
	}
-

-
	closedir(dirp);
-

-
	return (EPKG_OK);
-
}
-

-
static struct {
-
	const char *dir;
-
	enum pkg_shlib_flags flags;
-
} system_shlib_table[] = {
-
	{"/lib", PKG_SHLIB_FLAGS_NONE },
-
	{"/usr/lib", PKG_SHLIB_FLAGS_NONE },
-
	{"/usr/lib32", PKG_SHLIB_FLAGS_COMPAT_32 },
-
};
-

-
int
-
scan_system_shlibs(pkghash **system_shlibs, const char *rootdir)
-
{
-
	for (int i = 0; i < NELEM(system_shlib_table); i++) {
-
		char *dir;
-
		if (rootdir != NULL) {
-
			xasprintf(&dir, "%s%s", rootdir, system_shlib_table[i].dir);
-
		} else {
-
			dir = xstrdup(system_shlib_table[i].dir);
-
		}
-
		int ret = scan_dir_for_shlibs(system_shlibs, dir, system_shlib_table[i].flags);
-
		free(dir);
-
		if (ret != EPKG_OK) {
-
			return (ret);
-
		}
-
	}
-

-
	return (EPKG_OK);
-
}
modified src/check.c
@@ -41,6 +41,7 @@ check_deps(struct pkgdb *db, struct pkg *p, deps_entries *dh, bool noinstall, xs
	int nbpkgs = 0;
	struct pkg_stringlist *sl = NULL;
	struct pkg_stringlist_iterator	*slit;
+
	struct pkgbase *pb;

	assert(db != NULL);
	assert(p != NULL);
@@ -60,8 +61,11 @@ check_deps(struct pkgdb *db, struct pkg *p, deps_entries *dh, bool noinstall, xs

	/* checking libraries required */
	pkg_get(p, PKG_ATTR_SHLIBS_REQUIRED, &sl);
+
	pb = pkgbase_new(db);
	slit = pkg_stringlist_iterator(sl);
	while ((buf = pkg_stringlist_next(slit))) {
+
		if (pkgbase_provide_shlib(pb, buf))
+
			continue;
		it = pkgdb_query_shlib_provide(db, buf);
		if (it != NULL && pkgdb_it_count(it) > 0) {
			pkgdb_it_free(it);
@@ -82,6 +86,8 @@ check_deps(struct pkgdb *db, struct pkg *p, deps_entries *dh, bool noinstall, xs
	pkg_get(p, PKG_ATTR_REQUIRES, &sl);
	slit = pkg_stringlist_iterator(sl);
	while ((buf = pkg_stringlist_next(slit))) {
+
		if (pkgbase_provide(pb, buf))
+
			continue;
		it = pkgdb_query_provide(db, buf);
		if (it != NULL && pkgdb_it_count(it) > 0) {
			pkgdb_it_free(it);
@@ -94,6 +100,7 @@ check_deps(struct pkgdb *db, struct pkg *p, deps_entries *dh, bool noinstall, xs
			pkg_fprintf(out->fp, "%n has a missing requirement: %S\n",
			    p, buf);
	}
+
	pkgbase_free(pb);
	free(slit);
	free(sl);