39#include "xbps_api_impl.h"
64static int pkgdb_fd = -1;
65static bool pkgdb_map_names_done =
false;
76 prev_umask = umask(022);
78 if (xbps_pkgdb_init(xhp) == ENOENT) {
80 if (access(xhp->
metadir, R_OK|X_OK) == -1) {
81 if (errno != ENOENT) {
87 xbps_dbg_printf(
"[pkgdb] failed to create metadir "
88 "%s: %s\n", xhp->
metadir, strerror(rv));
93 xhp->
pkgdb = xbps_dictionary_create();
96 xbps_dbg_printf(
"[pkgdb] failed to create pkgdb "
102 if ((pkgdb_fd = open(xhp->
pkgdb_plist, O_CREAT|O_RDWR|O_CLOEXEC, 0664)) == -1) {
104 xbps_dbg_printf(
"[pkgdb] cannot open pkgdb for locking "
113 if (lockf(pkgdb_fd, F_TLOCK, 0) == -1) {
115 xbps_dbg_printf(
"[pkgdb] cannot lock pkgdb: %s\n", strerror(rv));
120 if (access(xhp->
rootdir, W_OK) == -1) {
122 xbps_dbg_printf(
"[pkgdb] rootdir %s: %s\n", xhp->
rootdir, strerror(rv));
133 xbps_dbg_printf(
"%s: pkgdb_fd %d\n", __func__, pkgdb_fd);
135 if (pkgdb_fd != -1) {
136 if (lockf(pkgdb_fd, F_ULOCK, 0) == -1)
137 xbps_dbg_printf(
"[pkgdb] failed to unlock pkgdb: %s\n", strerror(errno));
139 (void)close(pkgdb_fd);
147 xbps_object_iterator_t iter;
151 if (!xbps_dictionary_count(xhp->
pkgdb))
154 if (xhp->vpkgd == NULL) {
155 xhp->vpkgd = xbps_dictionary_create();
158 xbps_error_printf(
"failed to create dictionary\n");
166 iter = xbps_dictionary_iterator(xhp->
pkgdb);
169 xbps_error_printf(
"failed to create iterator");
173 while ((obj = xbps_object_iterator_next(iter))) {
174 xbps_array_t provides;
175 xbps_dictionary_t pkgd;
176 const char *pkgver = NULL;
177 const char *pkgname = NULL;
180 pkgd = xbps_dictionary_get_keysym(xhp->
pkgdb, obj);
181 provides = xbps_dictionary_get(pkgd,
"provides");
182 cnt = xbps_array_count(provides);
186 xbps_dictionary_get_cstring_nocopy(pkgd,
"pkgver", &pkgver);
187 xbps_dictionary_get_cstring_nocopy(pkgd,
"pkgname", &pkgname);
190 for (
unsigned int i = 0; i < cnt; i++) {
191 char vpkgname[XBPS_NAME_SIZE];
192 const char *vpkg = NULL;
193 xbps_dictionary_t providers;
196 xbps_array_get_cstring_nocopy(provides, i, &vpkg);
198 xbps_warn_printf(
"%s: invalid provides: %s\n", pkgver, vpkg);
202 providers = xbps_dictionary_get(xhp->vpkgd, vpkgname);
204 providers = xbps_dictionary_create();
207 xbps_error_printf(
"failed to create dictionary\n");
210 if (!xbps_dictionary_set(xhp->vpkgd, vpkgname, providers)) {
212 xbps_error_printf(
"failed to set dictionary entry\n");
213 xbps_object_release(providers);
219 if (!xbps_dictionary_set_cstring(providers, vpkg, pkgname)) {
221 xbps_error_printf(
"failed to set dictionary entry\n");
223 xbps_object_release(providers);
227 xbps_object_release(providers);
228 xbps_dbg_printf(
"[pkgdb] added vpkg %s for %s\n", vpkg, pkgname);
232 xbps_object_iterator_release(iter);
239 xbps_object_iterator_t iter;
243 if (pkgdb_map_names_done || !xbps_dictionary_count(xhp->
pkgdb))
250 iter = xbps_dictionary_iterator(xhp->
pkgdb);
253 while ((obj = xbps_object_iterator_next(iter))) {
254 xbps_dictionary_t pkgd;
256 char pkgname[XBPS_NAME_SIZE] = {0};
258 pkgd = xbps_dictionary_get_keysym(xhp->
pkgdb, obj);
259 if (!xbps_dictionary_get_cstring_nocopy(pkgd,
"pkgver", &pkgver)) {
266 if (!xbps_dictionary_set_cstring(pkgd,
"pkgname", pkgname)) {
271 xbps_object_iterator_release(iter);
273 pkgdb_map_names_done =
true;
292 if ((rv = xbps_pkgdb_conversion(xhp)) != 0)
299 xbps_dbg_printf(
"[pkgdb] cannot internalize "
300 "pkgdb dictionary: %s\n", strerror(rv));
304 if ((rv = pkgdb_map_names(xhp)) != 0) {
305 xbps_dbg_printf(
"[pkgdb] pkgdb_map_names %s\n", strerror(rv));
308 if ((rv = pkgdb_map_vpkgs(xhp)) != 0) {
309 xbps_dbg_printf(
"[pkgdb] pkgdb_map_vpkgs %s\n", strerror(rv));
313 xbps_dbg_printf(
"[pkgdb] initialized ok.\n");
321 xbps_dictionary_t pkgdb_storage;
323 static int cached_rv;
326 if (cached_rv && !flush)
329 if (xhp->
pkgdb && flush) {
330 pkgdb_storage = xbps_dictionary_internalize_from_file(xhp->
pkgdb_plist);
331 if (pkgdb_storage == NULL ||
332 !xbps_dictionary_equals(xhp->
pkgdb, pkgdb_storage)) {
334 prev_umask = umask(022);
342 xbps_object_release(pkgdb_storage);
344 xbps_object_release(xhp->
pkgdb);
352 if ((xhp->
pkgdb = xbps_dictionary_internalize_from_file(xhp->
pkgdb_plist)) == NULL) {
358 xhp->
pkgdb = xbps_dictionary_create();
360 xbps_error_printf(
"cannot access to pkgdb: %s\n", strerror(rv));
362 cached_rv = rv = errno;
375 xbps_object_release(xhp->
pkgdb);
376 xbps_dbg_printf(
"[pkgdb] released ok.\n");
381 int (*fn)(
struct xbps_handle *, xbps_object_t,
const char *,
void *,
bool *),
384 xbps_array_t allkeys;
387 if ((rv = xbps_pkgdb_init(xhp)) != 0)
390 allkeys = xbps_dictionary_all_keys(xhp->
pkgdb);
393 xbps_object_release(allkeys);
399 int (*fn)(
struct xbps_handle *, xbps_object_t,
const char *,
void *,
bool *),
402 xbps_array_t allkeys;
405 if ((rv = xbps_pkgdb_init(xhp)) != 0)
408 allkeys = xbps_dictionary_all_keys(xhp->
pkgdb);
411 xbps_object_release(allkeys);
418 xbps_dictionary_t pkgd;
420 if (xbps_pkgdb_init(xhp) != 0)
423 pkgd = xbps_find_pkg_in_dict(xhp->
pkgdb, pkg);
432 if (xbps_pkgdb_init(xhp) != 0)
435 return xbps_find_virtualpkg_in_dict(xhp, xhp->
pkgdb, vpkg);
442 xbps_object_iterator_t iter;
443 xbps_dictionary_t vpkg_cache;
445 if (xhp->pkgdb_revdeps)
448 xhp->pkgdb_revdeps = xbps_dictionary_create();
449 assert(xhp->pkgdb_revdeps);
451 vpkg_cache = xbps_dictionary_create();
454 iter = xbps_dictionary_iterator(xhp->
pkgdb);
457 while ((obj = xbps_object_iterator_next(iter))) {
458 xbps_array_t rundeps;
459 xbps_dictionary_t pkgd;
460 const char *pkgver = NULL;
462 pkgd = xbps_dictionary_get_keysym(xhp->
pkgdb, obj);
463 rundeps = xbps_dictionary_get(pkgd,
"run_depends");
464 if (!xbps_array_count(rundeps))
467 xbps_dictionary_get_cstring_nocopy(pkgd,
"pkgver", &pkgver);
468 for (
unsigned int i = 0; i < xbps_array_count(rundeps); i++) {
470 const char *pkgdep = NULL, *v;
471 char curpkgname[XBPS_NAME_SIZE];
474 xbps_array_get_cstring_nocopy(rundeps, i, &pkgdep);
485 if (!xbps_dictionary_get_cstring_nocopy(vpkg_cache, curpkgname, &v)) {
486 const char *vpkgname = vpkg_user_conf(xhp, curpkgname);
493 if (!xbps_dictionary_set_cstring_nocopy(vpkg_cache, curpkgname, v)) {
494 xbps_error_printf(
"%s\n", strerror(errno ? errno : ENOMEM));
499 pkg = xbps_dictionary_get(xhp->pkgdb_revdeps, v);
502 pkg = xbps_array_create();
505 xbps_array_add_cstring_nocopy(pkg, pkgver);
506 xbps_dictionary_set(xhp->pkgdb_revdeps, v, pkg);
509 xbps_object_release(pkg);
512 xbps_object_iterator_release(iter);
513 xbps_object_release(vpkg_cache);
519 xbps_dictionary_t pkgd;
520 const char *pkgver = NULL;
521 char pkgname[XBPS_NAME_SIZE];
526 generate_full_revdeps_tree(xhp);
527 xbps_dictionary_get_cstring_nocopy(pkgd,
"pkgver", &pkgver);
531 return xbps_dictionary_get(xhp->pkgdb_revdeps, pkgname);
537 return xbps_get_pkg_fulldeptree(xhp, pkg,
false);
543 xbps_dictionary_t pkgd;
544 const char *pkgver = NULL;
545 char pkgname[XBPS_NAME_SIZE], plist[PATH_MAX];
554 xbps_dictionary_get_cstring_nocopy(pkgd,
"pkgver", &pkgver);
558 snprintf(plist,
sizeof(plist)-1,
"%s/.%s-files.plist", xhp->
metadir, pkgname);
char rootdir[XBPS_MAXPATH]
char metadir[XBPS_MAXPATH]
Generic XBPS structure handler for initialization.
xbps_array_t xbps_pkgdb_get_pkg_fulldeptree(struct xbps_handle *xhp, const char *pkg)
int xbps_pkgdb_foreach_cb_multi(struct xbps_handle *xhp, int(*fn)(struct xbps_handle *, xbps_object_t, const char *, void *, bool *), void *arg)
xbps_dictionary_t xbps_pkgdb_get_pkg_files(struct xbps_handle *xhp, const char *pkg)
void xbps_pkgdb_unlock(struct xbps_handle *xhp)
xbps_dictionary_t xbps_pkgdb_get_virtualpkg(struct xbps_handle *xhp, const char *vpkg)
int xbps_pkgdb_foreach_cb(struct xbps_handle *xhp, int(*fn)(struct xbps_handle *, xbps_object_t, const char *, void *, bool *), void *arg)
xbps_array_t xbps_pkgdb_get_pkg_revdeps(struct xbps_handle *xhp, const char *pkg)
int xbps_pkgdb_update(struct xbps_handle *xhp, bool flush, bool update)
int xbps_pkgdb_lock(struct xbps_handle *xhp)
xbps_dictionary_t xbps_pkgdb_get_pkg(struct xbps_handle *xhp, const char *pkg)
bool xbps_match_string_in_array(xbps_array_t array, const char *val)
int xbps_array_foreach_cb_multi(struct xbps_handle *xhp, xbps_array_t array, xbps_dictionary_t dict, int(*fn)(struct xbps_handle *, xbps_object_t obj, const char *, void *arg, bool *done), void *arg)
int xbps_array_foreach_cb(struct xbps_handle *xhp, xbps_array_t array, xbps_dictionary_t dict, int(*fn)(struct xbps_handle *, xbps_object_t obj, const char *, void *arg, bool *done), void *arg)
xbps_dictionary_t xbps_plist_dictionary_from_file(const char *path)
char * xbps_xasprintf(const char *fmt,...) __attribute__((format(printf
bool xbps_pkg_name(char *dst, size_t len, const char *pkg)
int xbps_mkpath(const char *path, mode_t mode)
bool xbps_pkgpattern_name(char *dst, size_t len, const char *pattern)