Beispiel #1
0
bool HIDDEN
xbps_transaction_shlibs(struct xbps_handle *xhp, xbps_array_t pkgs, xbps_array_t mshlibs)
{
	xbps_object_t obj;
	xbps_object_iterator_t iter;
	xbps_dictionary_t shrequires, shprovides;
	bool unmatched = false;

	shrequires = collect_shlibs(xhp, pkgs, true);
	shprovides = collect_shlibs(xhp, pkgs, false);

	/* iterate over shlib-requires to find unmatched shlibs */
	iter = xbps_dictionary_iterator(shrequires);
	assert(iter);

	while ((obj = xbps_object_iterator_next(iter))) {
		xbps_array_t array;
		const char *pkgver, *shlib;
		char *buf;

		shlib = xbps_dictionary_keysym_cstring_nocopy(obj);
		xbps_dbg_printf(xhp, "%s: checking for `%s': ", __func__, shlib);
		if (xbps_dictionary_get(shprovides, shlib)) {
			xbps_dbg_printf_append(xhp, "found\n");
			continue;
		}
		xbps_dbg_printf_append(xhp, "not found\n");

		unmatched = true;
		array = xbps_dictionary_get_keysym(shrequires, obj);
		for (unsigned int i = 0; i < xbps_array_count(array); i++) {
			xbps_array_get_cstring_nocopy(array, i, &pkgver);
			buf = xbps_xasprintf("%s: broken, unresolvable "
			    "shlib `%s'", pkgver, shlib);
			xbps_array_add_cstring(mshlibs, buf);
			free(buf);
		}
		xbps_object_release(array);
	}
	xbps_object_iterator_release(iter);
	xbps_object_release(shprovides);

	return unmatched;
}
Beispiel #2
0
int
xbps_alternatives_register(struct xbps_handle *xhp, xbps_dictionary_t pkgd)
{
	xbps_array_t allkeys;
	xbps_dictionary_t alternatives, pkg_alternatives;
	const char *pkgver;
	char *pkgname;
	int rv = 0;

	assert(xhp);

	if (xhp->pkgdb == NULL)
		return EINVAL;

	pkg_alternatives = xbps_dictionary_get(pkgd, "alternatives");
	if (!xbps_dictionary_count(pkg_alternatives))
		return 0;

	alternatives = xbps_dictionary_get(xhp->pkgdb, "_XBPS_ALTERNATIVES_");
	if (alternatives == NULL) {
		alternatives = xbps_dictionary_create();
		xbps_dictionary_set(xhp->pkgdb, "_XBPS_ALTERNATIVES_", alternatives);
		xbps_object_release(alternatives);
	}
	alternatives = xbps_dictionary_get(xhp->pkgdb, "_XBPS_ALTERNATIVES_");
	assert(alternatives);

	xbps_dictionary_get_cstring_nocopy(pkgd, "pkgver", &pkgver);
	pkgname = xbps_pkg_name(pkgver);
	if (pkgname == NULL)
		return EINVAL;

	allkeys = xbps_dictionary_all_keys(pkg_alternatives);
	for (unsigned int i = 0; i < xbps_array_count(allkeys); i++) {
		xbps_array_t array;
		xbps_object_t keysym;
		const char *keyname;
		bool alloc = false;

		keysym = xbps_array_get(allkeys, i);
		keyname = xbps_dictionary_keysym_cstring_nocopy(keysym);

		array = xbps_dictionary_get(alternatives, keyname);
		if (array == NULL) {
			alloc = true;
			array = xbps_array_create();
		} else {
			/* already registered */
			if (xbps_match_string_in_array(array, pkgname))
				continue;
		}

		xbps_array_add_cstring(array, pkgname);
		xbps_dictionary_set(alternatives, keyname, array);
		xbps_set_cb_state(xhp, XBPS_STATE_ALTGROUP_ADDED, 0, NULL,
		    "%s: registered '%s' alternatives group", pkgver, keyname);
		if (alloc) {
			/* apply alternatives for this group */
			rv = create_symlinks(xhp,
				xbps_dictionary_get(pkg_alternatives, keyname),
				keyname);
			xbps_object_release(array);
			if (rv != 0)
				break;
		}
	}
	xbps_object_release(allkeys);
	free(pkgname);

	return rv;
}
Beispiel #3
0
int
xbps_alternatives_unregister(struct xbps_handle *xhp, xbps_dictionary_t pkgd)
{
	xbps_array_t allkeys;
	xbps_dictionary_t alternatives, pkg_alternatives;
	const char *pkgver;
	char *pkgname;
	bool update = false;
	int rv = 0;

	assert(xhp);

	alternatives = xbps_dictionary_get(xhp->pkgdb, "_XBPS_ALTERNATIVES_");
	if (alternatives == NULL)
		return 0;

	pkg_alternatives = xbps_dictionary_get(pkgd, "alternatives");
	if (!xbps_dictionary_count(pkg_alternatives))
		return 0;

	xbps_dictionary_get_cstring_nocopy(pkgd, "pkgver", &pkgver);
	if ((pkgname = xbps_pkg_name(pkgver)) == NULL)
		return EINVAL;

	xbps_dictionary_get_bool(pkgd, "alternatives-update", &update);

	allkeys = xbps_dictionary_all_keys(pkg_alternatives);
	for (unsigned int i = 0; i < xbps_array_count(allkeys); i++) {
		xbps_array_t array;
		xbps_object_t keysym;
		const char *first = NULL, *keyname;

		keysym = xbps_array_get(allkeys, i);
		keyname = xbps_dictionary_keysym_cstring_nocopy(keysym);

		array = xbps_dictionary_get(alternatives, keyname);
		if (array == NULL)
			continue;

		xbps_array_get_cstring_nocopy(array, 0, &first);
		if (strcmp(pkgname, first) == 0) {
			/* this pkg is the current alternative for this group */
			rv = remove_symlinks(xhp,
				xbps_dictionary_get(pkg_alternatives, keyname),
				keyname);
			if (rv != 0)
				break;
		}

		xbps_set_cb_state(xhp, XBPS_STATE_ALTGROUP_REMOVED, 0, NULL,
		    "%s: unregistered '%s' alternatives group", pkgver, keyname);
		if (!update)
			xbps_remove_string_from_array(array, pkgname);

		if (xbps_array_count(array) == 0) {
			xbps_dictionary_remove(alternatives, keyname);
		} else {
			xbps_dictionary_t curpkgd;

			first = NULL;
			xbps_array_get_cstring_nocopy(array, 0, &first);
			curpkgd = xbps_pkgdb_get_pkg(xhp, first);
			assert(curpkgd);
			xbps_set_cb_state(xhp, XBPS_STATE_ALTGROUP_SWITCHED, 0, NULL,
			    "Switched '%s' alternatives group to '%s'", keyname, first);
			pkg_alternatives = xbps_dictionary_get(curpkgd, "alternatives");
			rv = create_symlinks(xhp,
				xbps_dictionary_get(pkg_alternatives, keyname),
				keyname);
			if (rv != 0)
				break;
		}

	}
	xbps_object_release(allkeys);
	free(pkgname);

	return rv;
}
Beispiel #4
0
int
xbps_alternatives_set(struct xbps_handle *xhp, const char *pkgname,
		const char *group)
{
	xbps_array_t allkeys;
	xbps_dictionary_t alternatives, pkg_alternatives, pkgd;
	const char *pkgver;
	int rv = 0;

	assert(xhp);
	assert(pkgname);

	alternatives = xbps_dictionary_get(xhp->pkgdb, "_XBPS_ALTERNATIVES_");
	if (alternatives == NULL)
		return ENOENT;

	pkgd = xbps_pkgdb_get_pkg(xhp, pkgname);
	if (pkgd == NULL)
		return ENOENT;

	pkg_alternatives = xbps_dictionary_get(pkgd, "alternatives");
	if (!xbps_dictionary_count(pkg_alternatives))
		return ENOENT;

	xbps_dictionary_get_cstring_nocopy(pkgd, "pkgver", &pkgver);

	allkeys = xbps_dictionary_all_keys(pkg_alternatives);
	for (unsigned int i = 0; i < xbps_array_count(allkeys); i++) {
		xbps_array_t array;
		xbps_object_t keysym;
		xbps_string_t kstr;
		const char *keyname;

		keysym = xbps_array_get(allkeys, i);
		keyname = xbps_dictionary_keysym_cstring_nocopy(keysym);

		if (group && strcmp(keyname, group)) {
			rv = ENOENT;
			continue;
		}

		array = xbps_dictionary_get(alternatives, keyname);
		if (array == NULL)
			continue;

		/* put this alternative group at the head */
		xbps_remove_string_from_array(array, pkgname);
		kstr = xbps_string_create_cstring(pkgname);
		xbps_array_add_first(array, kstr);
		xbps_object_release(kstr);

		/* apply the alternatives group */
		xbps_set_cb_state(xhp, XBPS_STATE_ALTGROUP_ADDED, 0, NULL,
		    "%s: applying '%s' alternatives group", pkgver, keyname);
		rv = create_symlinks(xhp, xbps_dictionary_get(pkg_alternatives, keyname), keyname);
		if (rv != 0)
			break;
	}
	xbps_object_release(allkeys);
	return rv;
}
Beispiel #5
0
static bool
repodata_commit(struct xbps_handle *xhp, const char *repodir,
	xbps_dictionary_t idx, xbps_dictionary_t meta, xbps_dictionary_t stage) {
	const char *pkgname;
	xbps_object_iterator_t iter;
	xbps_object_t keysym;
	int rv;

	if(xbps_dictionary_count(stage) == 0) {
		// Nothing to do.
		return true;
	}

	/*
	 * Find old shlibs-provides
	 */
	xbps_dictionary_t oldshlibs = xbps_dictionary_create();
	xbps_dictionary_t usedshlibs = xbps_dictionary_create();

	iter = xbps_dictionary_iterator(stage);
	while ((keysym = xbps_object_iterator_next(iter))) {
		pkgname = xbps_dictionary_keysym_cstring_nocopy(keysym);
		xbps_dictionary_t oldpkg = xbps_dictionary_get(idx, pkgname);

		xbps_array_t pkgshlibs = xbps_dictionary_get(oldpkg, "shlib-provides");
		for(unsigned int i = 0; i < xbps_array_count(pkgshlibs); i++) {
			const char *shlib = NULL;
			xbps_array_get_cstring_nocopy(pkgshlibs, i, &shlib);
			xbps_dictionary_set_cstring(oldshlibs, shlib, pkgname);
		}
	}
	xbps_object_iterator_release(iter);

	/*
	 * throw away all unused shlibs
	 */
	iter = xbps_dictionary_iterator(idx);
	while ((keysym = xbps_object_iterator_next(iter))) {
		pkgname = xbps_dictionary_keysym_cstring_nocopy(keysym);
		xbps_dictionary_t pkg = xbps_dictionary_get(stage, pkgname);
		if(!pkg)
			pkg = xbps_dictionary_get_keysym(idx, keysym);
		xbps_array_t pkgshlibs = xbps_dictionary_get(pkg, "shlib-requires");

		for(unsigned int i = 0; i < xbps_array_count(pkgshlibs); i++) {
			const char *shlib = NULL, *user = NULL;
			xbps_array_get_cstring_nocopy(pkgshlibs, i, &shlib);
			xbps_dictionary_get_cstring_nocopy(pkg, shlib, &user);
			if(!user)
				continue;
			xbps_array_t users = xbps_dictionary_get(usedshlibs, shlib);
			if(!users) {
				users = xbps_array_create();
				xbps_dictionary_set(usedshlibs, shlib, users);
			}
			xbps_array_add_cstring(users, user);
		}
	}
	xbps_object_iterator_release(iter);

	/*
	 * purge all packages that are fullfilled by the stage
	 */
	iter = xbps_dictionary_iterator(stage);
	while ((keysym = xbps_object_iterator_next(iter))) {
		pkgname = xbps_dictionary_keysym_cstring_nocopy(keysym);
		xbps_dictionary_t newpkg = xbps_dictionary_get(idx, pkgname);

		xbps_array_t pkgshlibs = xbps_dictionary_get(newpkg, "shlib-provides");
		for(unsigned int i = 0; i < xbps_array_count(pkgshlibs); i++) {
			const char *shlib;
			xbps_array_get_cstring_nocopy(pkgshlibs, i, &shlib);
			xbps_dictionary_remove(usedshlibs, shlib);
		}
	}
	xbps_object_iterator_release(iter);

	if(xbps_dictionary_count(usedshlibs) != 0) {
		puts("Unfullfilled shlibs:");
		iter = xbps_dictionary_iterator(usedshlibs);
		while ((keysym = xbps_object_iterator_next(iter))) {
			const char *shlib = xbps_dictionary_keysym_cstring_nocopy(keysym), *provider = NULL;
			xbps_array_t users = xbps_dictionary_get(usedshlibs, shlib);
			xbps_dictionary_get_cstring_nocopy(usedshlibs, shlib, &provider);

			printf(" %s (provided by: %s; used by: ", shlib, provider);
			const char *pre = "";
			for(unsigned int i = 0; i < xbps_array_count(users); i++) {
				const char *user;
				xbps_array_get_cstring_nocopy(users, i, &user);
				xbps_dictionary_remove(usedshlibs, shlib);
				printf("%s%s",pre, user);
				pre = ", ";
			}
			puts(")");
		}
		puts("Changes are commit to stage.");
		xbps_object_iterator_release(iter);
		// TODO FLUSH STAGE
		rv = true;
	}
	else {
		iter = xbps_dictionary_iterator(stage);
		while ((keysym = xbps_object_iterator_next(iter))) {
			pkgname = xbps_dictionary_keysym_cstring_nocopy(keysym);
			xbps_dictionary_t newpkg = xbps_dictionary_get_keysym(stage, keysym);
			xbps_dictionary_set(idx, pkgname, newpkg);
		}
		xbps_object_iterator_release(iter);
		rv = repodata_flush(xhp, repodir, idx, meta);
	}
	xbps_object_release(usedshlibs);
	xbps_object_release(oldshlibs);
	return rv;
}