Example #1
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);
}
Example #2
0
/*
 * Verify reverse dependencies for packages in transaction.
 * This will catch cases where a package update would break its reverse dependencies:
 *
 * 	- foo-1.0 is being updated to 2.0.
 * 	- baz-1.1 depends on foo<2.0.
 * 	- foo is updated to 2.0, hence baz-1.1 is currently broken.
 *
 * Abort transaction if such case is found.
 */
static bool
check_virtual_pkgs(xbps_array_t mdeps,
		   xbps_dictionary_t trans_pkgd,
		   xbps_dictionary_t rev_pkgd)
{
	xbps_array_t provides;
	bool matched = false;

	provides = xbps_dictionary_get(trans_pkgd, "provides");
	for (unsigned int i = 0; i < xbps_array_count(provides); i++) {
		xbps_array_t rundeps;
		const char *pkgver, *revpkgver, *pkgpattern;
		char *pkgname, *vpkgname, *vpkgver, *str;

		pkgver = revpkgver = pkgpattern = NULL;
		pkgname = vpkgname = vpkgver = str = NULL;

		xbps_dictionary_get_cstring_nocopy(trans_pkgd, "pkgver", &pkgver);
		xbps_dictionary_get_cstring_nocopy(rev_pkgd, "pkgver", &revpkgver);
		xbps_array_get_cstring(provides, i, &vpkgver);
		vpkgname = xbps_pkg_name(vpkgver);
		assert(vpkgname);
		rundeps = xbps_dictionary_get(rev_pkgd, "run_depends");
		for (unsigned int x = 0; x < xbps_array_count(rundeps); x++) {
			xbps_array_get_cstring_nocopy(rundeps, x, &pkgpattern);
			if (((pkgname = xbps_pkgpattern_name(pkgpattern)) == NULL) &&
			    ((pkgname = xbps_pkg_name(pkgpattern)) == NULL))
				continue;

			if (strcmp(vpkgname, pkgname)) {
				free(pkgname);
				continue;
			}
			free(pkgname);
			if (!strcmp(vpkgver, pkgpattern) ||
			    xbps_pkgpattern_match(vpkgver, pkgpattern)) {
				continue;
			}

			str = xbps_xasprintf("%s broken, needs '%s' virtual pkg (got `%s')",
			    revpkgver, pkgpattern, vpkgver);
			xbps_array_add_cstring(mdeps, str);
			free(str);
			matched = true;
		}
		free(vpkgname);
		free(vpkgver);
	}
	return matched;
}
Example #3
0
File: list.c Project: stpx/xpkgfile
void list_files (xbps_dictionary_t filesd,
                 const char *pkgver,
                 void *arg)
{
	xbps_array_t pkgfiles;
	const char *pkgname;
	struct config *cfg = arg;

	pkgname = xbps_pkg_name (pkgver);
	if (strcmp (pkgname, cfg->pattern) != 0)
		return;


	pkgfiles = xbps_dictionary_get (filesd, pkgver);
	for (unsigned int i = 0; i < xbps_array_count (pkgfiles); i++) {
		char *filestr = NULL;
		xbps_array_get_cstring (pkgfiles, i, &filestr);

		if (filestr == NULL)
			continue;

		printf ("%s: %s\n", pkgver, filestr);
		free (filestr);
	}
}
Example #4
0
ATF_TC_BODY(pkgdb_get_pkg_revdeps_test, tc)
{
	struct xbps_handle xh;
	xbps_array_t res;
	xbps_string_t pstr;
	const char *tcsdir, *str;
	const char *eout = "four-0.1_1\ntwo-0.1_1\n";
	unsigned int i;

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

	memset(&xh, 0, sizeof(xh));
	strncpy(xh.rootdir, tcsdir, sizeof(xh.rootdir));
	strncpy(xh.metadir, tcsdir, sizeof(xh.metadir));
	xh.flags = XBPS_FLAG_DEBUG;
	ATF_REQUIRE_EQ(xbps_init(&xh), 0);

	res = xbps_pkgdb_get_pkg_revdeps(&xh, "mixed");
	ATF_REQUIRE_EQ(xbps_object_type(res), XBPS_TYPE_ARRAY);

	pstr = xbps_string_create();
	for (i = 0; i < xbps_array_count(res); i++) {
		xbps_array_get_cstring_nocopy(res, i, &str);
		xbps_string_append_cstring(pstr, str);
		xbps_string_append_cstring(pstr, "\n");
	}
	ATF_REQUIRE_STREQ(xbps_string_cstring_nocopy(pstr), eout);
}
Example #5
0
static int
remove_symlinks(struct xbps_handle *xhp, xbps_array_t a, const char *grname)
{
	unsigned int i, cnt;

	cnt = xbps_array_count(a);
	for (i = 0; i < cnt; i++) {
		xbps_string_t str;
		char *l, *lnk;

		str = xbps_array_get(a, i);
		l = left(xbps_string_cstring_nocopy(str));
		assert(l);
		if (l[0] != '/') {
			const char *tgt;
			char *tgt_dup, *tgt_dir;
			tgt = right(xbps_string_cstring_nocopy(str));
			tgt_dup = strdup(tgt);
			assert(tgt_dup);
			tgt_dir = dirname(tgt_dup);
			lnk = xbps_xasprintf("%s%s/%s", xhp->rootdir, tgt_dir, l);
			free(tgt_dup);
		} else {
			lnk = xbps_xasprintf("%s%s", xhp->rootdir, l);
		}
		xbps_set_cb_state(xhp, XBPS_STATE_ALTGROUP_LINK_REMOVED, 0, NULL,
		    "Removing '%s' alternatives group symlink: %s", grname, l);
		unlink(lnk);
		free(lnk);
		free(l);
	}

	return 0;
}
Example #6
0
ATF_TC_BODY(find_all_orphans_test, tc)
{
	struct xbps_handle xh;
	xbps_array_t 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);

	pstr = xbps_string_create();
	res = xbps_find_pkg_orphans(&xh, NULL);
	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");
	}
	printf("%s", xbps_string_cstring_nocopy(pstr));

	ATF_REQUIRE_STREQ(xbps_string_cstring_nocopy(pstr), expected_output_all);
}
Example #7
0
static bool
check_remove_pkg_files(struct xbps_handle *xhp,
	xbps_dictionary_t pkgd, const char *pkgver, uid_t euid)
{
	struct stat st;
	xbps_array_t array;
	xbps_object_iterator_t iter;
	xbps_object_t obj;
	const char *objs[] = { "files", "conf_files", "links", "dirs" };
	const char *file;
	char path[PATH_MAX];
	bool fail = false;

	for (uint8_t i = 0; i < __arraycount(objs); i++) {
		array = xbps_dictionary_get(pkgd, objs[i]);
		if (array == NULL || xbps_array_count(array) == 0)
			continue;

		iter = xbps_array_iter_from_dict(pkgd, objs[i]);
		if (iter == NULL)
			continue;

		while ((obj = xbps_object_iterator_next(iter))) {
			xbps_dictionary_get_cstring_nocopy(obj, "file", &file);
			snprintf(path, sizeof(path), "%s/%s", xhp->rootdir, file);
			/*
			 * Check if effective user ID owns the file; this is
			 * enough to ensure the user has write permissions
			 * on the directory.
			 */
			if (euid == 0 || (!lstat(path, &st) && euid == st.st_uid)) {
				/* success */
				continue;
			}
			if (errno != ENOENT) {
				/*
				 * only bail out if something else than ENOENT
				 * is returned.
				 */
				int rv = errno;
				if (rv == 0) {
					/* lstat succeeds but euid != uid */
					rv = EPERM;
				}
				fail = true;
				xbps_set_cb_state(xhp, XBPS_STATE_REMOVE_FILE_FAIL,
				    rv, pkgver,
				    "%s: cannot remove `%s': %s",
				    pkgver, file, strerror(rv));
			}
			errno = 0;
		}
		xbps_object_iterator_release(iter);
	}

	return fail;
}
Example #8
0
static void
print_array(xbps_array_t a)
{
	const char *str;

	for (unsigned int i = 0; i < xbps_array_count(a); i++) {
		xbps_array_get_cstring_nocopy(a, i, &str);
		fprintf(stderr, "%s\n", str);
	}
}
Example #9
0
/*
 * Returns true if entry is a configuration file, false otherwise.
 */
