Radish alpha
H
rad:z3QDZAW2FAfuLvihrhiyDC9fAD8G9
HardenedBSD Package Manager
Radicle
Git
Update libpkg API to access both shlibs_required and shlibs_provided.
Matthew Seaman committed 13 years ago
commit 24ad4639ee6bee54f24f71dded228f50fe56cb08
parent 21f45ec
12 files changed +249 -90
modified libpkg/pkg.c
@@ -109,7 +109,8 @@ pkg_reset(struct pkg *pkg, pkg_t type)
	pkg_list_free(pkg, PKG_OPTIONS);
	pkg_list_free(pkg, PKG_USERS);
	pkg_list_free(pkg, PKG_GROUPS);
-
	pkg_list_free(pkg, PKG_SHLIBS);
+
	pkg_list_free(pkg, PKG_SHLIBS_REQUIRED);
+
	pkg_list_free(pkg, PKG_SHLIBS_PROVIDED);

	pkg->rowid = 0;
	pkg->type = type;
@@ -136,7 +137,8 @@ pkg_free(struct pkg *pkg)
	pkg_list_free(pkg, PKG_OPTIONS);
	pkg_list_free(pkg, PKG_USERS);
	pkg_list_free(pkg, PKG_GROUPS);
-
	pkg_list_free(pkg, PKG_SHLIBS);
+
	pkg_list_free(pkg, PKG_SHLIBS_REQUIRED);
+
	pkg_list_free(pkg, PKG_SHLIBS_PROVIDED);

	free(pkg);
}
@@ -453,12 +455,19 @@ pkg_options(struct pkg *pkg, struct pkg_option **o)
}

int
+
pkg_shlibs_required(struct pkg *pkg, struct pkg_shlib **s)
+
{
+
	assert(pkg != NULL);
+

+
	HASH_NEXT(pkg->shlibs_required, (*s));
+
}

-
pkg_shlibs(struct pkg *pkg, struct pkg_shlib **s)
+
int
+
pkg_shlibs_provided(struct pkg *pkg, struct pkg_shlib **s)
{
	assert(pkg != NULL);

-
	HASH_NEXT(pkg->shlibs, (*s));
+
	HASH_NEXT(pkg->shlibs_provided, (*s));
}

int
@@ -833,14 +842,38 @@ pkg_addoption(struct pkg *pkg, const char *key, const char *value)
}

int
-
pkg_addshlib(struct pkg *pkg, const char *name)
+
pkg_addshlib_required(struct pkg *pkg, const char *name)
+
{
+
	struct pkg_shlib *s = NULL;
+

+
	assert(pkg != NULL);
+
	assert(name != NULL && name[0] != '\0');
+

+
	HASH_FIND_STR(pkg->shlibs_required, __DECONST(char *, name), s);
+
	/* silently ignore duplicates in case of shlibs */
+
	if (s != NULL)
+
		return (EPKG_OK);
+

+
	pkg_shlib_new(&s);
+

+
	sbuf_set(&s->name, name);
+

+
	HASH_ADD_KEYPTR(hh, pkg->shlibs_required,
+
	    __DECONST(char *, pkg_shlib_name(s)),
+
	    strlen(pkg_shlib_name(s)), s);
+

+
	return (EPKG_OK);
+
}
+

