예제 #1
0
파일: plist_find.c 프로젝트: prodigeni/xbps
static xbps_dictionary_t
get_pkg_in_array(xbps_array_t array, const char *str, bool virtual)
{
	xbps_object_t obj = NULL;
	xbps_object_iterator_t iter;
	const char *pkgver;
	char *dpkgn;
	bool found = false;

	iter = xbps_array_iterator(array);
	assert(iter);

	while ((obj = xbps_object_iterator_next(iter))) {
		if (virtual) {
			/*
			 * Check if package pattern matches
			 * any virtual package version in dictionary.
			 */
			if (xbps_pkgpattern_version(str))
				found = xbps_match_virtual_pkg_in_dict(obj, str, true);
			else
				found = xbps_match_virtual_pkg_in_dict(obj, str, false);

			if (found)
				break;
		} else if (xbps_pkgpattern_version(str)) {
			/* match by pattern against pkgver */
			if (!xbps_dictionary_get_cstring_nocopy(obj,
			    "pkgver", &pkgver))
				continue;
			if (xbps_pkgpattern_match(pkgver, str)) {
				found = true;
				break;
			}
		} else if (xbps_pkg_version(str)) {
			/* match by exact pkgver */
			if (!xbps_dictionary_get_cstring_nocopy(obj,
			    "pkgver", &pkgver))
				continue;
			if (strcmp(str, pkgver) == 0) {
				found = true;
				break;
			}
		} else {
			/* match by pkgname */
			if (!xbps_dictionary_get_cstring_nocopy(obj,
			    "pkgver", &pkgver))
				continue;
			dpkgn = xbps_pkg_name(pkgver);
			assert(dpkgn);
			if (strcmp(dpkgn, str) == 0) {
				free(dpkgn);
				found = true;
				break;
			}
			free(dpkgn);
		}
	}
예제 #2
0
prop_dictionary_t
xbps_rpool_dictionary_metadata_plist(struct xbps_handle *xhp,
				     const char *pattern,
				     const char *plistf)
{
	prop_dictionary_t pkgd = NULL, plistd = NULL;
	const char *repoloc;
	char *url;

	assert(pattern != NULL);
	assert(plistf != NULL);
	/*
	 * Iterate over the the repository pool and search for a plist file
	 * in the binary package matching `pattern'. The plist file will be
	 * internalized to a proplib dictionary.
	 *
	 * The first repository that has it wins and the loop is stopped.
	 * This will work locally and remotely, thanks to libarchive and
	 * libfetch!
	 */
	if (xbps_pkgpattern_version(pattern))
		pkgd = xbps_rpool_find_pkg(xhp, pattern, true, false);
	else
		pkgd = xbps_rpool_find_pkg(xhp, pattern, false, true);

	if (pkgd == NULL)
		goto out;

	prop_dictionary_get_cstring_nocopy(pkgd, "repository", &repoloc);
	url = xbps_path_from_repository_uri(xhp, pkgd, repoloc);
	if (url == NULL) {
		errno = EINVAL;
		goto out;
	}
	plistd = xbps_dictionary_metadata_plist_by_url(url, plistf);
	free(url);

out:
	if (plistd == NULL)
		errno = ENOENT;

	return plistd;
}
예제 #3
0
파일: main.c 프로젝트: bougyman/xbps
int
main(int argc, char **argv)
{
	xbps_dictionary_t dict;
	struct xbps_handle xh;
	struct xferstat xfer;
	const char *version, *rootdir = NULL, *confdir = NULL;
	char *pkgname, *hash, *filename;
	int flags = 0, c, rv = 0;

	while ((c = getopt(argc, argv, "C:dr:V")) != -1) {
		switch (c) {
		case 'C':
			confdir = optarg;
			break;
		case 'r':
			/* To specify the root directory */
			rootdir = optarg;
			break;
		case 'd':
			flags |= XBPS_FLAG_DEBUG;
			break;
		case 'V':
			printf("%s\n", XBPS_RELVER);
			exit(EXIT_SUCCESS);
		case '?':
		default:
			usage();
		}
	}

	argc -= optind;
	argv += optind;

	if (argc < 1)
		usage();

	memset(&xh, 0, sizeof(xh));

	if ((strcmp(argv[0], "version") == 0) ||
	    (strcmp(argv[0], "real-version") == 0) ||
	    (strcmp(argv[0], "arch") == 0) ||
	    (strcmp(argv[0], "getsystemdir") == 0) ||
	    (strcmp(argv[0], "fetch") == 0)) {
		/*
		* Initialize libxbps.
		*/
		xh.flags = flags;
		xh.fetch_cb = fetch_file_progress_cb;
		xh.fetch_cb_data = &xfer;
		if (rootdir)
			xbps_strlcpy(xh.rootdir, rootdir, sizeof(xh.rootdir));
		if (confdir)
			xbps_strlcpy(xh.confdir, confdir, sizeof(xh.confdir));
		if ((rv = xbps_init(&xh)) != 0) {
			xbps_error_printf("xbps-uhelper: failed to "
			    "initialize libxbps: %s.\n", strerror(rv));
			exit(EXIT_FAILURE);
		}
	}

	if (strcmp(argv[0], "version") == 0) {
		/* Prints version of an installed package */
		if (argc != 2)
			usage();

		if ((((dict = xbps_pkgdb_get_pkg(&xh, argv[1])) == NULL)) &&
		    (((dict = xbps_pkgdb_get_virtualpkg(&xh, argv[1])) == NULL)))
			exit(EXIT_FAILURE);

		xbps_dictionary_get_cstring_nocopy(dict, "pkgver", &version);
		printf("%s\n", xbps_pkg_version(version));
	} else if (strcmp(argv[0], "real-version") == 0) {
		/* Prints version of an installed real package, not virtual */
		if (argc != 2)
			usage();

		if ((dict = xbps_pkgdb_get_pkg(&xh, argv[1])) == NULL)
			exit(EXIT_FAILURE);

		xbps_dictionary_get_cstring_nocopy(dict, "pkgver", &version);
		printf("%s\n", xbps_pkg_version(version));
	} else if (strcmp(argv[0], "getpkgversion") == 0) {
		/* Returns the version of a pkg string */
		if (argc != 2)
			usage();

		version = xbps_pkg_version(argv[1]);
		if (version == NULL) {
			fprintf(stderr,
			    "Invalid string, expected <string>-<version>_<revision>\n");
			exit(EXIT_FAILURE);
		}
		printf("%s\n", version);
	} else if (strcmp(argv[0], "getpkgname") == 0) {
		/* Returns the name of a pkg string */
		if (argc != 2)
			usage();

		pkgname = xbps_pkg_name(argv[1]);
		if (pkgname == NULL) {
			fprintf(stderr,
			    "Invalid string, expected <string>-<version>_<revision>\n");
			exit(EXIT_FAILURE);
		}
		printf("%s\n", pkgname);
		free(pkgname);
	} else if (strcmp(argv[0], "getpkgrevision") == 0) {
		/* Returns the revision of a pkg string */
		if (argc != 2)
			usage();

		version = xbps_pkg_revision(argv[1]);
		if (version == NULL)
			exit(EXIT_SUCCESS);

		printf("%s\n", version);
	} else if (strcmp(argv[0], "getpkgdepname") == 0) {
		/* Returns the pkgname of a dependency */
		if (argc != 2)
			usage();

		pkgname = xbps_pkgpattern_name(argv[1]);
		if (pkgname == NULL)
			exit(EXIT_FAILURE);

		printf("%s\n", pkgname);
		free(pkgname);
	} else if (strcmp(argv[0], "getpkgdepversion") == 0) {
		/* returns the version of a package pattern dependency */
		if (argc != 2)
			usage();

		version = xbps_pkgpattern_version(argv[1]);
		if (version == NULL)
			exit(EXIT_FAILURE);

		printf("%s\n", version);
	} else if (strcmp(argv[0], "binpkgver") == 0) {
		/* Returns the pkgver of a binpkg string */
		if (argc != 2)
			usage();

		version = xbps_binpkg_pkgver(argv[1]);
		if (version == NULL) {
			fprintf(stderr,
			    "Invalid string, expected <pkgname>-<version>_<revision>.<arch>.xbps\n");
			exit(EXIT_FAILURE);
		}
		printf("%s\n", version);
	} else if (strcmp(argv[0], "binpkgarch") == 0) {
		/* Returns the arch of a binpkg string */
		if (argc != 2)
			usage();

		version = xbps_binpkg_arch(argv[1]);
		if (version == NULL) {
			fprintf(stderr,
			    "Invalid string, expected <pkgname>-<version>_<revision>.<arch>.xbps\n");
			exit(EXIT_FAILURE);
		}
		printf("%s\n", version);
	} else if (strcmp(argv[0], "pkgmatch") == 0) {
		/* Matches a pkg with a pattern */
		if (argc != 3)
			usage();

		exit(xbps_pkgpattern_match(argv[1], argv[2]));
	} else if (strcmp(argv[0], "cmpver") == 0) {
		/* Compare two version strings, installed vs required */
		if (argc != 3)
			usage();

		exit(xbps_cmpver(argv[1], argv[2]));
	} else if (strcmp(argv[0], "arch") == 0) {
		/* returns the xbps native arch */
		if (argc != 1)
			usage();

		printf("%s\n", xh.native_arch);
	} else if (strcmp(argv[0], "getsystemdir") == 0) {
		/* returns the xbps system directory (<sharedir>/xbps.d) */
		if (argc != 1)
			usage();

		printf("%s\n", XBPS_SYSDEFCONF_PATH);
	} else if (strcmp(argv[0], "digest") == 0) {
		/* Prints SHA256 hashes for specified files */
		if (argc < 2)
			usage();

		for (int i = 1; i < argc; i++) {
			hash = xbps_file_hash(argv[i]);
			if (hash == NULL) {
				fprintf(stderr,
				    "E: couldn't get hash for %s (%s)\n",
				    argv[i], strerror(errno));
				exit(EXIT_FAILURE);
			}
			printf("%s\n", hash);
		}
	} else if (strcmp(argv[0], "fetch") == 0) {
		/* Fetch a file from specified URL */
		if (argc < 2)
			usage();

		for (int i = 1; i < argc; i++) {
			filename = fname(argv[i]);
			rv = xbps_fetch_file_dest(&xh, argv[i], filename, "v");

			if (rv == -1) {
				printf("%s: %s\n", argv[i],
				    xbps_fetch_error_string());
			} else if (rv == 0) {
				printf("%s: file is identical with remote.\n",
				    argv[i]);
			} else
				rv = 0;
		}
	} else {
		usage();
	}

	exit(rv ? EXIT_FAILURE : EXIT_SUCCESS);
}
예제 #4
0
static int
add_missing_reqdep(struct xbps_handle *xhp, const char *reqpkg)
{
	xbps_array_t mdeps;
	xbps_object_iterator_t iter = NULL;
	xbps_object_t obj;
	unsigned int idx = 0;
	bool add_pkgdep, pkgfound, update_pkgdep;
	int rv = 0;

	assert(reqpkg != NULL);

	add_pkgdep = update_pkgdep = pkgfound = false;
	mdeps = xbps_dictionary_get(xhp->transd, "missing_deps");

	iter = xbps_array_iterator(mdeps);
	if (iter == NULL)
		goto out;

	while ((obj = xbps_object_iterator_next(iter)) != NULL) {
		const char *curdep, *curver, *pkgver;
		char *curpkgnamedep = NULL, *pkgnamedep = NULL;

		assert(xbps_object_type(obj) == XBPS_TYPE_STRING);
		curdep = xbps_string_cstring_nocopy(obj);
		curver = xbps_pkgpattern_version(curdep);
		pkgver = xbps_pkgpattern_version(reqpkg);
		if (curver == NULL || pkgver == NULL)
			goto out;
		curpkgnamedep = xbps_pkgpattern_name(curdep);
		if (curpkgnamedep == NULL)
			goto out;
		pkgnamedep = xbps_pkgpattern_name(reqpkg);
		if (pkgnamedep == NULL) {
			free(curpkgnamedep);
			goto out;
		}
		if (strcmp(pkgnamedep, curpkgnamedep) == 0) {
			pkgfound = true;
			if (strcmp(curver, pkgver) == 0) {
				free(curpkgnamedep);
				free(pkgnamedep);
				rv = EEXIST;
				goto out;
			}
			/*
			 * if new dependency version is greater than current
			 * one, store it.
			 */
			xbps_dbg_printf(xhp, "Missing pkgdep name matched, curver: %s newver: %s\n", curver, pkgver);
			if (xbps_cmpver(curver, pkgver) <= 0) {
				add_pkgdep = false;
				free(curpkgnamedep);
				free(pkgnamedep);
				rv = EEXIST;
				goto out;
			}
			update_pkgdep = true;
		}
		free(curpkgnamedep);
		free(pkgnamedep);
		if (pkgfound)
			break;

		idx++;
	}
	add_pkgdep = true;
out:
	if (iter)
		xbps_object_iterator_release(iter);
	if (update_pkgdep)
		xbps_array_remove(mdeps, idx);
	if (add_pkgdep) {
		char *str;

		str = xbps_xasprintf("MISSING: %s", reqpkg);
		xbps_array_add_cstring(mdeps, str);
		free(str);
	}

	return rv;
}