int HIDDEN
xbps_entry_is_a_conf_file(xbps_dictionary_t filesd,
			  const char *entry_pname)
{
	xbps_array_t array;
	xbps_dictionary_t d;
	const char *cffile;

	array = xbps_dictionary_get(filesd, "conf_files");
	if (xbps_array_count(array) == 0)
		return false;

	for (unsigned int i = 0; i < xbps_array_count(array); i++) {
		d = xbps_array_get(array, i);
		xbps_dictionary_get_cstring_nocopy(d, "file", &cffile);
		if (strcmp(cffile, entry_pname) == 0)
			return true;
	}
	return false;
}
Example #10
0
static bool
entry_is_conf_file(const char *file)
{
	xbps_array_t a;
	const char *curfile;
	unsigned int i;

	assert(file);

	a = xbps_dictionary_get(pkg_propsd, "conf_files");
	if (a == NULL || xbps_array_count(a) == 0)
		return false;

	for (i = 0; i < xbps_array_count(a); i++) {
		xbps_array_get_cstring_nocopy(a, i, &curfile);
		if (strcmp(file, curfile) == 0)
			return true;
	}
	return false;
}
Example #11
0
static void
show_conflicts(xbps_array_t a)
{
	unsigned int i;
	const char *str;

	for (i = 0; i < xbps_array_count(a); i++) {
		xbps_array_get_cstring_nocopy(a, i, &str);
		fprintf(stderr, "%s\n", str);
	}
}
Example #12
0
File: search.c Project: Gottox/xbps
static void
print_results(struct xbps_handle *xhp, struct search_data *sd)
{
	const char *pkgver, *desc, *inststr;
	char tmp[256], *out;
	unsigned int j, tlen = 0, len = 0;

	/* Iterate over results array and find out largest pkgver string */
	for (unsigned int i = 0; i < xbps_array_count(sd->results); i+=2) {
		xbps_array_get_cstring_nocopy(sd->results, i, &pkgver);
		len = strlen(pkgver);
		if (tlen == 0 || len > tlen)
			tlen = len;
	}
	for (unsigned int i = 0; i < xbps_array_count(sd->results); i+=2) {
		xbps_array_get_cstring_nocopy(sd->results, i, &pkgver);
		xbps_array_get_cstring_nocopy(sd->results, i+1, &desc);
		xbps_strlcpy(tmp, pkgver, sizeof(tmp));
		for (j = strlen(tmp); j < tlen; j++)
			tmp[j] = ' ';

		tmp[j] = '\0';
		if (xbps_pkgdb_get_pkg(xhp, pkgver))
			inststr = "[*]";
		else
			inststr = "[-]";

		len = strlen(inststr) + strlen(tmp) + strlen(desc) + 3;
		if (sd->maxcols && (int)len > sd->maxcols) {
			out = malloc(sd->maxcols+1);
			assert(out);
			snprintf(out, sd->maxcols-3, "%s %s %s",
			    inststr, tmp, desc);
			xbps_strlcat(out, "...\n", sd->maxcols+1);
			printf("%s", out);
			free(out);
		} else {
			printf("%s %s %s\n", inststr, tmp, desc);
		}
	}
}
Example #13
0
static int
pkgdb_map_vpkgs(struct xbps_handle *xhp)
{
	xbps_object_iterator_t iter;
	xbps_object_t obj;
	int rv = 0;

	if (!xbps_dictionary_count(xhp->pkgdb))
		return 0;

	if (xhp->vpkgd == NULL) {
		xhp->vpkgd = xbps_dictionary_create();
		assert(xhp->vpkgd);
	}
	/*
	 * This maps all pkgs that have virtualpkgs in pkgdb.
	 */
	iter = xbps_dictionary_iterator(xhp->pkgdb);
	assert(iter);

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

		pkgd = xbps_dictionary_get_keysym(xhp->pkgdb, obj);
		provides = xbps_dictionary_get(pkgd, "provides");
		if (provides == NULL)
			continue;

		xbps_dictionary_get_cstring_nocopy(pkgd, "pkgver", &pkgver);
		pkgname = xbps_pkg_name(pkgver);
		assert(pkgname);

		for (unsigned int i = 0; i < xbps_array_count(provides); i++) {
			const char *vpkg;

			xbps_array_get_cstring_nocopy(provides, i, &vpkg);
			if (!xbps_dictionary_set_cstring(xhp->vpkgd, vpkg, pkgname)) {
				xbps_dbg_printf(xhp, "%s: set_cstring vpkg "
				    "%s pkgname %s\n", __func__, vpkg, pkgname);
				rv = EINVAL;
			} else {
				xbps_dbg_printf(xhp, "[pkgdb] added vpkg %s for %s\n",
				    vpkg, pkgname);
			}
		}
		free(pkgname);
	}
	xbps_object_iterator_release(iter);
	return rv;
}
Example #14
0
File: util.c Project: bougyman/xbps
bool
xbps_pkg_has_rundeps(xbps_dictionary_t pkgd)
{
	xbps_array_t array;

	assert(xbps_object_type(pkgd) == XBPS_TYPE_DICTIONARY);

	array = xbps_dictionary_get(pkgd, "run_depends");
	if (xbps_array_count(array))
		return true;

	return false;
}
Example #15
0
/*
 * Returns true if entry is a configuration file, false otherwise.
 */