+
int
+
pkg_addshlib_provided(struct pkg *pkg, const char *name)
{
	struct pkg_shlib *s = NULL;

	assert(pkg != NULL);
	assert(name != NULL && name[0] != '\0');

-
	HASH_FIND_STR(pkg->shlibs, __DECONST(char *, name), s);
+
	HASH_FIND_STR(pkg->shlibs_provided, __DECONST(char *, name), s);
	/* silently ignore duplicates in case of shlibs */
	if (s != NULL)
		return (EPKG_OK);
@@ -849,7 +882,8 @@ pkg_addshlib(struct pkg *pkg, const char *name)

	sbuf_set(&s->name, name);

-
	HASH_ADD_KEYPTR(hh, pkg->shlibs,__DECONST(char *, pkg_shlib_name(s)),
+
	HASH_ADD_KEYPTR(hh, pkg->shlibs_provided,
+
	    __DECONST(char *, pkg_shlib_name(s)),
	    strlen(pkg_shlib_name(s)), s);

	return (EPKG_OK);
@@ -877,8 +911,10 @@ pkg_list_count(struct pkg *pkg, pkg_list list)
		return (HASH_COUNT(pkg->users));
	case PKG_GROUPS:
		return (HASH_COUNT(pkg->groups));
-
	case PKG_SHLIBS:
-
		return (HASH_COUNT(pkg->shlibs));
+
	case PKG_SHLIBS_REQUIRED:
+
		return (HASH_COUNT(pkg->shlibs_required));
+
	case PKG_SHLIBS_PROVIDED:
+
		return (HASH_COUNT(pkg->shlibs_provided));
	}
	
	return (0);
@@ -923,9 +959,13 @@ pkg_list_free(struct pkg *pkg, pkg_list list) {
		HASH_FREE(pkg->groups, pkg_group, pkg_group_free);
		pkg->flags &= ~PKG_LOAD_GROUPS;
		break;
-
	case PKG_SHLIBS:
-
		HASH_FREE(pkg->shlibs, pkg_shlib, pkg_shlib_free);
-
		pkg->flags &= ~PKG_LOAD_SHLIBS;
+
	case PKG_SHLIBS_REQUIRED:
+
		HASH_FREE(pkg->shlibs_required, pkg_shlib, pkg_shlib_free);
+
		pkg->flags &= ~PKG_LOAD_SHLIBS_REQUIRED;
+
		break;
+
	case PKG_SHLIBS_PROVIDED:
+
		HASH_FREE(pkg->shlibs_provided, pkg_shlib, pkg_shlib_free);
+
		pkg->flags &= ~PKG_LOAD_SHLIBS_PROVIDED;
		break;
	}
}
modified libpkg/pkg.h.in
@@ -261,7 +261,8 @@ typedef enum {
	PKG_DIRS,
	PKG_USERS,
	PKG_GROUPS,
-
	PKG_SHLIBS
+
	PKG_SHLIBS_REQUIRED,
+
	PKG_SHLIBS_PROVIDED,
} pkg_list;

/**
@@ -568,7 +569,14 @@ int pkg_options(struct pkg *, struct pkg_option **option);
 * @param shlib must be set to NULL for the first call.
 * @return An error code
 */
-
int pkg_shlibs(struct pkg *pkg, struct pkg_shlib **shlib);
+
int pkg_shlibs_required(struct pkg *pkg, struct pkg_shlib **shlib);
+

+
/**
+
 * Iterates over the shared libraries provided by the package.
+
 * @param shlib must be set to NULL for the first call.
+
 * @return An error code
+
 */
+
int pkg_shlibs_provided(struct pkg *pkg, struct pkg_shlib **shlib);

/**
 * Iterate over all of the files within the package pkg, ensuring the
@@ -726,10 +734,16 @@ int pkg_appendscript(struct pkg *pkg, const char *cmd, pkg_script type);
int pkg_addoption(struct pkg *pkg, const char *name, const char *value);

/**
-
 * Add a shared library
+
 * Add a shared library used by this package
+
 * @return An error code.
+
 */
+
int pkg_addshlib_required(struct pkg *pkg, const char *name);
+

+
/**
+
 * Add a shared library provided by this package
 * @return An error code.
 */
-
int pkg_addshlib(struct pkg *pkg, const char *name);
+
int pkg_addshlib_provided(struct pkg *pkg, const char *name);

/**
 * Parse a manifest and set the attributes of pkg accordingly.
@@ -898,22 +912,23 @@ struct pkgdb_it * pkgdb_search(struct pkgdb *db, const char *pattern,
 */
struct pkgdb_it * pkgdb_query_which(struct pkgdb *db, const char *path);

-
struct pkgdb_it * pkgdb_query_requires_shlib(struct pkgdb *db, const char *shlib);
-
struct pkgdb_it * pkgdb_query_provides_shlib(struct pkgdb *db, const char *shlib);
-

-
#define PKG_LOAD_BASIC		0
-
#define PKG_LOAD_DEPS		(1U << 0)
-
#define PKG_LOAD_RDEPS		(1U << 1)
-
#define PKG_LOAD_FILES		(1U << 2)
-
#define PKG_LOAD_SCRIPTS	(1U << 3)
-
#define PKG_LOAD_OPTIONS	(1U << 4)
-
#define PKG_LOAD_MTREE		(1U << 5)
-
#define PKG_LOAD_DIRS		(1U << 6)
-
#define PKG_LOAD_CATEGORIES	(1U << 7)
-
#define PKG_LOAD_LICENSES	(1U << 8)
-
#define PKG_LOAD_USERS		(1U << 9)
-
#define PKG_LOAD_GROUPS		(1U << 10)
-
#define PKG_LOAD_SHLIBS		(1U << 11)
+
struct pkgdb_it * pkgdb_query_shlib_required(struct pkgdb *db, const char *shlib);
+
struct pkgdb_it * pkgdb_query_shlib_provided(struct pkgdb *db, const char *shlib);
+

