Ejemplo n.º 1
0
static void
process_one_alternative(const char *altgrname, const char *val)
{
	xbps_dictionary_t d;
	xbps_array_t a;
	char *altfiles;
	bool alloc = false;

	if ((d = xbps_dictionary_get(pkg_propsd, "alternatives")) == NULL) {
		d = xbps_dictionary_create();
		assert(d);
		alloc = true;
	}
	if ((a = xbps_dictionary_get(d, altgrname)) == NULL) {
		a = xbps_array_create();
		assert(a);
	}
	altfiles = strchr(val, ':') + 1;
	assert(altfiles);

	xbps_array_add_cstring(a, altfiles);
	xbps_dictionary_set(d, altgrname, a);
	xbps_dictionary_set(pkg_propsd, "alternatives", d);

	if (alloc) {
		xbps_object_release(a);
		xbps_object_release(d);
	}
}
Ejemplo n.º 2
0
ATF_TC_BODY(find_pkg_orphans_test, tc)
{
	struct xbps_handle xh;
	xbps_array_t a, res;
	xbps_dictionary_t pkgd;
	xbps_string_t pstr;
	const char *pkgver, *tcsdir;
	unsigned int i;

	/* get test source dir */
	tcsdir = atf_tc_get_config_var(tc, "srcdir");

	memset(&xh, 0, sizeof(xh));
	xbps_strlcpy(xh.rootdir, tcsdir, sizeof(xh.rootdir));
	xbps_strlcpy(xh.metadir, tcsdir, sizeof(xh.metadir));
	ATF_REQUIRE_EQ(xbps_init(&xh), 0);

	a = xbps_array_create();
	xbps_array_add_cstring_nocopy(a, "xbps-git");

	pstr = xbps_string_create();
	res = xbps_find_pkg_orphans(&xh, a);
	for (i = 0; i < xbps_array_count(res); i++) {
		pkgd = xbps_array_get(res, i);
		xbps_dictionary_get_cstring_nocopy(pkgd, "pkgver", &pkgver);
		xbps_string_append_cstring(pstr, pkgver);
		xbps_string_append_cstring(pstr, "\n");
	}
	ATF_REQUIRE_STREQ(xbps_string_cstring_nocopy(pstr), expected_output);
}
Ejemplo n.º 3
0
static void
process_array(const char *key, const char *val)
{
	xbps_array_t array = NULL;
	char *args, *p = NULL, *saveptr = NULL;

	assert(key);

	if (val == NULL)
		return;

	array = xbps_array_create();
	assert(array);

	if (strchr(val, ' ') == NULL) {
		xbps_array_add_cstring_nocopy(array, val);
		goto out;
	}

        args = strdup(val);
	assert(args);

	for ((p = strtok_r(args, " ", &saveptr)); p;
	     (p = strtok_r(NULL, " ", &saveptr))) {
		xbps_array_add_cstring(array, p);
	}
	free(args);
out:
	xbps_dictionary_set(pkg_propsd, key, array);
	xbps_object_release(array);
}
Ejemplo n.º 4
0
static void
generate_full_revdeps_tree(struct xbps_handle *xhp)
{
	xbps_object_t obj;
	xbps_object_iterator_t iter;

	if (xhp->pkgdb_revdeps)
		return;

	xhp->pkgdb_revdeps = xbps_dictionary_create();
	assert(xhp->pkgdb_revdeps);

	iter = xbps_dictionary_iterator(xhp->pkgdb);
	assert(iter);

	while ((obj = xbps_object_iterator_next(iter))) {
		xbps_array_t rundeps;
		xbps_dictionary_t pkgd;
		const char *pkgver;

		pkgd = xbps_dictionary_get_keysym(xhp->pkgdb, obj);
		rundeps = xbps_dictionary_get(pkgd, "run_depends");
		if (!xbps_array_count(rundeps))
			continue;

		xbps_dictionary_get_cstring_nocopy(pkgd, "pkgver", &pkgver);
		for (unsigned int i = 0; i < xbps_array_count(rundeps); i++) {
			xbps_array_t pkg;
			const char *pkgdep, *vpkgname;
			char *curpkgname;
			bool alloc = false;

			xbps_array_get_cstring_nocopy(rundeps, i, &pkgdep);
			curpkgname = xbps_pkgpattern_name(pkgdep);
			if (curpkgname == NULL)
				curpkgname = xbps_pkg_name(pkgdep);
			assert(curpkgname);
			vpkgname = vpkg_user_conf(xhp, curpkgname);
			if (vpkgname == NULL)
				vpkgname = curpkgname;

			pkg = xbps_dictionary_get(xhp->pkgdb_revdeps, vpkgname);
			if (pkg == NULL) {
				alloc = true;
				pkg = xbps_array_create();
			}
			if (!xbps_match_string_in_array(pkg, pkgver)) {
				xbps_array_add_cstring_nocopy(pkg, pkgver);
				xbps_dictionary_set(xhp->pkgdb_revdeps, vpkgname, pkg);
			}
			free(curpkgname);
			if (alloc)
				xbps_object_release(pkg);
		}
	}
	xbps_object_iterator_release(iter);
}
Ejemplo n.º 5
0
static bool
store_repo(struct xbps_handle *xhp, const char *repo)
{
	if (xhp->repositories == NULL)
		xhp->repositories = xbps_array_create();

	if (xbps_match_string_in_array(xhp->repositories, repo))
		return false;

	xbps_array_add_cstring(xhp->repositories, repo);
	return true;
}
Ejemplo n.º 6
0
static void
shlib_register(xbps_dictionary_t d, const char *shlib, const char *pkgver)
{
	xbps_array_t array;
	bool alloc = false;

	if ((array = xbps_dictionary_get(d, shlib)) == NULL) {
		alloc = true;
		array = xbps_array_create();
		xbps_dictionary_set(d, shlib, array);
	}
	if (!xbps_match_string_in_array(array, pkgver))
		xbps_array_add_cstring_nocopy(array, pkgver);
	if (alloc)
		xbps_object_release(array);
}
Ejemplo n.º 7
0
static void
store_preserved_file(struct xbps_handle *xhp, const char *file)
{
	glob_t globbuf;
	char *p = NULL, *rfile = NULL;
	size_t len;
	int rv = 0;

	if (xhp->preserved_files == NULL) {
		xhp->preserved_files = xbps_array_create();
		assert(xhp->preserved_files);
	}

	rfile = xbps_xasprintf("%s%s", xhp->rootdir, file);

	rv = glob(rfile, 0, NULL, &globbuf);
	if (rv == GLOB_NOMATCH) {
		if (xbps_match_string_in_array(xhp->preserved_files, file))
			goto out;
		xbps_array_add_cstring(xhp->preserved_files, file);
		xbps_dbg_printf(xhp, "Added preserved file: %s\n", file);
		goto out;
	} else if (rv != 0) {
		goto out;
	}
	for (size_t i = 0; i < globbuf.gl_pathc; i++) {
		if (xbps_match_string_in_array(xhp->preserved_files, globbuf.gl_pathv[i]))
			continue;

		len = strlen(globbuf.gl_pathv[i]) - strlen(xhp->rootdir) + 1;
		p = malloc(len);
		assert(p);
		strlcpy(p, globbuf.gl_pathv[i] + strlen(xhp->rootdir), len);
		xbps_array_add_cstring(xhp->preserved_files, p);
		xbps_dbg_printf(xhp, "Added preserved file: %s (expanded from %s)\n", p, file);
		free(p);
	}
out:
	globfree(&globbuf);
	free(rfile);
}
Ejemplo n.º 8
0
bool
xbps_repo_store(struct xbps_handle *xhp, const char *repo)
{
	char *url = NULL;

	assert(xhp);
	assert(repo);

	if (xhp->repositories == NULL) {
		xhp->repositories = xbps_array_create();
		assert(xhp->repositories);
	}
	/*
	 * If it's a local repo and path is relative, make it absolute.
	 */
	if (!xbps_repository_is_remote(repo)) {
		if (repo[0] != '/' && repo[0] != '\0') {
			if ((url = realpath(repo, NULL)) == NULL)
				xbps_dbg_printf(xhp, "[repo] %s: realpath %s\n", __func__, repo);
		}
	}
	if (xbps_match_string_in_array(xhp->repositories, url ? url : repo)) {
		xbps_dbg_printf(xhp, "[repo] `%s' already stored\n", url ? url : repo);
		if (url)
			free(url);
		return false;
	}
	if (xbps_array_add_cstring(xhp->repositories, url ? url : repo)) {
		xbps_dbg_printf(xhp, "[repo] `%s' stored successfully\n", url ? url : repo);
		if (url)
			free(url);
		return true;
	}
	if (url)
		free(url);

	return false;
}
Ejemplo n.º 9
0
static xbps_array_t
merge_filelist(xbps_dictionary_t d)
{
	xbps_array_t a, result;
	xbps_dictionary_t filed;
	unsigned int i;

	result = xbps_array_create();
	assert(result);

	if ((a = xbps_dictionary_get(d, "files"))) {
		for (i = 0; i < xbps_array_count(a); i++) {
			filed = xbps_array_get(a, i);
			xbps_array_add(result, filed);
		}
	}
	if ((a = xbps_dictionary_get(d, "links"))) {
		for (i = 0; i < xbps_array_count(a); i++) {
			filed = xbps_array_get(a, i);
			xbps_array_add(result, filed);
		}
	}
	if ((a = xbps_dictionary_get(d, "conf_files"))) {
		for (i = 0; i < xbps_array_count(a); i++) {
			filed = xbps_array_get(a, i);
			xbps_array_add(result, filed);
		}
	}
	if ((a = xbps_dictionary_get(d, "dirs"))) {
		for (i = 0; i < xbps_array_count(a); i++) {
			filed = xbps_array_get(a, i);
			xbps_array_add(result, filed);
		}
	}

	return result;
}
Ejemplo n.º 10
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;
}
Ejemplo n.º 11
0
static xbps_array_t
revdeps_match(struct xbps_repo *repo, xbps_dictionary_t tpkgd, const char *str)
{
	xbps_dictionary_t pkgd;
	xbps_array_t revdeps = NULL, pkgdeps, provides;
	xbps_object_iterator_t iter;
	xbps_object_t obj;
	const char *pkgver, *tpkgver, *arch, *vpkg;

	iter = xbps_dictionary_iterator(repo->idx);
	assert(iter);

	while ((obj = xbps_object_iterator_next(iter))) {
		pkgd = xbps_dictionary_get_keysym(repo->idx, obj);
		if (xbps_dictionary_equals(pkgd, tpkgd))
			continue;

		pkgdeps = xbps_dictionary_get(pkgd, "run_depends");
		if (!xbps_array_count(pkgdeps))
			continue;
		/*
		 * Try to match passed in string.
		 */
		if (str) {
			if (!xbps_match_pkgdep_in_array(pkgdeps, str))
				continue;
			xbps_dictionary_get_cstring_nocopy(pkgd,
			    "architecture", &arch);
			if (!xbps_pkg_arch_match(repo->xhp, arch, NULL))
				continue;

			xbps_dictionary_get_cstring_nocopy(pkgd,
			    "pkgver", &tpkgver);
			/* match */
			if (revdeps == NULL)
				revdeps = xbps_array_create();

			if (!xbps_match_string_in_array(revdeps, tpkgver))
				xbps_array_add_cstring_nocopy(revdeps, tpkgver);

			continue;
		}
		/*
		 * Try to match any virtual package.
		 */
		provides = xbps_dictionary_get(tpkgd, "provides");
		for (unsigned int i = 0; i < xbps_array_count(provides); i++) {
			xbps_array_get_cstring_nocopy(provides, i, &vpkg);
			if (!xbps_match_pkgdep_in_array(pkgdeps, vpkg))
				continue;

			xbps_dictionary_get_cstring_nocopy(pkgd,
			    "architecture", &arch);
			if (!xbps_pkg_arch_match(repo->xhp, arch, NULL))
				continue;

			xbps_dictionary_get_cstring_nocopy(pkgd, "pkgver",
			    &tpkgver);
			/* match */
			if (revdeps == NULL)
				revdeps = xbps_array_create();

			if (!xbps_match_string_in_array(revdeps, tpkgver))
				xbps_array_add_cstring_nocopy(revdeps, tpkgver);
		}
		/*
		 * Try to match by pkgver.
		 */
		xbps_dictionary_get_cstring_nocopy(tpkgd, "pkgver", &pkgver);
		if (!xbps_match_pkgdep_in_array(pkgdeps, pkgver))
			continue;

		xbps_dictionary_get_cstring_nocopy(pkgd,
		    "architecture", &arch);
		if (!xbps_pkg_arch_match(repo->xhp, arch, NULL))
			continue;

		xbps_dictionary_get_cstring_nocopy(pkgd, "pkgver", &tpkgver);
		/* match */
		if (revdeps == NULL)
			revdeps = xbps_array_create();

		if (!xbps_match_string_in_array(revdeps, tpkgver))
			xbps_array_add_cstring_nocopy(revdeps, tpkgver);
	}
	xbps_object_iterator_release(iter);
	return revdeps;
}
Ejemplo n.º 12
0
xbps_array_t
xbps_find_pkg_obsoletes(struct xbps_handle *xhp,
			xbps_dictionary_t instd,
			xbps_dictionary_t newd)
{
	xbps_array_t instfiles, newfiles, obsoletes;
	xbps_object_t obj, obj2;
	xbps_string_t oldstr, newstr;
	unsigned int i, x;
	const char *oldhash;
	char *file;
	int rv = 0;
	bool found;

	assert(xbps_object_type(instd) == XBPS_TYPE_DICTIONARY);
	assert(xbps_object_type(newd) == XBPS_TYPE_DICTIONARY);

	obsoletes = xbps_array_create();
	assert(obsoletes);

	instfiles = merge_filelist(instd);
	if (xbps_array_count(instfiles) == 0) {
		/* nothing to check if current pkg does not own any file */
		xbps_object_release(instfiles);
		return obsoletes;
	}
	newfiles = merge_filelist(newd);

	/*
	 * Iterate over files list from installed package.
	 */
	for (i = 0; i < xbps_array_count(instfiles); i++) {
		found = false;
		obj = xbps_array_get(instfiles, i);
		if (xbps_object_type(obj) != XBPS_TYPE_DICTIONARY) {
			/* ignore unexistent files */
			continue;
		}
		oldstr = xbps_dictionary_get(obj, "file");
		if (oldstr == NULL)
			continue;

		file = xbps_xasprintf(".%s",
		    xbps_string_cstring_nocopy(oldstr));

		oldhash = NULL;
		xbps_dictionary_get_cstring_nocopy(obj,
		    "sha256", &oldhash);
		if (oldhash) {
			rv = xbps_file_hash_check(file, oldhash);
			if (rv == ENOENT || rv == ERANGE) {
				/*
				 * Skip unexistent and files that do not
				 * match the hash.
				 */
				free(file);
				continue;
			}
		}
		/*
		 * Check if current file is available in new pkg filelist.
		 */
		for (x = 0; x < xbps_array_count(newfiles); x++) {
			obj2 = xbps_array_get(newfiles, x);
			newstr = xbps_dictionary_get(obj2, "file");
			assert(newstr);
			/*
			 * Skip files with same path.
			 */
			if (xbps_string_equals(oldstr, newstr)) {
				found = true;
				break;
			}
		}
		if (found) {
			free(file);
			continue;
		}
		/*
		 * Do not add required symlinks for the
		 * system transition to /usr.
		 */
		if ((strcmp(file, "./bin") == 0) ||
		    (strcmp(file, "./bin/") == 0) ||
		    (strcmp(file, "./sbin") == 0) ||
		    (strcmp(file, "./sbin/") == 0) ||
		    (strcmp(file, "./lib") == 0) ||
		    (strcmp(file, "./lib/") == 0) ||
		    (strcmp(file, "./lib64/") == 0) ||
		    (strcmp(file, "./lib64") == 0)) {
			free(file);
			continue;
		}
		/*
		 * Obsolete found, add onto the array.
		 */
		xbps_dbg_printf(xhp, "found obsolete: %s\n", file);
		xbps_array_add_cstring(obsoletes, file);
		free(file);
	}
	xbps_object_release(instfiles);
	xbps_object_release(newfiles);

	return obsoletes;
}
Ejemplo n.º 13
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;
}
Ejemplo n.º 14
0
xbps_array_t
xbps_find_pkg_obsoletes(struct xbps_handle *xhp,
			xbps_dictionary_t instd,
			xbps_dictionary_t newd)
{
	xbps_array_t instfiles, newfiles, obsoletes;
	/* These are symlinks in Void and must not be removed */
	const char *basesymlinks[] = {
		"./bin",
		"./sbin",
		"./lib",
		"./lib32",
		"./lib64",
		"./usr/lib32",
		"./usr/lib64",
		"./var/run",
	};
	int rv = 0;

	assert(xbps_object_type(instd) == XBPS_TYPE_DICTIONARY);
	assert(xbps_object_type(newd) == XBPS_TYPE_DICTIONARY);

	obsoletes = xbps_array_create();
	assert(obsoletes);

	instfiles = merge_filelist(instd);
	if (xbps_array_count(instfiles) == 0) {
		/* nothing to check if current pkg does not own any file */
		xbps_object_release(instfiles);
		return obsoletes;
	}
	newfiles = merge_filelist(newd);

	/*
	 * Iterate over files list from installed package.
	 */
	for (unsigned int i = 0; i < xbps_array_count(instfiles); i++) {
		xbps_object_t obj, obj2;
		xbps_string_t oldstr, newstr;
		struct stat st;
		uint64_t mtime = 0;
		const char *oldhash;
		char file[PATH_MAX];
		bool found = false;

		obj = xbps_array_get(instfiles, i);
		if (xbps_object_type(obj) != XBPS_TYPE_DICTIONARY) {
			/* ignore unexistent files */
			continue;
		}
		oldstr = xbps_dictionary_get(obj, "file");
		if (oldstr == NULL)
			continue;

		snprintf(file, sizeof(file), ".%s", xbps_string_cstring_nocopy(oldstr));

		if (xbps_dictionary_get_cstring_nocopy(obj, "sha256", &oldhash)) {
			rv = xbps_file_hash_check(file, oldhash);
			if (rv == ENOENT || rv == ERANGE) {
				/*
				  Skip unexistent and files that do not
				 * match the hash.
				 */
				continue;
			}
		}
		/*
		 * Check if current file is available in new pkg filelist.
		 */
		for (unsigned int x = 0; x < xbps_array_count(newfiles); x++) {
			obj2 = xbps_array_get(newfiles, x);
			newstr = xbps_dictionary_get(obj2, "file");
			assert(newstr);
			/*
			 * Skip files with same path.
			 */
			if (xbps_string_equals(oldstr, newstr)) {
				found = true;
				break;
			}
		}
		if (found) {
			continue;
		}
		/*
		 * Make sure to not remove any symlink of root directory.
		 */
		for (uint8_t x = 0; x < __arraycount(basesymlinks); x++) {
			if (strcmp(file, basesymlinks[x]) == 0) {
				found = true;
				xbps_dbg_printf(xhp, "[obsoletes] ignoring "
				    "%s removal\n", file);
				break;
			}
		}
		if (found) {
			continue;
		}
		/*
		 * Finally check if file mtime on disk matched what
		 * the installed pkg has stored.
		 */
		if (xbps_dictionary_get_uint64(obj, "mtime", &mtime)) {
			if (lstat(file, &st) == -1) {
				xbps_dbg_printf(xhp, "[obsoletes] lstat failed "
				    "for %s: %s\n", file, strerror(errno));
				continue;
			}
			if (mtime != (uint64_t)st.st_mtime)
				continue;

			xbps_dbg_printf(xhp,
			    "[obsoletes] %s: matched mtime, adding obsolete.\n", file);
		}
		/*
		 * Obsolete found, add onto the array.
		 */
		xbps_dbg_printf(xhp, "found obsolete: %s\n", file);
		xbps_array_add_cstring(obsoletes, file);
	}
	xbps_object_release(instfiles);
	xbps_object_release(newfiles);

	return obsoletes;
}
Ejemplo n.º 15
0
int
xbps_transaction_prepare(struct xbps_handle *xhp)
{
	xbps_array_t array, pkgs, edges;
	unsigned int i, cnt;
	int rv = 0;

	if (xhp->transd == NULL)
		return ENXIO;

	/*
	 * Collect dependencies for pkgs in transaction.
	 */
	if ((edges = xbps_array_create()) == NULL)
		return ENOMEM;
	/*
	 * The edges are also appended after its dependencies have been
	 * collected; the edges at the original array are removed later.
	 */
	pkgs = xbps_dictionary_get(xhp->transd, "packages");
	assert(xbps_object_type(pkgs) == XBPS_TYPE_ARRAY);
	cnt = xbps_array_count(pkgs);
	for (i = 0; i < cnt; i++) {
		xbps_dictionary_t pkgd;
		xbps_string_t str;
		const char *tract = NULL;

		pkgd = xbps_array_get(pkgs, i);
		str = xbps_dictionary_get(pkgd, "pkgver");
		xbps_dictionary_get_cstring_nocopy(pkgd, "transaction", &tract);
		if ((strcmp(tract, "remove") == 0) || strcmp(tract, "hold") == 0)
			continue;

		assert(xbps_object_type(str) == XBPS_TYPE_STRING);

		if (!xbps_array_add(edges, str))
			return ENOMEM;

		if ((rv = xbps_repository_find_deps(xhp, pkgs, pkgd)) != 0)
			return rv;

		if (!xbps_array_add(pkgs, pkgd))
			return ENOMEM;
	}
	/* ... remove dup edges at head */
	for (i = 0; i < xbps_array_count(edges); i++) {
		const char *pkgver;
		xbps_array_get_cstring_nocopy(edges, i, &pkgver);
		xbps_remove_pkg_from_array_by_pkgver(pkgs, pkgver);
	}
	xbps_object_release(edges);

	/*
	 * Check for packages to be replaced.
	 */
	if ((rv = xbps_transaction_package_replace(xhp, pkgs)) != 0) {
		xbps_object_release(xhp->transd);
		xhp->transd = NULL;
		return rv;
	}
	/*
	 * If there are missing deps or revdeps bail out.
	 */
	xbps_transaction_revdeps(xhp, pkgs);
	array = xbps_dictionary_get(xhp->transd, "missing_deps");
	if (xbps_array_count(array)) {
		if (xhp->flags & XBPS_FLAG_FORCE_REMOVE_REVDEPS) {
			xbps_dbg_printf(xhp, "[trans] continuing with broken reverse dependencies!");
		} else {
			return ENODEV;
		}
	}
	/*
	 * If there are package conflicts bail out.
	 */
	xbps_transaction_conflicts(xhp, pkgs);
	array = xbps_dictionary_get(xhp->transd, "conflicts");
	if (xbps_array_count(array))
		return EAGAIN;
	/*
	 * Check for unresolved shared libraries.
	 */
	if (xbps_transaction_shlibs(xhp, pkgs,
	    xbps_dictionary_get(xhp->transd, "missing_shlibs"))) {
		if (xhp->flags & XBPS_FLAG_FORCE_REMOVE_REVDEPS) {
			xbps_dbg_printf(xhp, "[trans] continuing with unresolved shared libraries!");
		} else {
			return ENOEXEC;
		}
	}
	/*
	 * Add transaction stats for total download/installed size,
	 * number of packages to be installed, updated, configured
	 * and removed to the transaction dictionary.
	 */
	if ((rv = compute_transaction_stats(xhp)) != 0) {
		return rv;
	}
	/*
	 * Remove now unneeded objects.
	 */
	xbps_dictionary_remove(xhp->transd, "missing_shlibs");
	xbps_dictionary_remove(xhp->transd, "missing_deps");
	xbps_dictionary_remove(xhp->transd, "conflicts");
	xbps_dictionary_make_immutable(xhp->transd);

	return 0;
}
Ejemplo n.º 16
0
int HIDDEN
xbps_transaction_init(struct xbps_handle *xhp)
{
	xbps_array_t array;

	if (xhp->transd != NULL)
		return 0;

	if ((xhp->transd = xbps_dictionary_create()) == NULL)
		return ENOMEM;

        if ((array = xbps_array_create()) == NULL) {
		xbps_object_release(xhp->transd);
		xhp->transd = NULL;
		return ENOMEM;
	}
	if (!xbps_dictionary_set(xhp->transd, "packages", array)) {
		xbps_object_release(xhp->transd);
		xhp->transd = NULL;
		return EINVAL;
	}
	xbps_object_release(array);

	if ((array = xbps_array_create()) == NULL) {
		xbps_object_release(xhp->transd);
		xhp->transd = NULL;
		return ENOMEM;
	}
	if (!xbps_dictionary_set(xhp->transd, "missing_deps", array)) {
		xbps_object_release(xhp->transd);
		xhp->transd = NULL;
		return EINVAL;
	}
	xbps_object_release(array);

	if ((array = xbps_array_create()) == NULL) {
		xbps_object_release(xhp->transd);
		xhp->transd = NULL;
		return ENOMEM;
	}
	if (!xbps_dictionary_set(xhp->transd, "missing_shlibs", array)) {
		xbps_object_release(xhp->transd);
		xhp->transd = NULL;
		return EINVAL;
	}
	xbps_object_release(array);

	if ((array = xbps_array_create()) == NULL) {
		xbps_object_release(xhp->transd);
		xhp->transd = NULL;
		return ENOMEM;
	}
	if (!xbps_dictionary_set(xhp->transd, "conflicts", array)) {
		xbps_object_release(xhp->transd);
		xhp->transd = NULL;
		return EINVAL;
	}
	xbps_object_release(array);

	return 0;
}