int HIDDEN
xbps_entry_is_a_conf_file(xbps_dictionary_t propsd,
			  const char *entry_pname)
{
	xbps_array_t array;
	const char *cffile;
	unsigned int i;

	assert(xbps_object_type(propsd) == XBPS_TYPE_DICTIONARY);
	assert(entry_pname != NULL);

	array = xbps_dictionary_get(propsd, "conf_files");
	if (xbps_array_count(array) == 0)
		return false;

	for (i = 0; i < xbps_array_count(array); i++) {
		xbps_array_get_cstring_nocopy(array, i, &cffile);
		if (strcmp(cffile, entry_pname) == 0)
			return true;
	}
	return false;
}
Example #16
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;
}
Example #17
0
int
show_pkg_revdeps(struct xbps_handle *xhp, const char *pkg)
{
	xbps_array_t reqby;
	const char *pkgdep;
	unsigned int i;

	if ((reqby = xbps_pkgdb_get_pkg_revdeps(xhp, pkg)) != NULL) {
		for (i = 0; i < xbps_array_count(reqby); i++) {
			xbps_array_get_cstring_nocopy(reqby, i, &pkgdep);
			printf("%s\n", pkgdep);
		}
	}
	return 0;
}
Example #18
0
int
check_pkg_symlinks(struct xbps_handle *xhp, const char *pkgname, void *arg)
{
	xbps_array_t array;
	xbps_object_t obj;
	xbps_dictionary_t filesd = arg;
	int rv = 0;

	array = xbps_dictionary_get(filesd, "links");
	if (array == NULL)
		return 0;

	for (unsigned int i = 0; i < xbps_array_count(array); i++) {
		const char *file = NULL, *tgt = NULL;
		char path[PATH_MAX], *lnk = NULL;

		obj = xbps_array_get(array, i);
		if (!xbps_dictionary_get_cstring_nocopy(obj, "file", &file))
			continue;

		if (!xbps_dictionary_get_cstring_nocopy(obj, "target", &tgt)) {
			xbps_warn_printf("%s: `%s' symlink with "
			    "empty target object!\n", pkgname, file);
			continue;
		}
		if (tgt[0] == '\0') {
			xbps_warn_printf("%s: `%s' symlink with "
			    "empty target object!\n", pkgname, file);
			continue;
		}
		snprintf(path, sizeof(path), "%s/%s", xhp->rootdir, file);
		if ((lnk = xbps_symlink_target(xhp, path, tgt)) == NULL) {
			xbps_error_printf("%s: broken symlink %s (target: %s)\n", pkgname, file, tgt);
			rv = -1;
			continue;
		}
		if (strcmp(lnk, tgt)) {
			xbps_warn_printf("%s: modified symlink %s "
			    "points to %s (shall be %s)\n",
			    pkgname, file, lnk, tgt);
			rv = -1;
		}
		free(lnk);
	}
	return rv;
}
Example #19
0
int
repo_show_pkg_revdeps(struct xbps_handle *xhp, const char *pkg)
{
	xbps_array_t revdeps;
	const char *pkgver;
	unsigned int i;
	int rv;

	revdeps = xbps_rpool_get_pkg_revdeps(xhp, pkg);
	rv = errno;

	for (i = 0; i < xbps_array_count(revdeps); i++) {
		xbps_array_get_cstring_nocopy(revdeps, i, &pkgver);
		printf("%s\n", pkgver);
	}

	return rv;
}
Example #20
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;
}
Example #21
0
xbps_array_t
xbps_repo_get_pkg_revdeps(struct xbps_repo *repo, const char *pkg)
{
	xbps_array_t revdeps = NULL, vdeps = NULL;
	xbps_dictionary_t pkgd;
	const char *vpkg;
	bool match = false;

	if (repo->idx == NULL)
		return NULL;

	if (((pkgd = xbps_repo_get_pkg(repo, pkg)) == NULL) &&
	    ((pkgd = xbps_repo_get_virtualpkg(repo, pkg)) == NULL)) {
		errno = ENOENT;
		return NULL;
	}
	/*
	 * If pkg is a virtual pkg let's match it instead of the real pkgver.
	 */
	if ((vdeps = xbps_dictionary_get(pkgd, "provides"))) {
		for (unsigned int i = 0; i < xbps_array_count(vdeps); i++) {
			char *vpkgn;

			xbps_array_get_cstring_nocopy(vdeps, i, &vpkg);
			vpkgn = xbps_pkg_name(vpkg);
			assert(vpkgn);
			if (strcmp(vpkgn, pkg) == 0) {
				free(vpkgn);
				match = true;
				break;
			}
			free(vpkgn);
			vpkg = NULL;
		}
		if (match)
			revdeps = revdeps_match(repo, pkgd, vpkg);
	}
	if (!match)
		revdeps = revdeps_match(repo, pkgd, NULL);

	return revdeps;
}
Example #22
0
File: util.c Project: bougyman/xbps
/*
 * Check if pkg is explicitly marked to replace a specific installed version.
 */