+
#define PKG_LOAD_BASIC			0
+
#define PKG_LOAD_DEPS			(1U << 0)
+
#define PKG_LOAD_RDEPS			(1U << 1)
+
#define PKG_LOAD_FILES			(1U << 2)
+
#define PKG_LOAD_SCRIPTS		(1U << 3)
+
#define PKG_LOAD_OPTIONS		(1U << 4)
+
#define PKG_LOAD_MTREE			(1U << 5)
+
#define PKG_LOAD_DIRS			(1U << 6)
+
#define PKG_LOAD_CATEGORIES		(1U << 7)
+
#define PKG_LOAD_LICENSES		(1U << 8)
+
#define PKG_LOAD_USERS			(1U << 9)
+
#define PKG_LOAD_GROUPS			(1U << 10)
+
#define PKG_LOAD_SHLIBS_REQUIRED	(1U << 11)
+
#define PKG_LOAD_SHLIBS_PROVIDED	(1U << 12)
/* Make sure new PKG_LOAD don't conflict with PKG_CONTAINS_* */

/**
modified libpkg/pkg_elf.c
@@ -99,7 +99,7 @@ add_shlibs_to_pkg(__unused void *actdata, struct pkg *pkg, const char *fpath,
{
	switch(filter_system_shlibs(name, NULL, 0)) {
	case EPKG_OK:		/* A non-system library */
-
		pkg_addshlib(pkg, name);
+
		pkg_addshlib_required(pkg, name);
		return (EPKG_OK);
	case EPKG_END:		/* A system library */
		return (EPKG_OK);
@@ -150,7 +150,7 @@ test_depends(void *actdata, struct pkg *pkg, const char *fpath,
	}

	if (shlibs)
-
		pkg_addshlib(pkg, name);
+
		pkg_addshlib_required(pkg, name);

	if ((it = pkgdb_query_which(db, pathbuf)) == NULL)
		return (EPKG_OK);
@@ -500,7 +500,7 @@ pkg_register_shlibs(struct pkg *pkg)

	pkg_config_bool(PKG_CONFIG_SHLIBS, &shlibs);

-
	pkg_list_free(pkg, PKG_SHLIBS);
+
	pkg_list_free(pkg, PKG_SHLIBS_REQUIRED);

	if (!shlibs)
		return (EPKG_OK);
modified libpkg/pkg_manifest.c
@@ -52,7 +52,8 @@
#define PKG_USERS -9
#define PKG_GROUPS -10
#define PKG_DIRECTORIES -11
-
#define PKG_SHLIBS -12
+
#define PKG_SHLIBS_REQUIRED -12
+
#define PKG_SHLIBS_PROVIDED -13

static int pkg_set_from_node(struct pkg *, yaml_node_t *, yaml_document_t *, int);
static int pkg_set_flatsize_from_node(struct pkg *, yaml_node_t *, yaml_document_t *, int);
@@ -96,7 +97,8 @@ static struct manifest_key {
	{ "groups", PKG_GROUPS, YAML_SEQUENCE_NODE, parse_sequence},
	/* compatibility with old format */
	{ "groups", PKG_GROUPS, YAML_MAPPING_NODE, parse_mapping},
-
	{ "shlibs", PKG_SHLIBS, YAML_SEQUENCE_NODE, parse_sequence},
+
	{ "shlibs_required", PKG_SHLIBS_REQUIRED, YAML_SEQUENCE_NODE, parse_sequence},
+
	{ "shlibs_provided", PKG_SHLIBS_PROVIDED, YAML_SEQUENCE_NODE, parse_sequence},
	{ NULL, -99, -99, NULL}
};

@@ -282,11 +284,18 @@ parse_sequence(struct pkg * pkg, yaml_node_t *node, yaml_document_t *doc,
			else
				pkg_emit_error("Skipping malformed dirs");
			break;
-
		case PKG_SHLIBS:
+
		case PKG_SHLIBS_REQUIRED:
			if (!is_valid_yaml_scalar(val))
-
				pkg_emit_error("Skipping malformed shared library");
+
				pkg_emit_error("Skipping malformed required shared library");
			else
-
				pkg_addshlib(pkg, val->data.scalar.value);
+
				pkg_addshlib_required(pkg, val->data.scalar.value);
+
			break;
+
		case PKG_SHLIBS_PROVIDED:
+
			if (!is_valid_yaml_scalar(val))
+
				pkg_emit_error("Skipping malformed provided shared library");
+
			else
+
				pkg_addshlib_provided(pkg, val->data.scalar.value);
+
			break;
		}
		++item;
	}
