34#include "xbps/xbps_array.h"
35#include "xbps/xbps_dictionary.h"
36#include "xbps_api_impl.h"
57 struct xbps_handle *xhp;
58 struct shlib_entry *entries;
59 xbps_dictionary_t seen;
63static struct shlib_entry *
64shlib_entry_find(
struct shlib_entry *head,
const char *name)
66 struct shlib_entry *res = NULL;
67 HASH_FIND_STR(head, name, res);
71static struct shlib_entry *
72shlib_entry_get(
struct shlib_ctx *ctx,
const char *name)
74 struct shlib_entry *res = shlib_entry_find(ctx->entries, name);
77 res = calloc(1,
sizeof(*res));
83 HASH_ADD_STR(ctx->entries, name, res);
88collect_shlib_array(
struct shlib_ctx *ctx, xbps_array_t array)
90 for (
unsigned int i = 0; i < xbps_array_count(array); i++) {
91 struct shlib_entry *entry;
92 const char *shlib = NULL;
93 if (!xbps_array_get_cstring_nocopy(array, i, &shlib))
95 entry = shlib_entry_get(ctx, shlib);
103collect_shlibs(
struct shlib_ctx *ctx, xbps_array_t pkgs)
106 xbps_object_iterator_t iter;
107 xbps_bool_t placeholder;
110 placeholder = xbps_bool_create(
true);
114 ctx->seen = xbps_dictionary_create();
118 for (
unsigned int i = 0; i < xbps_array_count(pkgs); i++) {
120 xbps_dictionary_t pkgd = xbps_array_get(pkgs, i);
125 if (!xbps_dictionary_get_cstring_nocopy(pkgd,
"pkgname", &pkgname)) {
129 if (!xbps_dictionary_set(ctx->seen, pkgname, placeholder))
135 array = xbps_dictionary_get(pkgd,
"shlib-provides");
137 int r = collect_shlib_array(ctx, array);
143 iter = xbps_dictionary_iterator(ctx->xhp->
pkgdb);
147 while ((obj = xbps_object_iterator_next(iter))) {
149 xbps_dictionary_t pkgd;
150 const char *pkgname = NULL;
152 pkgname = xbps_dictionary_keysym_cstring_nocopy(obj);
154 if (strncmp(pkgname,
"_XBPS_", 6) == 0)
157 pkgd = xbps_dictionary_get_keysym(ctx->xhp->
pkgdb, obj);
159 if (xbps_dictionary_get(ctx->seen, pkgname))
162 array = xbps_dictionary_get(pkgd,
"shlib-provides");
164 int r = collect_shlib_array(ctx, array);
170 xbps_object_iterator_release(iter);
175check_shlibs(
struct shlib_ctx *ctx, xbps_array_t pkgs)
177 xbps_object_iterator_t iter;
180 for (
unsigned int i = 0; i < xbps_array_count(pkgs); i++) {
182 xbps_dictionary_t pkgd = xbps_array_get(pkgs, i);
185 if (ttype == XBPS_TRANS_HOLD || ttype == XBPS_TRANS_REMOVE)
188 array = xbps_dictionary_get(pkgd,
"shlib-requires");
191 for (
unsigned int j = 0; j < xbps_array_count(array); j++) {
192 const char *pkgver = NULL;
193 const char *shlib = NULL;
195 if (!xbps_array_get_cstring_nocopy(array, j, &shlib))
197 if (shlib_entry_find(ctx->entries, shlib))
199 if (!xbps_dictionary_get_cstring_nocopy(pkgd,
"pkgver", &pkgver))
202 "%s: broken, unresolvable shlib `%s'",
204 if (!xbps_array_add_cstring_nocopy(ctx->missing, missing))
209 iter = xbps_dictionary_iterator(ctx->xhp->
pkgdb);
213 while ((obj = xbps_object_iterator_next(iter))) {
215 xbps_dictionary_t pkgd;
216 const char *pkgname = NULL;
218 pkgname = xbps_dictionary_keysym_cstring_nocopy(obj);
220 if (strncmp(pkgname,
"_XBPS_", 6) == 0)
223 pkgd = xbps_dictionary_get_keysym(ctx->xhp->
pkgdb, obj);
225 if (xbps_dictionary_get(ctx->seen, pkgname))
228 array = xbps_dictionary_get(pkgd,
"shlib-requires");
231 for (
unsigned int i = 0; i < xbps_array_count(array); i++) {
232 const char *pkgver = NULL;
233 const char *shlib = NULL;
235 if (!xbps_array_get_cstring_nocopy(array, i, &shlib))
237 if (shlib_entry_find(ctx->entries, shlib))
239 if (!xbps_dictionary_get_cstring_nocopy(pkgd,
"pkgver", &pkgver))
242 "%s: broken, unresolvable shlib `%s'", pkgver,
244 if (!xbps_array_add_cstring_nocopy(ctx->missing, missing))
249 xbps_object_iterator_release(iter);
254xbps_transaction_check_shlibs(
struct xbps_handle *xhp, xbps_array_t pkgs)
256 struct shlib_entry *entry, *tmp;
257 struct shlib_ctx ctx = { .xhp = xhp };
260 ctx.missing = xbps_dictionary_get(xhp->
transd,
"missing_shlibs");
262 r = collect_shlibs(&ctx, pkgs);
266 r = check_shlibs(&ctx, pkgs);
270 if (xbps_array_count(ctx.missing) == 0)
271 xbps_dictionary_remove(xhp->
transd,
"missing_shlibs");
275 HASH_ITER(hh, ctx.entries, entry, tmp) {
276 HASH_DEL(ctx.entries, entry);
280 xbps_object_release(ctx.seen);
Generic XBPS structure handler for initialization.
#define xbps_error_oom()
Log out of memory condition.
void xbps_error_printf(const char *fmt,...)
Prints error messages to stderr.
xbps_trans_type_t xbps_transaction_pkg_type(xbps_dictionary_t pkg_repod)
char * xbps_xasprintf(const char *fmt,...) __attribute__((format(printf