bool
xbps_pkg_reverts(xbps_dictionary_t pkg, const char *pkgver)
{
	unsigned int i;
	xbps_array_t reverts;
	const char *version = xbps_pkg_version(pkgver);
	const char *revertver;

	if ((reverts = xbps_dictionary_get(pkg, "reverts")) == NULL)
		return false;

	for (i = 0; i < xbps_array_count(reverts); i++) {
		xbps_array_get_cstring_nocopy(reverts, i, &revertver);
		if (strcmp(version, revertver) == 0) {
			return true;
		}
	}

	return false;
}
Example #23
0
static void
print_rdeps(struct xbps_handle *xhp, xbps_array_t rdeps,
	    bool full, bool repo, bool origin, int *indent)
{
	xbps_array_t currdeps;
	xbps_dictionary_t pkgd;
	const char *pkgdep;
	unsigned int i;
	int j;

	if (!origin)
		(*indent)++;

	for (i = 0; i < xbps_array_count(rdeps); i++) {
		xbps_array_get_cstring_nocopy(rdeps, i, &pkgdep);
		if (!origin || !full)
			for (j = 0; j < *indent; j++)
				putchar(' ');

		printf("%s\n", pkgdep);
		if (!full)
			continue;

		if (repo) {
			pkgd = xbps_rpool_get_pkg(xhp, pkgdep);
			if (pkgd == NULL)
				pkgd = xbps_rpool_get_virtualpkg(xhp, pkgdep);
		} else {
			pkgd = xbps_pkgdb_get_pkg(xhp, pkgdep);
			if (pkgd == NULL)
				pkgd = xbps_pkgdb_get_virtualpkg(xhp, pkgdep);
		}
		if (pkgd != NULL) {
			currdeps = xbps_dictionary_get(pkgd, "run_depends");
			if (currdeps != NULL)
				print_rdeps(xhp, currdeps,
				    full, repo, false, indent);
		}
	}
	(*indent)--;
}
Example #24
0
void
match_files_by_pattern (xbps_dictionary_t filesd,
                        const char *pkgver,
                        void *arg)
{
	xbps_array_t pkgfiles;
	struct config *cfg = arg;

	pkgfiles = xbps_dictionary_get (filesd, pkgver);
	for (unsigned int i = 0; i < xbps_array_count (pkgfiles); i++) {
		char *filestr = NULL;
		xbps_array_get_cstring (pkgfiles, i, &filestr);

		if (filestr == NULL)
			continue;

		if (fnmatch (cfg->pattern, filestr, FNM_PERIOD) == 0)
			printf ("\033[0;1m%s:\033[0m %s\n", pkgver, filestr);

		free (filestr);
	}
}
Example #25
0
int HIDDEN
xbps_repository_find_deps(struct xbps_handle *xhp,
			  xbps_array_t unsorted,
			  xbps_dictionary_t repo_pkgd)
{
	xbps_array_t pkg_rdeps, pkg_provides = NULL;
	const char *pkgver;
	unsigned short depth = 0;

	pkg_rdeps = xbps_dictionary_get(repo_pkgd, "run_depends");
	if (xbps_array_count(pkg_rdeps) == 0)
		return 0;

	xbps_dictionary_get_cstring_nocopy(repo_pkgd, "pkgver", &pkgver);
	xbps_dbg_printf(xhp, "Finding required dependencies for '%s':\n", pkgver);
	/*
	 * This will find direct and indirect deps, if any of them is not
	 * there it will be added into the missing_deps array.
	 */
	pkg_provides = xbps_dictionary_get(repo_pkgd, "provides");
	return find_repo_deps(xhp, unsorted, pkg_rdeps, pkg_provides, pkgver, &depth);
}
Example #26
0
static const char *
find_pkg_symlink_target(xbps_dictionary_t d, const char *file)
{
	xbps_array_t links;
	xbps_object_t obj;
	unsigned int i;
	const char *pkgfile, *tgt = NULL;
	char *rfile;

	assert(d);

	links = xbps_dictionary_get(d, "links");
	for (i = 0; i < xbps_array_count(links); i++) {
		rfile = strchr(file, '.') + 1;
		obj = xbps_array_get(links, i);
		xbps_dictionary_get_cstring_nocopy(obj, "file", &pkgfile);
		if (strcmp(rfile, pkgfile) == 0) {
			xbps_dictionary_get_cstring_nocopy(obj, "target", &tgt);
			break;
		}
	}

	return tgt;
}
Example #27
0
int
xbps_init(struct xbps_handle *xhp)
{
	struct utsname un;
	char cwd[PATH_MAX-1], *buf;
	const char *repodir, *native_arch;
	int rv;

	assert(xhp != NULL);

	/* get cwd */
	if (getcwd(cwd, sizeof(cwd)) == NULL)
		return ENOTSUP;

	/* set conffile */
	if (xhp->conffile[0] == '\0') {
		snprintf(xhp->conffile, sizeof(xhp->conffile), XBPS_CONF_DEF);
	} else {
		buf = strdup(xhp->conffile);
		snprintf(xhp->conffile, sizeof(xhp->conffile), "%s/%s", cwd, buf);
		free(buf);
	}
	/* Set rootdir */
	if (xhp->rootdir[0] == '\0') {
		xhp->rootdir[0] = '/';
		xhp->rootdir[1] = '\0';
	} else if (xhp->rootdir[0] != '/') {
		buf = strdup(xhp->rootdir);
		snprintf(xhp->rootdir, sizeof(xhp->rootdir), "%s/%s", cwd, buf);
		free(buf);
	}
	/* parse configuration file */
	xbps_dbg_printf(xhp, "%s\n", XBPS_RELVER);
	if ((rv = parse_file(xhp, cwd, xhp->conffile, false, false)) != 0) {
		xbps_dbg_printf(xhp, "Using built-in defaults\n");
	}
	/* Set cachedir */
	if (xhp->cachedir[0] == '\0') {
		snprintf(xhp->cachedir, sizeof(xhp->cachedir),
		    "%s/%s", strcmp(xhp->rootdir, "/") ? xhp->rootdir : "",
		    XBPS_CACHE_PATH);
	} else if (xhp->cachedir[0] != '/') {
		/* relative path */
		buf = strdup(xhp->cachedir);
		snprintf(xhp->cachedir, sizeof(xhp->cachedir),
		    "%s/%s", strcmp(xhp->rootdir, "/") ? xhp->rootdir : "", buf);
		free(buf);
	}
	/* Set metadir */
	if (xhp->metadir[0] == '\0') {
		snprintf(xhp->metadir, sizeof(xhp->metadir),
		    "%s/%s", strcmp(xhp->rootdir, "/") ? xhp->rootdir : "",
		    XBPS_META_PATH);
	} else if (xhp->metadir[0] != '/') {
		/* relative path */
		buf = strdup(xhp->metadir);
		snprintf(xhp->metadir, sizeof(xhp->metadir),
		    "%s/%s", strcmp(xhp->rootdir, "/") ? xhp->rootdir : "", buf);
		free(buf);
	}
	/* process virtualpkg.d dirs */
	if ((rv = parse_dir(xhp, cwd, XBPS_SYS_VPKG_PATH, XBPS_VPKG_PATH, true)) != 0)
		return rv;

	/* process repo.d dirs */
	if ((rv = parse_dir(xhp, cwd, XBPS_SYS_REPOD_PATH, XBPS_REPOD_PATH, false)) != 0)
		return rv;

	/* process preserve.d dirs */
	if ((rv = parse_dir(xhp, cwd, XBPS_SYS_PRESERVED_PATH, XBPS_PRESERVED_PATH, false)) != 0)
		return rv;

	xhp->target_arch = getenv("XBPS_TARGET_ARCH");
	if ((native_arch = getenv("XBPS_ARCH")) != NULL) {
		strlcpy(xhp->native_arch, native_arch, sizeof(xhp->native_arch));
	} else {
		uname(&un);
		strlcpy(xhp->native_arch, un.machine, sizeof(xhp->native_arch));
	}
	assert(xhp->native_arch);

	xbps_fetch_set_cache_connection(XBPS_FETCH_CACHECONN, XBPS_FETCH_CACHECONN_HOST);

	xbps_dbg_printf(xhp, "rootdir=%s\n", xhp->rootdir);
	xbps_dbg_printf(xhp, "metadir=%s\n", xhp->metadir);
	xbps_dbg_printf(xhp, "cachedir=%s\n", xhp->cachedir);
	xbps_dbg_printf(xhp, "syslog=%s\n", xhp->flags & XBPS_FLAG_DISABLE_SYSLOG ? "false" : "true");
	xbps_dbg_printf(xhp, "Architecture: %s\n", xhp->native_arch);
	xbps_dbg_printf(xhp, "Target Architecture: %s\n", xhp->target_arch);

	if (xhp->flags & XBPS_FLAG_DEBUG) {
		for (unsigned int i = 0; i < xbps_array_count(xhp->repositories); i++) {
			xbps_array_get_cstring_nocopy(xhp->repositories, i, &repodir);
			xbps_dbg_printf(xhp, "Repository[%u]=%s\n", i, repodir);
		}
	}
	/* Going back to old working directory */
	if (chdir(cwd) == -1)
		xbps_dbg_printf(xhp, "%s: cannot chdir to %s: %s\n", __func__, cwd, strerror(errno));

	return 0;
}
Example #28
0
int HIDDEN
xbps_remove_pkg_files(struct xbps_handle *xhp,
		      xbps_dictionary_t dict,
		      const char *key,
		      const char *pkgver)
{
	struct stat st;
	xbps_array_t array;
	xbps_object_iterator_t iter;
	xbps_object_t obj;
	const char *file, *sha256, *curobj = NULL;
	char *path = NULL, *pkgname = NULL;
	char buf[PATH_MAX];
	int rv = 0;

	assert(xbps_object_type(dict) == XBPS_TYPE_DICTIONARY);
	assert(key != NULL);

	array = xbps_dictionary_get(dict, key);
	if (xbps_array_count(array) == 0)
		return 0;

	iter = xbps_array_iter_from_dict(dict, key);
	if (iter == NULL)
		return ENOMEM;

	if (strcmp(key, "files") == 0)
		curobj = "file";
	else if (strcmp(key, "conf_files") == 0)
		curobj = "configuration file";
	else if (strcmp(key, "links") == 0)
		curobj = "link";
	else if (strcmp(key, "dirs") == 0)
		curobj = "directory";

	pkgname = xbps_pkg_name(pkgver);
	assert(pkgname);

	while ((obj = xbps_object_iterator_next(iter))) {
		xbps_dictionary_get_cstring_nocopy(obj, "file", &file);
		path = xbps_xasprintf("%s/%s", xhp->rootdir, file);

		if ((strcmp(key, "files") == 0) ||
		    (strcmp(key, "conf_files") == 0)) {
			/*
			 * Check SHA256 hash in regular files and
			 * configuration files.
			 */
			xbps_dictionary_get_cstring_nocopy(obj,
			    "sha256", &sha256);
			rv = xbps_file_hash_check(path, sha256);
			if (rv == ENOENT) {
				/* missing file, ignore it */
				xbps_set_cb_state(xhp,
				    XBPS_STATE_REMOVE_FILE_HASH_FAIL,
				    rv, pkgver,
				    "%s: failed to check hash for %s `%s': %s",
				    pkgver, curobj, file, strerror(rv));
				free(path);
				rv = 0;
				continue;
			} else if (rv == ERANGE) {
				rv = 0;
				if ((xhp->flags &
				    XBPS_FLAG_FORCE_REMOVE_FILES) == 0) {
					xbps_set_cb_state(xhp,
					    XBPS_STATE_REMOVE_FILE_HASH_FAIL,
					    0, pkgver,
					    "%s: %s `%s' SHA256 mismatch, "
					    "preserving file", pkgver,
					    curobj, file);
					free(path);
					continue;
				} else {
					xbps_set_cb_state(xhp,
					    XBPS_STATE_REMOVE_FILE_HASH_FAIL,
					    0, pkgver,
					    "%s: %s `%s' SHA256 mismatch, "
					    "forcing removal", pkgver,
					    curobj, file);
				}
			} else if (rv != 0 && rv != ERANGE) {
				xbps_set_cb_state(xhp,
				    XBPS_STATE_REMOVE_FILE_HASH_FAIL,
				    rv, pkgver,
				    "%s: [remove] failed to check hash for "
				    "%s `%s': %s", pkgver, curobj, file,
				    strerror(rv));
				free(path);
				break;
			}
		} else if (strcmp(key, "links") == 0) {
			/*
			 * All regular files from package were removed at this
			 * point, so we will only remove dangling symlinks.
			 */
			if (realpath(path, buf) == NULL) {
				if (errno != ENOENT && errno != ELOOP) {
					free(path);
					rv = errno;
					break;
				}
			}
			if (stat(buf, &st) == 0) {
				free(path);
				continue;
			}
		}
		/*
		 * Remove the object if possible.
		 */
		if (remove(path) == -1) {
			xbps_set_cb_state(xhp, XBPS_STATE_REMOVE_FILE_FAIL,
			    errno, pkgver,
			    "%s: failed to remove %s `%s': %s", pkgver,
			    curobj, file, strerror(errno));
			errno = 0;
		} else {
			/* success */
			xbps_set_cb_state(xhp, XBPS_STATE_REMOVE_FILE,
			    0, pkgver, "Removed %s `%s'", curobj, file);
		}
		free(path);
	}
	xbps_object_iterator_release(iter);
	free(pkgname);

	return rv;
}
int HIDDEN
xbps_transaction_package_replace(struct xbps_handle *xhp, xbps_array_t pkgs)
{
	for (unsigned int i = 0; i < xbps_array_count(pkgs); i++) {
		xbps_array_t replaces;
		xbps_object_t obj, obj2;
		xbps_object_iterator_t iter;
		const char *pkgver;
		char *pkgname;

		obj = xbps_array_get(pkgs, i);
		replaces = xbps_dictionary_get(obj, "replaces");
		if (replaces == NULL || xbps_array_count(replaces) == 0)
			continue;

		iter = xbps_array_iterator(replaces);
		assert(iter);

		xbps_dictionary_get_cstring_nocopy(obj, "pkgver", &pkgver);
		pkgname = xbps_pkg_name(pkgver);
		assert(pkgname);

		while ((obj2 = xbps_object_iterator_next(iter)) != NULL) {
			xbps_dictionary_t instd, reppkgd;
			const char *tract, *pattern, *curpkgver;
			char *curpkgname;
			bool instd_auto = false;

			pattern = xbps_string_cstring_nocopy(obj2);
			/*
			 * Find the installed package that matches the pattern
			 * to be replaced.
			 */
			if (((instd = xbps_pkgdb_get_pkg(xhp, pattern)) == NULL) &&
			    ((instd = xbps_pkgdb_get_virtualpkg(xhp, pattern)) == NULL))
				continue;

			xbps_dictionary_get_cstring_nocopy(instd,
			    "pkgver", &curpkgver);
			curpkgname = xbps_pkg_name(curpkgver);
			assert(curpkgname);
			/*
			 * Check that we are not replacing the same package,
			 * due to virtual packages.
			 */
			if (strcmp(pkgname, curpkgname) == 0) {
				free(curpkgname);
				continue;
			}
			/*
			 * Make sure to not add duplicates.
			 */
			xbps_dictionary_get_bool(instd, "automatic-install", &instd_auto);
			reppkgd = xbps_find_pkg_in_array(pkgs, curpkgname, NULL);
			if (reppkgd) {
				xbps_dictionary_get_cstring_nocopy(reppkgd,
				    "transaction", &tract);
				if (strcmp(tract, "remove") == 0)
					continue;
				/*
				 * Package contains replaces="pkgpattern", but the
				 * package that should be replaced is also in the
				 * transaction and it's going to be updated.
				 */
				xbps_dictionary_set_bool(reppkgd,
				    "automatic-install", instd_auto);
				xbps_array_replace_dict_by_name(pkgs,
				    reppkgd, curpkgname);
				continue;
			}
			/*
			 * If new package is providing a virtual package to the
			 * package that we want to replace we should respect
			 * the automatic-install object.
			 */
			if (xbps_match_virtual_pkg_in_dict(obj, pattern)) {
				xbps_dictionary_set_bool(obj,
				    "automatic-install", instd_auto);
			}
			xbps_dbg_printf(xhp,
			    "Package `%s' will be replaced by `%s', "
			    "matched with `%s'\n", curpkgver, pkgver, pattern);
			/*
			 * Add package dictionary into the transaction and mark
			 * it as to be "removed".
			 */
			xbps_dictionary_set_cstring_nocopy(instd,
			    "transaction", "remove");
			if (!xbps_array_add_first(pkgs, instd))
				return EINVAL;
			free(curpkgname);
		}
		xbps_object_iterator_release(iter);
		free(pkgname);
	}

	return 0;
}
Example #30
0
/*
 * Verify reverse dependencies for packages in transaction.
 * This will catch cases where a package update would break its reverse dependencies:
 *
 * 	- foo-1.0 is being updated to 2.0.
 * 	- baz-1.1 depends on foo<2.0.
 * 	- foo is updated to 2.0, hence baz-1.1 is currently broken.
 *
 * Abort transaction if such case is found.
 */