@@ -820,8 +829,13 @@ pkg_emit_manifest(struct pkg *pkg, char **dest)
		    pkg_group_name(group));

	seq = -1;
-
	while (pkg_shlibs(pkg, &shlib) == EPKG_OK)
-
		manifest_append_seqval(&doc, mapping, &seq, "shlibs",
+
	while (pkg_shlibs_required(pkg, &shlib) == EPKG_OK)
+
		manifest_append_seqval(&doc, mapping, &seq, "shlibs_required",
+
		    pkg_shlib_name(shlib));
+

+
	seq = -1;
+
	while (pkg_shlibs_provided(pkg, &shlib) == EPKG_OK)
+
		manifest_append_seqval(&doc, mapping, &seq, "shlibs_provided",
		    pkg_shlib_name(shlib));

	map = -1;
modified libpkg/pkg_repo.c
@@ -48,12 +48,12 @@
#include "private/thd_repo.h"

/* The package repo schema major revision */
-
#define REPO_SCHEMA_MAJOR 2
+
#define REPO_SCHEMA_MAJOR 3

/* The package repo schema minor revision.
   Minor schema changes don't prevent older pkgng
   versions accessing the repo */
-
#define REPO_SCHEMA_MINOR 1
+
#define REPO_SCHEMA_MINOR 0

#define REPO_SCHEMA_VERSION (REPO_SCHEMA_MAJOR * 1000 + REPO_SCHEMA_MINOR)

@@ -66,7 +66,8 @@ typedef enum _sql_prstmt_index {
	LIC2,
	OPTS,
	SHLIB1,
-
	SHLIB2,
+
	SHLIB_REQD,
+
	SHLIB_PROV,
	EXISTS,
	VERSION,
	DELETE,
@@ -123,12 +124,18 @@ static sql_prstmt sql_prepared_statements[PRSTMT_LAST] = {
		"INSERT OR IGNORE INTO shlibs(name) VALUES(?1)",
		"T",
	},
-
	[SHLIB2] = {
+
	[SHLIB_REQD] = {
		NULL,
		"INSERT OR ROLLBACK INTO pkg_shlibs_required(package_id, shlib_id) "
		"VALUES (?1, (SELECT id FROM shlibs WHERE name = ?2))",
		"IT",
	},
+
	[SHLIB_PROV] = {
+
		NULL,
+
		"INSERT OR ROLLBACK INTO pkg_shlibs_provided(package_id, shlib_id) "
+
		"VALUES (?1, (SELECT id FROM shlibs WHERE name = ?2))",
+
		"IT",
+
	},
	[EXISTS] = {
		NULL,
		"SELECT count(*) FROM packages WHERE cksum=?1",
@@ -855,12 +862,27 @@ pkg_create_repo(char *path, bool force, bool files,
		}

		shlib = NULL;
-
		while (pkg_shlibs(r->pkg, &shlib) == EPKG_OK) {
+
		while (pkg_shlibs_required(r->pkg, &shlib) == EPKG_OK) {
+
			const char *shlib_name = pkg_shlib_name(shlib);
+

+
			ret = run_prepared_statement(SHLIB1, shlib_name);
+
			if (ret == SQLITE_DONE)
+
			    ret = run_prepared_statement(SHLIB_REQD, package_id,
+
			        shlib_name);
+
			if (ret != SQLITE_DONE) {
+
				ERROR_SQLITE(sqlite);
+
				retcode = EPKG_FATAL;
+
				goto cleanup;
+
			}
+
		}
+

+
		shlib = NULL;
+
		while (pkg_shlibs_provided(r->pkg, &shlib) == EPKG_OK) {
			const char *shlib_name = pkg_shlib_name(shlib);

			ret = run_prepared_statement(SHLIB1, shlib_name);
			if (ret == SQLITE_DONE)
-
			    ret = run_prepared_statement(SHLIB2, package_id,
+
			    ret = run_prepared_statement(SHLIB_PROV, package_id,
			        shlib_name);
			if (ret != SQLITE_DONE) {
				ERROR_SQLITE(sqlite);
modified libpkg/pkgdb.c
@@ -1206,18 +1206,19 @@ static struct load_on_flag {
	int	flag;
	int	(*load)(struct pkgdb *db, struct pkg *p);
} load_on_flag[] = {
-
	{ PKG_LOAD_DEPS,	pkgdb_load_deps },
-
	{ PKG_LOAD_RDEPS,	pkgdb_load_rdeps },
-
	{ PKG_LOAD_FILES,	pkgdb_load_files },
-
	{ PKG_LOAD_DIRS,	pkgdb_load_dirs },
-
	{ PKG_LOAD_SCRIPTS,	pkgdb_load_scripts },
-
	{ PKG_LOAD_OPTIONS,	pkgdb_load_options },
-
	{ PKG_LOAD_MTREE,	pkgdb_load_mtree },
-
	{ PKG_LOAD_CATEGORIES,	pkgdb_load_category },
-
	{ PKG_LOAD_LICENSES,	pkgdb_load_license },
-
	{ PKG_LOAD_USERS,	pkgdb_load_user },
-
	{ PKG_LOAD_GROUPS,	pkgdb_load_group },
-
	{ PKG_LOAD_SHLIBS,	pkgdb_load_shlib },
+
	{ PKG_LOAD_DEPS,		pkgdb_load_deps },
+
	{ PKG_LOAD_RDEPS,		pkgdb_load_rdeps },
+
	{ PKG_LOAD_FILES,		pkgdb_load_files },
+
	{ PKG_LOAD_DIRS,		pkgdb_load_dirs },
+
	{ PKG_LOAD_SCRIPTS,		pkgdb_load_scripts },
+
	{ PKG_LOAD_OPTIONS,		pkgdb_load_options },
+
	{ PKG_LOAD_MTREE,		pkgdb_load_mtree },
+
	{ PKG_LOAD_CATEGORIES,		pkgdb_load_category },
+
	{ PKG_LOAD_LICENSES,		pkgdb_load_license },
+
	{ PKG_LOAD_USERS,		pkgdb_load_user },
+
	{ PKG_LOAD_GROUPS,		pkgdb_load_group },
+
	{ PKG_LOAD_SHLIBS_REQUIRED,	pkgdb_load_shlib_required },
+
	{ PKG_LOAD_SHLIBS_PROVIDED,	pkgdb_load_shlib_provided },
	{ -1,			NULL }
};

@@ -1427,7 +1428,7 @@ pkgdb_query_which(struct pkgdb *db, const char *path)
}

struct pkgdb_it *
-
pkgdb_query_requires_shlib(struct pkgdb *db, const char *shlib)
+
pkgdb_query_shlib_required(struct pkgdb *db, const char *shlib)
{
	sqlite3_stmt	*stmt;
	const char	 sql[] = ""
@@ -1452,7 +1453,7 @@ pkgdb_query_requires_shlib(struct pkgdb *db, const char *shlib)
}

struct pkgdb_it *
-
pkgdb_query_provides_shlib(struct pkgdb *db, const char *shlib)
+
pkgdb_query_shlib_provided(struct pkgdb *db, const char *shlib)
{
	sqlite3_stmt	*stmt;
	const char	 sql[] = ""
@@ -1815,7 +1816,7 @@ pkgdb_load_group(struct pkgdb *db, struct pkg *pkg)
}

int
-
pkgdb_load_shlib(struct pkgdb *db, struct pkg *pkg)
+
pkgdb_load_shlib_required(struct pkgdb *db, struct pkg *pkg)
{
	char		 sql[BUFSIZ];
	const char	*reponame = NULL;
@@ -1835,8 +1836,34 @@ pkgdb_load_shlib(struct pkgdb *db, struct pkg *pkg)
	} else
		sqlite3_snprintf(sizeof(sql), sql, basesql, "main", "main");

-
	return (load_val(db->sqlite, pkg, sql, PKG_LOAD_SHLIBS,
-
	    pkg_addshlib, PKG_SHLIBS));
+
	return (load_val(db->sqlite, pkg, sql, PKG_LOAD_SHLIBS_REQUIRED,
+
	    pkg_addshlib_required, PKG_SHLIBS_REQUIRED));
+
}
+

+

+
int
+
pkgdb_load_shlib_provided(struct pkgdb *db, struct pkg *pkg)
+
{
+
	char		 sql[BUFSIZ];
+
	const char	*reponame = NULL;
+
	const char	*basesql = ""
+
		"SELECT name "
+
		"FROM %Q.pkg_shlibs_provided, %Q.shlibs AS s "
+
		"WHERE package_id = ?1 "
+
			"AND shlib_id = s.id "
+
		"ORDER by name DESC";
+

+
	assert(db != NULL && pkg != NULL);
+

+
	if (pkg->type == PKG_REMOTE) {
+
		assert(db->type == PKGDB_REMOTE);
+
		pkg_get(pkg, PKG_REPONAME, &reponame);
+
		sqlite3_snprintf(sizeof(sql), sql, basesql, reponame, reponame);
+
	} else
+
		sqlite3_snprintf(sizeof(sql), sql, basesql, "main", "main");
+

+
	return (load_val(db->sqlite, pkg, sql, PKG_LOAD_SHLIBS_PROVIDED,
+
	    pkg_addshlib_provided, PKG_SHLIBS_PROVIDED));
}

int
@@ -1960,7 +1987,8 @@ typedef enum _sql_prstmt_index {
	SCRIPTS,
	OPTIONS,
	SHLIBS1,
-
	SHLIBS2,
+
	SHLIBS_REQD,
+
	SHLIBS_PROV,
	PRSTMT_LAST,
} sql_prstmt_index;

@@ -2076,12 +2104,18 @@ static sql_prstmt sql_prepared_statements[PRSTMT_LAST] = {
		"INSERT OR IGNORE INTO shlibs(name) VALUES(?1)",
		"T",
	},
-
	[SHLIBS2] = {
+
	[SHLIBS_REQD] = {
		NULL,
		"INSERT INTO pkg_shlibs_required(package_id, shlib_id) "
		"VALUES (?1, (SELECT id FROM shlibs WHERE name = ?2))",
		"IT",
	},
+
	[SHLIBS_PROV] = {
+
		NULL,
+
		"INSERT INTO pkg_shlibs_provided(package_id, shlib_id) "
+
		"VALUES (?1, (SELECT id FROM shlibs WHERE name = ?2))",
+
		"IT",
+
	},
	/* PRSTMT_LAST */
};

@@ -2437,7 +2471,9 @@ pkgdb_register_pkg(struct pkgdb *db, struct pkg *pkg, int complete)
	/*
	 * Insert shlibs
	 */
-
	if (pkgdb_update_shlibs(pkg, package_id, s) != EPKG_OK)
+
	if (pkgdb_update_shlibs_required(pkg, package_id, s) != EPKG_OK)
+
		goto cleanup;
+
	if (pkgdb_update_shlibs_provided(pkg, package_id, s) != EPKG_OK)
		goto cleanup;

	retcode = EPKG_OK;
@@ -2448,15 +2484,34 @@ pkgdb_register_pkg(struct pkgdb *db, struct pkg *pkg, int complete)
}

int
-
pkgdb_update_shlibs(struct pkg *pkg, int64_t package_id, sqlite3 *s)
+
pkgdb_update_shlibs_required(struct pkg *pkg, int64_t package_id, sqlite3 *s)
+
{
+
	struct pkg_shlib	*shlib = NULL;
+

+
	while (pkg_shlibs_required(pkg, &shlib) == EPKG_OK) {
+
		if (run_prstmt(SHLIBS1, pkg_shlib_name(shlib))
+
		    != SQLITE_DONE
+
		    ||
+
		    run_prstmt(SHLIBS_REQD, package_id, pkg_shlib_name(shlib))
+
		    != SQLITE_DONE) {
+
			ERROR_SQLITE(s);
+
			return (EPKG_FATAL);
+
		}
+
	}
+

+
	return (EPKG_OK);
+
}
+

+
int
+
pkgdb_update_shlibs_provided(struct pkg *pkg, int64_t package_id, sqlite3 *s)
{
	struct pkg_shlib	*shlib = NULL;

-
	while (pkg_shlibs(pkg, &shlib) == EPKG_OK) {
+
	while (pkg_shlibs_provided(pkg, &shlib) == EPKG_OK) {
		if (run_prstmt(SHLIBS1, pkg_shlib_name(shlib))
		    != SQLITE_DONE
		    ||
-
		    run_prstmt(SHLIBS2, package_id, pkg_shlib_name(shlib))
+
		    run_prstmt(SHLIBS_PROV, package_id, pkg_shlib_name(shlib))
		    != SQLITE_DONE) {
			ERROR_SQLITE(s);
			return (EPKG_FATAL);
@@ -2526,7 +2581,9 @@ pkgdb_reanalyse_shlibs(struct pkgdb *db, struct pkg *pkg)
			return (EPKG_FATAL);

		/* Save shlibs */
-
		ret = pkgdb_update_shlibs(pkg, package_id, s);
+
		ret = pkgdb_update_shlibs_required(pkg, package_id, s);
+
		if (ret == EPKG_OK)
+
			ret = pkgdb_update_shlibs_provided(pkg, package_id, s);
	}

	return (ret);
modified libpkg/private/pkg.h
@@ -1,6 +1,7 @@
/*-
 * Copyright (c) 2011-2012 Baptiste Daroussin <bapt@FreeBSD.org>
 * Copyright (c) 2011-2012 Julien Laffaye <jlaffaye@FreeBSD.org>
+
 * Copyright (c) 2013 Matthew Seaman <matthew@FreeBSD.org>
 * All rights reserved.
 * 
 * Redistribution and use in source and binary forms, with or without
@@ -112,7 +113,8 @@ struct pkg {
	struct pkg_option *options;
	struct pkg_user *users;
	struct pkg_group *groups;
-
	struct pkg_shlib *shlibs;
+
	struct pkg_shlib *shlibs_required;
+
	struct pkg_shlib *shlibs_provided;
	unsigned       	 flags;
	int64_t		 rowid;
	int64_t		 time;
@@ -359,10 +361,12 @@ int pkgdb_load_category(struct pkgdb *db, struct pkg *pkg);
int pkgdb_load_license(struct pkgdb *db, struct pkg *pkg);
int pkgdb_load_user(struct pkgdb *db, struct pkg *pkg);
int pkgdb_load_group(struct pkgdb *db, struct pkg *pkg);
-
int pkgdb_load_shlib(struct pkgdb *db, struct pkg *pkg);
+
int pkgdb_load_shlib_required(struct pkgdb *db, struct pkg *pkg);
+
int pkgdb_load_shlib_provided(struct pkgdb *db, struct pkg *pkg);

int pkgdb_register_pkg(struct pkgdb *db, struct pkg *pkg, int complete);
-
int pkgdb_update_shlibs(struct pkg *pkg, int64_t package_id, sqlite3 *s);
+
int pkgdb_update_shlibs_required(struct pkg *pkg, int64_t package_id, sqlite3 *s);
+
int pkgdb_update_shlibs_provided(struct pkg *pkg, int64_t package_id, sqlite3 *s);
int pkgdb_register_finale(struct pkgdb *db, int retcode);

int pkg_register_shlibs(struct pkg *pkg);
modified pkg/create.c
@@ -75,7 +75,8 @@ pkg_create_matches(int argc, char **argv, match_t match, pkg_formats fmt,
	int query_flags = PKG_LOAD_DEPS | PKG_LOAD_FILES |
	    PKG_LOAD_CATEGORIES | PKG_LOAD_DIRS | PKG_LOAD_SCRIPTS |
	    PKG_LOAD_OPTIONS | PKG_LOAD_MTREE | PKG_LOAD_LICENSES |
-
	    PKG_LOAD_USERS | PKG_LOAD_GROUPS | PKG_LOAD_SHLIBS;
+
	    PKG_LOAD_USERS | PKG_LOAD_GROUPS | PKG_LOAD_SHLIBS_REQUIRED |
+
	    PKG_LOAD_SHLIBS_PROVIDED;
	struct pkg_head head = STAILQ_HEAD_INITIALIZER(head);
	struct pkg_entry *e = NULL;
	char pkgpath[MAXPATHLEN];
modified pkg/query.c
@@ -52,7 +52,7 @@ static struct query_flags accepted_query_flags[] = {
	{ 'L', "",		1, PKG_LOAD_LICENSES },
	{ 'U', "",		1, PKG_LOAD_USERS },
	{ 'G', "",		1, PKG_LOAD_GROUPS },
-
	{ 'B', "",		1, PKG_LOAD_SHLIBS },
+
	{ 'B', "",		1, PKG_LOAD_SHLIBS_REQUIRED },
	{ '?', "drCFODLUGB",	1, PKG_LOAD_BASIC },	/* dbflags handled in analyse_query_string() */
	{ '#', "drCFODLUGB",	1, PKG_LOAD_BASIC },	/* dbflags handled in analyse_query_string() */
	{ 's', "hb",		0, PKG_LOAD_BASIC },
@@ -186,7 +186,7 @@ format_str(struct pkg *pkg, struct sbuf *dest, const char *qstr, void *data)
					sbuf_printf(dest, "%d", pkg_list_count(pkg, PKG_GROUPS) > 0);
					break;
				case 'B':
-
					sbuf_printf(dest, "%d", pkg_list_count(pkg, PKG_SHLIBS) > 0);
+
					sbuf_printf(dest, "%d", pkg_list_count(pkg, PKG_SHLIBS_REQUIRED) > 0);
					break;
				}
				break;
@@ -221,7 +221,7 @@ format_str(struct pkg *pkg, struct sbuf *dest, const char *qstr, void *data)
					sbuf_printf(dest, "%d", pkg_list_count(pkg, PKG_GROUPS));
					break;
				case 'B':
-
					sbuf_printf(dest, "%d", pkg_list_count(pkg, PKG_SHLIBS));
+
					sbuf_printf(dest, "%d", pkg_list_count(pkg, PKG_SHLIBS_REQUIRED));
					break;
				}
				break;
@@ -401,7 +401,7 @@ print_query(struct pkg *pkg, char *qstr, char multiline)
		}
		break;
	case 'B':
-
		while (pkg_shlibs(pkg, &shlib) == EPKG_OK) {
+
		while (pkg_shlibs_required(pkg, &shlib) == EPKG_OK) {
			format_str(pkg, output, qstr, shlib);
			printf("%s\n", sbuf_data(output));
		}
@@ -537,7 +537,7 @@ format_sql_condition(const char *str, struct sbuf *sqlcond, bool for_remote)
							sbuf_printf(sqlcond, "(SELECT COUNT(*) FROM %spkg_groups AS d WHERE d.package_id=p.id)", dbstr);
							break;
						case 'B':
-
							sbuf_printf(sqlcond, "(SELECT COUNT(*) FROM %spkg_shlibs AS d WHERE d.package_id=p.id)", dbstr);
+
							sbuf_printf(sqlcond, "(SELECT COUNT(*) FROM %spkg_shlibs_required AS d WHERE d.package_id=p.id)", dbstr);
							break;
						default:
							goto bad_option;
modified pkg/rquery.c
@@ -48,7 +48,7 @@ static struct query_flags accepted_rquery_flags[] = {
	{ 'C', "",		1, PKG_LOAD_CATEGORIES },
	{ 'O', "kv",		1, PKG_LOAD_OPTIONS },
	{ 'L', "",		1, PKG_LOAD_LICENSES },
-
	{ 'B', "",		1, PKG_LOAD_SHLIBS },
+
	{ 'B', "",		1, PKG_LOAD_SHLIBS_REQUIRED },
	{ '?', "drCOLB",	1, PKG_LOAD_BASIC },	/* dbflags handled in analyse_query_string() */
	{ '#', "drCOLB",	1, PKG_LOAD_BASIC },	/* dbflags handled in analyse_query_string() */
	{ 's', "hb",		0, PKG_LOAD_BASIC },
modified pkg/shlib.c
@@ -94,7 +94,7 @@ exec_shlib(int argc, char **argv)
		return (EX_IOERR);
	}

-
	if ((it = pkgdb_query_requires_shlib(db, libname)) == NULL) {
+
	if ((it = pkgdb_query_shlib_required(db, libname)) == NULL) {
		return (EX_IOERR);
	}

modified pkg/utils.c
@@ -144,7 +144,7 @@ info_flags(unsigned int opt)
	if (opt & INFO_OPTIONS)
		flags |= PKG_LOAD_OPTIONS;
	if (opt & INFO_SHLIBS)
-
		flags |= PKG_LOAD_SHLIBS;
+
		flags |= PKG_LOAD_SHLIBS_REQUIRED;
	if (opt & INFO_DEPS)
		flags |= PKG_LOAD_DEPS;
	if (opt & INFO_RDEPS)
@@ -158,10 +158,16 @@ info_flags(unsigned int opt)
	if (opt & INFO_GROUPS)
		flags |= PKG_LOAD_GROUPS;
	if (opt & INFO_RAW) {
-
		flags |= PKG_LOAD_CATEGORIES|PKG_LOAD_LICENSES|PKG_LOAD_OPTIONS ;
-
		flags |= PKG_LOAD_SHLIBS|PKG_LOAD_DEPS|PKG_LOAD_FILES;
-
		flags |= PKG_LOAD_DIRS|PKG_LOAD_USERS|PKG_LOAD_GROUPS;
-
		flags |= PKG_LOAD_SCRIPTS;
+
		flags |= PKG_LOAD_CATEGORIES      |
+
			 PKG_LOAD_LICENSES        |
+
			 PKG_LOAD_OPTIONS         |
+
			 PKG_LOAD_SHLIBS_REQUIRED |
+
			 PKG_LOAD_DEPS            |
+
			 PKG_LOAD_FILES           |
+
			 PKG_LOAD_DIRS            |
+
			 PKG_LOAD_USERS           |
+
			 PKG_LOAD_GROUPS          |
+
			 PKG_LOAD_SCRIPTS;
	}

	return flags;
@@ -377,10 +383,10 @@ print_info(struct pkg * const pkg, unsigned int options)
			}
			break;
		case INFO_SHLIBS:
-
			if (pkg_list_count(pkg, PKG_SHLIBS) > 0) {
+
			if (pkg_list_count(pkg, PKG_SHLIBS_REQUIRED) > 0) {
				if (print_tag)
					printf("%-15s:\n", "Shared Libs");
-
				while (pkg_shlibs(pkg, &shlib) == EPKG_OK)
+
				while (pkg_shlibs_required(pkg, &shlib) == EPKG_OK)
					printf("%s%s\n", tab, pkg_shlib_name(shlib));
			}
			break;