static bool
check_virtual_pkgs(struct xbps_handle *xhp,
		   xbps_dictionary_t trans_pkgd,
		   xbps_dictionary_t rev_pkgd)
{
	xbps_array_t unsorted, provides, rundeps, mdeps;
	const char *pkgver, *revpkgver, *pkgpattern;
	char *pkgname, *pkgdepname, *vpkgname, *vpkgver, *str;
	unsigned int i, x;
	bool matched = false;

	unsorted = xbps_dictionary_get(xhp->transd, "unsorted_deps");
	provides = xbps_dictionary_get(trans_pkgd, "provides");
	for (i = 0; i < xbps_array_count(provides); i++) {
		char *tmp = NULL;

		xbps_array_get_cstring(provides, i, &vpkgver);
		if (strchr(vpkgver, '_') == NULL) {
			tmp = xbps_xasprintf("%s_1", vpkgver);
			vpkgver = strdup(tmp);
		}
		vpkgname = xbps_pkg_name(vpkgver);
		assert(vpkgname);
		rundeps = xbps_dictionary_get(rev_pkgd, "run_depends");
		for (x = 0; x < xbps_array_count(rundeps); x++) {
			xbps_array_get_cstring_nocopy(rundeps, x, &pkgpattern);
			if (((pkgname = xbps_pkgpattern_name(pkgpattern)) == NULL) &&
			    ((pkgname = xbps_pkg_name(pkgpattern)) == NULL))
				continue;

			if (strcmp(vpkgname, pkgname)) {
				free(pkgname);
				continue;
			}
			free(pkgname);
			if (xbps_pkgpattern_match(vpkgver, pkgpattern))
				continue;

			/*
			 * Installed package conflicts with package
			 * in transaction being updated, check
			 * if a new version of this conflicting package
			 * is in the transaction.
			 */
			xbps_dictionary_get_cstring_nocopy(trans_pkgd, "pkgver", &pkgver);
			pkgdepname = xbps_pkg_name(pkgver);
			assert(pkgdepname);
			if (xbps_find_pkg_in_array(unsorted, pkgdepname)) {
				free(pkgdepname);
				continue;
			}
			free(pkgdepname);

			mdeps = xbps_dictionary_get(xhp->transd, "missing_deps");
			xbps_dictionary_get_cstring_nocopy(trans_pkgd, "pkgver", &pkgver);
			xbps_dictionary_get_cstring_nocopy(rev_pkgd, "pkgver", &revpkgver);
			str = xbps_xasprintf("CONFLICT: `%s' update "
			    "breaks `%s', needs `%s' virtual pkg (got `%s`)",
			    pkgver, revpkgver, pkgpattern, vpkgver);
			xbps_array_add_cstring(mdeps, str);
			free(str);
			matched = true;
		}
		free(vpkgname);
		free(vpkgver);
	}
	return matched;
}