Esempio n. 1
0
File: add.c Progetto: ppentchev/pkg
int
exec_add(int argc, char **argv)
{
	struct pkgdb *db = NULL;
	struct sbuf *failedpkgs = NULL;
	char path[MAXPATHLEN];
	char *file;
	int retcode;
	int ch;
	int i;
	int failedpkgcount = 0;
	pkg_flags f = PKG_FLAG_NONE;
	struct pkg_manifest_key *keys = NULL;
	const char *location = NULL;

	/* options descriptor */
	struct option longopts[] = {
		{ "no-scripts",          no_argument,            NULL,           'I' },
		{ "automatic",           no_argument,            NULL,           'A' },
		{ "force",               no_argument,            NULL,           'f' },
		{ "accept-missing",      no_argument,            NULL,           'M' },
		{ "quiet",               no_argument,            NULL,           'q' },
		{ "relocate",            required_argument,      NULL,            1  },
		{ NULL,                  0,                      NULL,            0  }
	};

	while ((ch = getopt_long(argc, argv, "IAfqM", longopts, NULL)) != -1) {
		switch (ch) {
		case 'I':
			f |= PKG_ADD_NOSCRIPT;
			break;
		case 'A':
			f |= PKG_ADD_AUTOMATIC;
			break;
		case 'f':
			f |= PKG_ADD_FORCE;
			break;
		case 'M':
			f |= PKG_ADD_FORCE_MISSING;
			break;
		case 'q':
			quiet = true;
			break;
		case 1:
			location = optarg;
			break;
		default:
			usage_add();
			return (EX_USAGE);
		}
	}
	argc -= optind;
	argv += optind;

	if (argc < 1) {
		usage_add();
		return (EX_USAGE);
	}

	retcode = pkgdb_access(PKGDB_MODE_READ  |
			       PKGDB_MODE_WRITE |
			       PKGDB_MODE_CREATE,
			       PKGDB_DB_LOCAL);
	if (retcode == EPKG_ENOACCESS) {
		warnx("Insufficient privileges to add packages");
		return (EX_NOPERM);
	} else if (retcode != EPKG_OK)
		return (EX_IOERR);

	if (pkgdb_open(&db, PKGDB_DEFAULT) != EPKG_OK)
		return (EX_IOERR);

	if (pkgdb_obtain_lock(db, PKGDB_LOCK_EXCLUSIVE) != EPKG_OK) {
		pkgdb_close(db);
		warnx("Cannot get an exclusive lock on a database, it is locked by another process");
		return (EX_TEMPFAIL);
	}

	failedpkgs = sbuf_new_auto();
	pkg_manifest_keys_new(&keys);
	for (i = 0; i < argc; i++) {
		if (is_url(argv[i]) == EPKG_OK) {
			snprintf(path, sizeof(path), "%s/%s.XXXXX",
			    getenv("TMPDIR") != NULL ? getenv("TMPDIR") : "/tmp", basename(argv[i]));
			if ((retcode = pkg_fetch_file(NULL, argv[i], path, 0)) != EPKG_OK)
				break;

			file = path;
		} else {
			file = argv[i];

			/* Special case: treat a filename of "-" as
			   meaning 'read from stdin.'  It doesn't make
			   sense to have a filename of "-" more than
			   once per command line, but we aren't
			   testing for that at the moment */

			if (strcmp(file, "-") != 0 && access(file, F_OK) != 0) {
				warn("%s", file);
				if (errno == ENOENT)
					warnx("Was 'pkg install %s' meant?", file);
				sbuf_cat(failedpkgs, argv[i]);
				if (i != argc - 1)
					sbuf_printf(failedpkgs, ", ");
				failedpkgcount++;
				continue;
			}

		}

		if ((retcode = pkg_add(db, file, f, keys, location)) != EPKG_OK) {
			sbuf_cat(failedpkgs, argv[i]);
			if (i != argc - 1)
				sbuf_printf(failedpkgs, ", ");
			failedpkgcount++;
		}

		if (is_url(argv[i]) == EPKG_OK)
			unlink(file);

	}
	pkg_manifest_keys_free(keys);
	pkgdb_release_lock(db, PKGDB_LOCK_EXCLUSIVE);
	pkgdb_close(db);
	
	if(failedpkgcount > 0) {
		sbuf_finish(failedpkgs);
		printf("\nFailed to install the following %d package(s): %s\n", failedpkgcount, sbuf_data(failedpkgs));
		retcode = EPKG_FATAL;
	}
	sbuf_delete(failedpkgs);

	if (messages != NULL) {
		sbuf_finish(messages);
		printf("%s", sbuf_data(messages));
	}

	return (retcode == EPKG_OK ? EX_OK : EX_SOFTWARE);
}
Esempio n. 2
0
int
exec_upgrade(int argc, char **argv)
{
	struct pkgdb *db = NULL;
	struct pkg_jobs *jobs = NULL;
	const char *reponame = NULL;
	int retcode;
	int updcode;
	int ch;
	bool yes;
	bool dry_run = false;
	bool auto_update;
	nbactions = nbdone = 0;
	pkg_flags f = PKG_FLAG_NONE | PKG_FLAG_PKG_VERSION_TEST;

	pkg_config_bool(PKG_CONFIG_ASSUME_ALWAYS_YES, &yes);
	pkg_config_bool(PKG_CONFIG_REPO_AUTOUPDATE, &auto_update);


	while ((ch = getopt(argc, argv, "fInqFr:Uy")) != -1) {
		switch (ch) {
		case 'f':
			f |= PKG_FLAG_FORCE;
			break;
		case 'I':
			f |= PKG_FLAG_NOSCRIPT;
			break;
		case 'U':
			auto_update = false;
			break;
		case 'n':
			f |= PKG_FLAG_DRY_RUN;
			dry_run = true;
			break;
		case 'F':
			f |= PKG_FLAG_SKIP_INSTALL;
			break;
		case 'q':
			quiet = true;
			break;
		case 'r':
			reponame = optarg;
			break;
		case 'y':
			yes = true;
			break;
		default:
			usage_upgrade();
			return (EX_USAGE);
			/* NOTREACHED */
		}
	}
	argc -= optind;
	argv += optind;

	if (argc != 0) {
		usage_upgrade();
		return (EX_USAGE);
	}

	if (dry_run && !auto_update)
		retcode = pkgdb_access(PKGDB_MODE_READ,
				       PKGDB_DB_LOCAL|PKGDB_DB_REPO);
	else
		retcode = pkgdb_access(PKGDB_MODE_READ  |
				       PKGDB_MODE_WRITE |
				       PKGDB_MODE_CREATE,
				       PKGDB_DB_LOCAL|PKGDB_DB_REPO);
	if (retcode == EPKG_ENOACCESS && dry_run) {
		auto_update = false;
		retcode = pkgdb_access(PKGDB_MODE_READ,
				       PKGDB_DB_LOCAL|PKGDB_DB_REPO);
	}

	if (retcode == EPKG_ENOACCESS) {
		warnx("Insufficient privilege to upgrade packages");
		return (EX_NOPERM);
	} else if (retcode != EPKG_OK)
		return (EX_IOERR);
	else
		retcode = EX_SOFTWARE;
	
	/* first update the remote repositories if needed */
	if (auto_update &&
	    (updcode = pkgcli_update(false)) != EPKG_OK)
		return (updcode);

	if (pkgdb_open(&db, PKGDB_REMOTE) != EPKG_OK)
		return (EX_IOERR);

	if (pkg_jobs_new(&jobs, PKG_JOBS_UPGRADE, db) != EPKG_OK)
		goto cleanup;

	if (reponame != NULL && pkg_jobs_set_repository(jobs, reponame) != EPKG_OK)
		goto cleanup;

	pkg_jobs_set_flags(jobs, f);

	if (pkg_jobs_solve(jobs) != EPKG_OK)
		goto cleanup;

	if ((nbactions = pkg_jobs_count(jobs)) == 0) {
		if (!quiet)
			printf("Nothing to do\n");
		retcode = EXIT_SUCCESS;
		goto cleanup;
	}

	if (!quiet || dry_run) {
		print_jobs_summary(jobs,
		    "Upgrades have been requested for the following %d "
		    "packages:\n\n", nbactions);

		if (!yes && !dry_run)
			yes = query_yesno("\nProceed with upgrading "
			          "packages [y/N]: ");
		if (dry_run)
			yes = false;
	}

	if (yes && pkg_jobs_apply(jobs) != EPKG_OK)
		goto cleanup;

	if (messages != NULL) {
		sbuf_finish(messages);
		printf("%s", sbuf_data(messages));
	}

	retcode = EXIT_SUCCESS;

	cleanup:
	pkg_jobs_free(jobs);
	pkgdb_close(db);

	if (!yes && newpkgversion)
		newpkgversion = false;

	return (retcode);
}
Esempio n. 3
0
File: set.c Progetto: aklv/pkgng
int
exec_set(int argc, char **argv)
{
	struct pkgdb *db = NULL;
	struct pkgdb_it *it = NULL;
	struct pkg *pkg = NULL;
	int ch;
	int i;
	bool yes;
	match_t match = MATCH_EXACT;
	int newautomatic = -1;
	bool automatic = false;
	const char *errstr;
	const char *name;
	const char *version;
	char *neworigin = NULL;
	char *oldorigin = NULL;
	unsigned int loads = PKG_LOAD_BASIC;
	unsigned int sets = 0;
	int retcode;

	pkg_config_bool(PKG_CONFIG_ASSUME_ALWAYS_YES, &yes);

	while ((ch = getopt(argc, argv, "A:agio:xy")) != -1) {
		switch (ch) {
		case 'A':
			sets |= AUTOMATIC;
			newautomatic = strtonum(optarg, 0, 1, &errstr);
			if (errstr)
				errx(EX_USAGE, "Wrong value for -A. "
				    "Expecting 0 or 1, got: %s (%s)",
				    optarg, errstr);
			break;
		case 'a':
			match = MATCH_ALL;
			break;
		case 'g':
			match = MATCH_GLOB;
			break;
		case 'i':
			pkgdb_set_case_sensitivity(false);
			break;
		case 'o':
			sets |= ORIGIN;
			loads |= PKG_LOAD_DEPS;
			match = MATCH_ALL;
			oldorigin = strdup(optarg);
			neworigin = strrchr(oldorigin, ':');
			if (neworigin == NULL) {
				free(oldorigin);
				errx(EX_USAGE, "Wrong format for -o. "
				    "Expecting oldorigin:neworigin, got: %s",
				    optarg);
			}
			*neworigin = '\0';
			neworigin++;
			if (strrchr(oldorigin, '/') == NULL ||
			    strrchr(neworigin, '/') == NULL) {
				free(oldorigin);
				errx(EX_USAGE,
				    "Bad origin format, got: %s", optarg);
			}
			break;
		case 'x':
			match = MATCH_REGEX;
			break;
		case 'y':
			yes = true;
			break;
		default:
			if (oldorigin != NULL)
				free(oldorigin);
			
			usage_set();
			return (EX_USAGE);
		}
	}

	argc -= optind;
	argv += optind;

	if ((argc < 1 && match != MATCH_ALL) || (newautomatic == -1 && neworigin == NULL)) {
		usage_set();
		return (EX_USAGE);
	}

	retcode = pkgdb_access(PKGDB_MODE_READ|PKGDB_MODE_WRITE,
			       PKGDB_DB_LOCAL);
	if (retcode == EPKG_ENODB) {
		if (match == MATCH_ALL)
			return (EX_OK);
		if (!quiet)
			warnx("No packages installed.  Nothing to do!");
		return (EX_OK);
	} else if (retcode == EPKG_ENOACCESS) {
		warnx("Insufficient privilege to modify package database");
		return (EX_NOPERM);
	} else if (retcode != EPKG_OK) {
		warnx("Error accessing package database");
		return (EX_SOFTWARE);
	}

	if (pkgdb_open(&db, PKGDB_DEFAULT) != EPKG_OK)
		return (EX_IOERR);
 
	if (oldorigin != NULL) {
		match = MATCH_ALL;
		if ((it = pkgdb_query(db, oldorigin, MATCH_EXACT)) == NULL) {
			pkgdb_close(db);
			return (EX_IOERR);
		}

		if (pkgdb_it_next(it, &pkg, PKG_LOAD_BASIC) != EPKG_OK) {
			pkg = NULL;
/*			fprintf(stderr, "%s not installed\n", oldorigin);
			free(oldorigin);
			pkgdb_it_free(it);
			pkgdb_close(db);
			return (EX_SOFTWARE);*/
		}
		if (pkg != NULL)
			pkg_get(pkg, PKG_NAME, &name, PKG_VERSION, &version);
		if (!yes) {
			if (pkg != NULL)
				yes = query_yesno("Change origin from %s to %s for %s-%s? [y/N]: ",
				    oldorigin, neworigin, name, version);
			else
				yes = query_yesno("Change origin from %s to %s for all dependencies? "
				    "[y/N]: ", oldorigin, neworigin);
		}
		if (pkg != NULL && yes) {
			if (pkgdb_set(db, pkg, PKG_SET_ORIGIN, neworigin) != EPKG_OK)
				return (EX_IOERR);
		}
		pkgdb_it_free(it);
	}
	i = 0;
	do {
		bool save_yes = yes;

		if ((it = pkgdb_query(db, argv[i], match)) == NULL) {
			free(oldorigin);
			pkgdb_close(db);
			return (EX_IOERR);
		}

		while (pkgdb_it_next(it, &pkg, loads) == EPKG_OK) {
			if ((sets & AUTOMATIC) == AUTOMATIC) {
				pkg_get(pkg, PKG_AUTOMATIC, &automatic);
				if (automatic == newautomatic)
					continue;
				if (!yes) {
					pkg_get(pkg, PKG_NAME, &name, PKG_VERSION, &version);
					if (newautomatic)
						yes = query_yesno("Mark %s-%s as automatically installed? [y/N]: ", name, version);
					else
						yes = query_yesno("Mark %s-%s as not automatically installed? [y/N]: ", name, version);
				}
				if (yes)
					pkgdb_set(db, pkg, PKG_SET_AUTOMATIC, newautomatic);
				yes = save_yes;
			}
			if ((sets & ORIGIN) == ORIGIN) {
				struct pkg_dep *d = NULL;
				while (pkg_deps(pkg, &d) == EPKG_OK) {
					/*
					 * Do not query user when he has already
					 * been queried.
					 */
					if (pkgdb_set(db, pkg, PKG_SET_DEPORIGIN, oldorigin, neworigin) != EPKG_OK)
						return (EX_IOERR);
				}
			}
		}
		pkgdb_it_free(it);
		i++;
	} while (i < argc);

	free(oldorigin);
	pkg_free(pkg);
	pkgdb_close(db);

	return (EX_OK);
}
Esempio n. 4
0
int
exec_autoremove(int argc, char **argv)
{
	struct pkgdb *db = NULL;
	struct pkg_jobs *jobs = NULL;
	int retcode = EX_OK;
	int ch;
	nbactions = nbdone = 0;
	pkg_flags f = PKG_FLAG_FORCE;
	bool rc = false;

	struct option longopts[] = {
		{ "dry-run",	no_argument,	NULL,	'n' },
		{ "quiet",	no_argument,	NULL,	'q' },
		{ "yes",	no_argument,	NULL,	'y' },
		{ NULL,		0,		NULL,	0   },
	};

	while ((ch = getopt_long(argc, argv, "+nqy", longopts, NULL)) != -1) {
		switch (ch) {
		case 'n':
			f |= PKG_FLAG_DRY_RUN;
			dry_run = true;
			break;
		case 'q':
			quiet = true;
			break;
		case 'y':
			yes = true;
			break;
		default:
			break;
		}
	}
	argc -= optind;
	argv += optind;

	if (argc != 0) {
		usage_autoremove();
		return (EX_USAGE);
	}

	if (dry_run) 
		retcode = pkgdb_access(PKGDB_MODE_READ, PKGDB_DB_LOCAL);
	else
		retcode = pkgdb_access(PKGDB_MODE_READ|PKGDB_MODE_WRITE,
				       PKGDB_DB_LOCAL);

	if (retcode == EPKG_ENOACCESS) {
		warnx("Insufficient privileges to autoremove packages");
		return (EX_NOPERM);
	} else if (retcode == EPKG_ENODB) {
		warnx("No packages installed.  Nothing to do!");
		return (EX_OK);
	} else if (retcode != EPKG_OK) {
		warnx("Error accessing the package database");
		return (EX_SOFTWARE);
	}

	if (pkgdb_open(&db, PKGDB_DEFAULT) != EPKG_OK) {
		return (EX_IOERR);
	}

	if (pkgdb_obtain_lock(db, PKGDB_LOCK_ADVISORY) != EPKG_OK) {
		pkgdb_close(db);
		warnx("Cannot get an advisory lock on a database, it is locked by another process");
		return (EX_TEMPFAIL);
	}
	/* Always force packages to be removed */
	if (pkg_jobs_new(&jobs, PKG_JOBS_AUTOREMOVE, db) != EPKG_OK) {
		pkgdb_close(db);
		return (EX_IOERR);
	}

	pkg_jobs_set_flags(jobs, f);

	if ((retcode = pkg_jobs_solve(jobs)) != EPKG_OK) {
		retcode = EX_SOFTWARE;
		goto cleanup;
	}

	if ((nbactions = pkg_jobs_count(jobs)) == 0) {
		printf("Nothing to do.\n");
		goto cleanup;
	}

	if (!quiet || dry_run) {
		print_jobs_summary(jobs,
				"Deinstallation has been requested for the following %d packages:\n\n", nbactions);
			rc = query_yesno(false,
		            "\nProceed with deinstalling packages [y/N]: ");
	}
	if (!rc || dry_run || (retcode = pkg_jobs_apply(jobs)) != EPKG_OK) {
		goto cleanup;
	}

	pkgdb_compact(db);

cleanup:
	pkg_jobs_free(jobs);
	pkgdb_release_lock(db, PKGDB_LOCK_ADVISORY);
	pkgdb_close(db);

	return (retcode);
}
Esempio n. 5
0
File: check.c Progetto: AMDmi3/pkg
static int
fix_deps(struct pkgdb *db, struct deps_head *dh, int nbpkgs)
{
	struct pkg_jobs *jobs = NULL;
	struct deps_entry *e = NULL;
	char **pkgs = NULL;
	int i = 0;
	bool rc;
	pkg_flags f = PKG_FLAG_AUTOMATIC;

	assert(db != NULL);
	assert(nbpkgs > 0);

	if ((pkgs = calloc(nbpkgs, sizeof (char *))) == NULL)
		err(1, "calloc()");

	STAILQ_FOREACH(e, dh, next)
		pkgs[i++] = e->name;

	if (pkgdb_open(&db, PKGDB_REMOTE) != EPKG_OK) {
		free(pkgs);
		return (EPKG_ENODB);
	}

	if (pkg_jobs_new(&jobs, PKG_JOBS_INSTALL, db) != EPKG_OK) {
		goto cleanup;
	}

	pkg_jobs_set_flags(jobs, f);

	if (pkg_jobs_add(jobs, MATCH_EXACT, pkgs, nbpkgs) == EPKG_FATAL) {
		goto cleanup;
	}

	if (pkg_jobs_solve(jobs) != EPKG_OK) {
		goto cleanup;
	}

	if (pkg_jobs_count(jobs) == 0) {
		printf("\nUnable to find packages for installation.\n\n");
		goto cleanup;
	}

	/* print a summary before applying the jobs */
	print_jobs_summary(jobs, "The following packages will be installed:\n\n");
	
	rc = query_yesno(false, "\n>>> Try to fix the missing dependencies? ");

	if (rc) {
		if (pkgdb_access(PKGDB_MODE_WRITE, PKGDB_DB_LOCAL) ==
		    EPKG_ENOACCESS) {
			warnx("Insufficient privileges to modify the package "
			      "database");

			goto cleanup;
		}

		pkg_jobs_apply(jobs);
	}

cleanup:
	free(pkgs);
	if (jobs != NULL)
		pkg_jobs_free(jobs);

	return (EPKG_OK);
}
Esempio n. 6
0
File: check.c Progetto: AMDmi3/pkg
int
exec_check(int argc, char **argv)
{
	struct pkg *pkg = NULL;
	struct pkgdb_it *it = NULL;
	struct pkgdb *db = NULL;
	struct sbuf *msg = NULL;
	match_t match = MATCH_EXACT;
	int flags = PKG_LOAD_BASIC;
	int ret, rc = EX_OK;
	int ch;
	bool dcheck = false;
	bool checksums = false;
	bool recompute = false;
	bool reanalyse_shlibs = false;
	bool noinstall = false;
	int nbpkgs = 0;
	int i, processed, total = 0;
	int verbose = 0;

	struct option longopts[] = {
		{ "all",		no_argument,	NULL,	'a' },
		{ "shlibs",		no_argument,	NULL,	'B' },
		{ "case-sensitive",	no_argument,	NULL,	'C' },
		{ "dependencies",	no_argument,	NULL,	'd' },
		{ "glob",		no_argument,	NULL,	'g' },
		{ "case-insensitive",	no_argument,	NULL,	'i' },
		{ "dry-run",		no_argument,	NULL,	'n' },
		{ "recompute",		no_argument,	NULL,	'r' },
		{ "checksums",		no_argument,	NULL,	's' },
		{ "verbose",		no_argument,	NULL,	'v' },
		{ "quiet",              no_argument,    NULL,   'q' },
		{ "regex",		no_argument,	NULL,	'x' },
		{ "yes",		no_argument,	NULL,	'y' },
		{ NULL,			0,		NULL,	0   },
	};

	struct deps_head dh = STAILQ_HEAD_INITIALIZER(dh);

	processed = 0;

	while ((ch = getopt_long(argc, argv, "+aBCdginqrsvxy", longopts, NULL)) != -1) {
		switch (ch) {
		case 'a':
			match = MATCH_ALL;
			break;
		case 'B':
			reanalyse_shlibs = true;
			flags |= PKG_LOAD_FILES;
			break;
		case 'C':
			pkgdb_set_case_sensitivity(true);
			break;
		case 'd':
			dcheck = true;
			flags |= PKG_LOAD_DEPS;
			break;
		case 'g':
			match = MATCH_GLOB;
			break;
		case 'i':
			pkgdb_set_case_sensitivity(false);
			break;
		case 'n':
			noinstall = true;
			break;
		case 'q':
			quiet = true;
			break;
		case 'r':
			recompute = true;
			flags |= PKG_LOAD_FILES;
			break;
		case 's':
			checksums = true;
			flags |= PKG_LOAD_FILES;
			break;
		case 'v':
			verbose = 1;
			break;
		case 'x':
			match = MATCH_REGEX;
			break;
		case 'y':
			yes = true;
			break;
		default:
			usage_check();
			return (EX_USAGE);
		}
	}
	argc -= optind;
	argv += optind;

	/* Default to all packages if no pkg provided */
	if (argc == 0 && (dcheck || checksums || recompute || reanalyse_shlibs)) {
		match = MATCH_ALL;
	} else if ((argc == 0 && match != MATCH_ALL) || !(dcheck || checksums || recompute || reanalyse_shlibs)) {
		usage_check();
		return (EX_USAGE);
	}

	if (recompute || reanalyse_shlibs)
		ret = pkgdb_access(PKGDB_MODE_READ|PKGDB_MODE_WRITE,
				   PKGDB_DB_LOCAL);
	else
		ret = pkgdb_access(PKGDB_MODE_READ, PKGDB_DB_LOCAL);

	if (ret == EPKG_ENODB) {
		if (!quiet)
			warnx("No packages installed.  Nothing to do!");
		return (EX_OK);
	} else if (ret == EPKG_ENOACCESS) {
		warnx("Insufficient privileges to access the package database");
		return (EX_NOPERM);
	} else if (ret != EPKG_OK) {
		warnx("Error accessing the package database");
		return (EX_SOFTWARE);
	}

	if (pkgdb_access(PKGDB_MODE_WRITE, PKGDB_DB_LOCAL) == EPKG_ENOACCESS) {
		warnx("Insufficient privileges");
		return (EX_NOPERM);
	}

	ret = pkgdb_open(&db, PKGDB_DEFAULT);
	if (ret != EPKG_OK)
		return (EX_IOERR);

	if (pkgdb_obtain_lock(db, PKGDB_LOCK_ADVISORY) != EPKG_OK) {
		pkgdb_close(db);
		warnx("Cannot get an advisory lock on a database, it is locked by another process");
		return (EX_TEMPFAIL);
	}

	i = 0;
	nbdone = 0;
	do {
		/* XXX: This is really quirky, it would be cleaner to pass
		 * in multiple matches and only run this top-loop once. */
		if ((it = pkgdb_query(db, argv[i], match)) == NULL) {
			rc = EX_IOERR;
			goto cleanup;
		}

		if (msg == NULL)
			msg = sbuf_new_auto();
		if (!verbose) {
			if (!quiet) {
				if (match == MATCH_ALL)
					progressbar_start("Checking all packages");
				else {
					sbuf_printf(msg, "Checking %s", argv[i]);
					sbuf_finish(msg);
					progressbar_start(sbuf_data(msg));
				}
			}
			processed = 0;
			total = pkgdb_it_count(it);
		} else {
			if (match == MATCH_ALL)
				nbactions = pkgdb_it_count(it);
			else
				nbactions = argc;
		}

		struct sbuf *out = sbuf_new_auto();
		while (pkgdb_it_next(it, &pkg, flags) == EPKG_OK) {
			if (!quiet) {
				if (!verbose)
					progressbar_tick(processed, total);
				else {
					++nbdone;
					job_status_begin(msg);
					pkg_sbuf_printf(msg, "Checking %n-%v:",
					    pkg, pkg);
					sbuf_flush(msg);
				}
			}

			/* check for missing dependencies */
			if (dcheck) {
				if (!quiet && verbose)
					printf(" dependencies...");
				nbpkgs += check_deps(db, pkg, &dh, noinstall, out);
				if (noinstall && nbpkgs > 0) {
					rc = EX_UNAVAILABLE;
				}
			}
			if (checksums) {
				if (!quiet && verbose)
					printf(" checksums...");
				if (pkg_test_filesum(pkg) != EPKG_OK) {
					rc = EX_DATAERR;
				}
			}
			if (recompute) {
				if (pkgdb_upgrade_lock(db, PKGDB_LOCK_ADVISORY,
						PKGDB_LOCK_EXCLUSIVE) == EPKG_OK) {
					if (!quiet && verbose)
						printf(" recomputing...");
					if (pkg_recompute(db, pkg) != EPKG_OK) {
						rc = EX_DATAERR;
					}
					pkgdb_downgrade_lock(db,
					    PKGDB_LOCK_EXCLUSIVE,
					    PKGDB_LOCK_ADVISORY);
				}
				else {
					rc = EX_TEMPFAIL;
				}
			}
			if (reanalyse_shlibs) {
				if (pkgdb_upgrade_lock(db, PKGDB_LOCK_ADVISORY,
						PKGDB_LOCK_EXCLUSIVE) == EPKG_OK) {
					if (!quiet && verbose)
						printf(" shared libraries...");
					if (pkgdb_reanalyse_shlibs(db, pkg) != EPKG_OK) {
						pkg_fprintf(stderr, "Failed to "
						    "reanalyse for shlibs: "
						    "%n-%v\n", pkg, pkg);
						rc = EX_UNAVAILABLE;
					}
					pkgdb_downgrade_lock(db,
					    PKGDB_LOCK_EXCLUSIVE,
					    PKGDB_LOCK_ADVISORY);
				}
				else {
					rc = EX_TEMPFAIL;
				}
			}

			if (!quiet) {
				if (!verbose)
					++processed;
				else
					printf(" done\n");
			}
		}
		if (!quiet && !verbose)
			progressbar_tick(processed, total);
		if (sbuf_len(out) > 0) {
			sbuf_finish(out);
			printf("%s", sbuf_data(out));
		}
		sbuf_delete(out);
		if (msg != NULL) {
			sbuf_delete(msg);
			msg = NULL;
		}

		if (dcheck && nbpkgs > 0 && !noinstall) {
			printf("\n>>> Missing package dependencies were detected.\n");
			printf(">>> Found %d issue(s) in the package database.\n\n", nbpkgs);
			if (pkgdb_upgrade_lock(db, PKGDB_LOCK_ADVISORY,
					PKGDB_LOCK_EXCLUSIVE) == EPKG_OK) {
				ret = fix_deps(db, &dh, nbpkgs);
				if (ret == EPKG_OK)
					check_summary(db, &dh);
				else if (ret == EPKG_ENODB) {
					db = NULL;
					rc = EX_IOERR;
				}
				if (rc == EX_IOERR)
					goto cleanup;
				pkgdb_downgrade_lock(db, PKGDB_LOCK_EXCLUSIVE,
				    PKGDB_LOCK_ADVISORY);
			}
			else {
				rc = EX_TEMPFAIL;
				goto cleanup;
			}
		}
		pkgdb_it_free(it);
		i++;
	} while (i < argc);

cleanup:
	if (!verbose)
		progressbar_stop();
	if (msg != NULL)
		sbuf_delete(msg);
	deps_free(&dh);
	pkg_free(pkg);
	pkgdb_release_lock(db, PKGDB_LOCK_ADVISORY);
	pkgdb_close(db);

	return (rc);
}
Esempio n. 7
0
File: install.c Progetto: afb/pkgng
int
exec_install(int argc, char **argv)
{
	struct pkgdb *db = NULL;
	struct pkg_jobs *jobs = NULL;
	const char *reponame = NULL;
	int retcode;
	int updcode = EPKG_OK;
	int ch;
	bool yes;
	bool auto_update;
	match_t match = MATCH_EXACT;
	bool dry_run = false;
	nbactions = nbdone = 0;
	pkg_flags f = PKG_FLAG_NONE | PKG_FLAG_PKG_VERSION_TEST;

	pkg_config_bool(PKG_CONFIG_ASSUME_ALWAYS_YES, &yes);
	pkg_config_bool(PKG_CONFIG_REPO_AUTOUPDATE, &auto_update);

	while ((ch = getopt(argc, argv, "AfgIiLFnqRr:Uxy")) != -1) {
		switch (ch) {
		case 'A':
			f |= PKG_FLAG_AUTOMATIC;
			break;
		case 'f':
			f |= PKG_FLAG_FORCE;
			break;
		case 'g':
			match = MATCH_GLOB;
			break;
		case 'I':
			f |= PKG_FLAG_NOSCRIPT;
			break;
		case 'F':
			f |= PKG_FLAG_SKIP_INSTALL;
			break;
		case 'i':
			pkgdb_set_case_sensitivity(false);
			break;
		case 'L':
			warnx("!!! The -L flag is deprecated and will be removed. Please use -U now.");
			/* FALLTHROUGH */
		case 'U':
			auto_update = false;
			break;
		case 'n':
			f |= PKG_FLAG_DRY_RUN;
			dry_run = true;
			break;
		case 'q':
			quiet = true;
			break;
		case 'R':
			f |= PKG_FLAG_RECURSIVE;
			break;
		case 'r':
			reponame = optarg;
			break;
		case 'x':
			match = MATCH_REGEX;
			break;
		case 'y':
			yes = true;
			break;
		default:
			usage_install();
			return (EX_USAGE);
		}
	}
	argc -= optind;
	argv += optind;

	if (argc < 1) {
		usage_install();
		return (EX_USAGE);
	}

	if (dry_run)
		retcode = pkgdb_access(PKGDB_MODE_READ,
				       PKGDB_DB_LOCAL   |
				       PKGDB_DB_REPO);
	else
		retcode = pkgdb_access(PKGDB_MODE_READ  |
				       PKGDB_MODE_WRITE |
				       PKGDB_MODE_CREATE,
				       PKGDB_DB_LOCAL   |
				       PKGDB_DB_REPO);
	
	if (retcode == EPKG_ENOACCESS) {
		warnx("Insufficient privilege to install packages");
		return (EX_NOPERM);
	} else if (retcode != EPKG_OK)
		return (EX_IOERR);
	else
		retcode = EX_SOFTWARE;

	/* first update the remote repositories if needed */
	if (auto_update && (updcode = pkgcli_update(false)) != EPKG_OK)
		return (updcode);

	if (pkgdb_open(&db, PKGDB_REMOTE) != EPKG_OK)
		return (EX_IOERR);

	if (pkg_jobs_new(&jobs, PKG_JOBS_INSTALL, db) != EPKG_OK)
		goto cleanup;

	if (reponame != NULL && pkg_jobs_set_repository(jobs, reponame) != EPKG_OK)
		goto cleanup;

	pkg_jobs_set_flags(jobs, f);

	if (pkg_jobs_add(jobs, match, argv, argc) == EPKG_FATAL)
		goto cleanup;

	if (pkg_jobs_solve(jobs) != EPKG_OK)
		goto cleanup;

	if ((nbactions = pkg_jobs_count(jobs)) > 0) {
		/* print a summary before applying the jobs */
		if (!quiet || dry_run) {
			print_jobs_summary(jobs,
			    "The following %d packages will be installed:\n\n",
			    nbactions);

			if (!yes && !dry_run)
				yes = query_yesno(
				    "\nProceed with installing packages [y/N]: ");
			if (dry_run)
				yes = false;
		}

		if (yes && pkg_jobs_apply(jobs) != EPKG_OK)
			goto cleanup;

		if (messages != NULL) {
			sbuf_finish(messages);
			printf("%s", sbuf_data(messages));
		}
	}

	retcode = EX_OK;

cleanup:
	pkg_jobs_free(jobs);
	pkgdb_close(db);

	return (retcode);
}
Esempio n. 8
0
int
exec_install(int argc, char **argv)
{
	struct pkgdb	*db = NULL;
	struct pkg_jobs	*jobs = NULL;
	const char	*reponame = NULL;
	int		 retcode;
	int		 updcode = EPKG_OK;
	int		 ch;
	int		 mode, repo_type;
	int		 done = 0;
	int		 lock_type = PKGDB_LOCK_ADVISORY;
	bool		 rc = true;
	bool		 local_only = false;
	match_t		 match = MATCH_EXACT;
	pkg_flags	 f = PKG_FLAG_NONE | PKG_FLAG_PKG_VERSION_TEST;

	struct option longopts[] = {
		{ "automatic",		no_argument,		NULL,	'A' },
		{ "case-sensitive",	no_argument,		NULL,	'C' },
		{ "force",		no_argument,		NULL,	'f' },
		{ "fetch-only",		no_argument,		NULL,	'F' },
		{ "glob",		no_argument,		NULL,	'g' },
		{ "case-insensitive",	no_argument,		NULL,	'i' },
		{ "no-install-scripts",	no_argument,		NULL,	'I' },
		{ "local-only",		no_argument,		NULL,	'l' },
		{ "ignore-missing",	no_argument,		NULL,	'M' },
		{ "dry-run",		no_argument,		NULL,	'n' },
		{ "quiet",		no_argument,		NULL,	'q' },
		{ "repository",		required_argument,	NULL,	'r' },
		{ "recursive",		no_argument,		NULL,   'R' },
		{ "no-repo-update",	no_argument,		NULL,	'U' },
		{ "regex",		no_argument,		NULL,	'x' },
		{ "yes",		no_argument,		NULL,	'y' },
		{ NULL,			0,			NULL,	0   },
	};

	nbactions = nbdone = 0;

	if (strcmp(argv[0], "add") == 0) {
		auto_update = false;
		local_only = true;
		yes = true;
		quiet = true;
	}

	while ((ch = getopt_long(argc, argv, "+ACfFgiIlMnqr:RUxy", longopts, NULL)) != -1) {
		switch (ch) {
		case 'A':
			f |= PKG_FLAG_AUTOMATIC;
			break;
		case 'C':
			pkgdb_set_case_sensitivity(true);
			break;
		case 'f':
			f |= PKG_FLAG_FORCE;
			break;
		case 'F':
			f |= PKG_FLAG_SKIP_INSTALL;
			lock_type = PKGDB_LOCK_READONLY;
			break;
		case 'g':
			match = MATCH_GLOB;
			break;
		case 'i':
			pkgdb_set_case_sensitivity(false);
			break;
		case 'I':
			f |= PKG_FLAG_NOSCRIPT;
			break;
		case 'l':
			local_only = true;
			auto_update = false;
			break;
		case 'M':
			f |= PKG_FLAG_FORCE_MISSING;
			break;
		case 'n':
			f |= PKG_FLAG_DRY_RUN;
			lock_type = PKGDB_LOCK_READONLY;
			dry_run = true;
			break;
		case 'q':
			quiet = true;
			break;
		case 'r':
			reponame = optarg;
			break;
		case 'R':
			f |= PKG_FLAG_RECURSIVE;
			break;
		case 'U':
			auto_update = false;
			break;
		case 'x':
			match = MATCH_REGEX;
			break;
		case 'y':
			yes = true;
			break;
		default:
			usage_install();
			return (EX_USAGE);
		}
	}
	argc -= optind;
	argv += optind;

	if (argc < 1) {
		usage_install();
		return (EX_USAGE);
	}

	if (dry_run && !auto_update)
		mode = PKGDB_MODE_READ;
	else
		mode =	PKGDB_MODE_READ  |
				PKGDB_MODE_WRITE |
				PKGDB_MODE_CREATE;
	if (local_only)
		repo_type = PKGDB_DB_LOCAL;
	else
		repo_type = PKGDB_DB_LOCAL|PKGDB_DB_REPO;

	retcode = pkgdb_access(mode, repo_type);

	if (retcode == EPKG_ENOACCESS && dry_run) {
		auto_update = false;
		retcode = pkgdb_access(PKGDB_MODE_READ,
				       repo_type);
	}

	if (retcode == EPKG_ENOACCESS) {
		warnx("Insufficient privileges to install packages");
		return (EX_NOPERM);
	} else if (retcode != EPKG_OK)
		return (EX_IOERR);
	else
		retcode = EX_SOFTWARE;

	/* first update the remote repositories if needed */
	if (auto_update && pkg_repos_total_count() > 0 &&
	    (updcode = pkgcli_update(false, false, reponame)) != EPKG_OK)
		return (updcode);

	if (pkgdb_open_all(&db,
	    local_only ? PKGDB_DEFAULT : PKGDB_MAYBE_REMOTE,
	    reponame) != EPKG_OK)
		return (EX_IOERR);

	if (pkgdb_obtain_lock(db, lock_type) != EPKG_OK) {
		pkgdb_close(db);
		warnx("Cannot get an advisory lock on a database, it is locked by another process");
		return (EX_TEMPFAIL);
	}

	if (pkg_jobs_new(&jobs, PKG_JOBS_INSTALL, db) != EPKG_OK)
		goto cleanup;

	if (!local_only && reponame != NULL &&
			pkg_jobs_set_repository(jobs, reponame) != EPKG_OK)
		goto cleanup;

	pkg_jobs_set_flags(jobs, f);

	if (pkg_jobs_add(jobs, match, argv, argc) == EPKG_FATAL)
		goto cleanup;

	if (pkg_jobs_solve(jobs) != EPKG_OK)
		goto cleanup;

	while ((nbactions = pkg_jobs_count(jobs)) > 0) {
		rc = yes;
		/* print a summary before applying the jobs */
		if (!quiet || dry_run) {
			print_jobs_summary(jobs,
			    "The following %d package(s) will be affected (of %d checked):\n\n",
			    nbactions, pkg_jobs_total(jobs));

			if (!dry_run) {
				rc = query_yesno(false,
				    "\nProceed with this action? ");
			} else {
				rc = false;
			}
		}

		if (rc) {
			retcode = pkg_jobs_apply(jobs);
			done = 1;
			if (retcode == EPKG_CONFLICT) {
				printf("Conflicts with the existing packages "
				    "have been found.\nOne more solver "
				    "iteration is needed to resolve them.\n");
				continue;
			}
			else if (retcode != EPKG_OK)
				goto cleanup;
		} else {
		}

		if (messages != NULL) {
			printf("%s", utstring_body(messages));
		}
		break;
	}

	if (done == 0 && rc)
		printf("The most recent versions of packages are already installed\n");

	if (rc)
		retcode = EX_OK;
	else
		retcode = EXIT_FAILURE;

cleanup:
	pkgdb_release_lock(db, lock_type);
	pkg_jobs_free(jobs);
	pkgdb_close(db);

	if (!dry_run)
		pkg_cache_full_clean();

	if (!rc && newpkgversion)
		newpkgversion = false;

	return (retcode);
}
Esempio n. 9
0
File: query.c Progetto: gelraen/pkg
int
exec_query(int argc, char **argv)
{
	struct pkgdb		*db = NULL;
	struct pkgdb_it		*it = NULL;
	struct pkg		*pkg = NULL;
	struct pkg_manifest_key	*keys = NULL;
	char			*pkgname = NULL;
	int			 query_flags = PKG_LOAD_BASIC;
	match_t			 match = MATCH_EXACT;
	int			 ch;
	int			 ret;
	int			 retcode = EX_OK;
	int			 i;
	char			 multiline = 0;
	char			*condition = NULL;
	struct sbuf		*sqlcond = NULL;
	const unsigned int	 q_flags_len = NELEM(accepted_query_flags);

	struct option longopts[] = {
		{ "all",		no_argument,		NULL,	'a' },
		{ "case-sensitive",	no_argument,		NULL,	'C' },
		{ "evaluate",		required_argument,	NULL,	'e' },
		{ "file",		required_argument,	NULL,	'F' },
		{ "glob",		no_argument,		NULL,	'g' },
		{ "case-insensitive",	no_argument,		NULL,	'i' },
		{ "regex",		no_argument,		NULL,	'x' },
		{ NULL,			0,			NULL,	0   },
	};

	while ((ch = getopt_long(argc, argv, "+aCe:F:gix", longopts, NULL)) != -1) {
		switch (ch) {
		case 'a':
			match = MATCH_ALL;
			break;
		case 'C':
			pkgdb_set_case_sensitivity(true);
			break;
		case 'e':
			match = MATCH_CONDITION;
			condition = optarg;
			break;
		case 'F':
			pkgname = optarg;
			break;
		case 'g':
			match = MATCH_GLOB;
			break;
		case 'i':
			pkgdb_set_case_sensitivity(false);
			break;
		case 'x':
			match = MATCH_REGEX;
			break;
		default:
			usage_query();
			return (EX_USAGE);
		}
	}

	argc -= optind;
	argv += optind;

	if (argc == 0) {
		usage_query();
		return (EX_USAGE);
	}

	/* Default to all packages if no pkg provided */
	if (argc == 1 && pkgname == NULL && condition == NULL && match == MATCH_EXACT) {
		match = MATCH_ALL;
	} else if (((argc == 1) ^ (match == MATCH_ALL)) && pkgname == NULL
			&& condition == NULL) {
		usage_query();
		return (EX_USAGE);
	}

	if (analyse_query_string(argv[0], accepted_query_flags, q_flags_len,
			&query_flags, &multiline) != EPKG_OK)
		return (EX_USAGE);

	if (pkgname != NULL) {
		pkg_manifest_keys_new(&keys);
		if (pkg_open(&pkg, pkgname, keys, 0) != EPKG_OK) {
			return (EX_IOERR);
		}

		pkg_manifest_keys_free(keys);
		print_query(pkg, argv[0], multiline);
		pkg_free(pkg);
		return (EX_OK);
	}

	if (condition != NULL) {
		sqlcond = sbuf_new_auto();
		if (format_sql_condition(condition, sqlcond, false) != EPKG_OK) {
			sbuf_delete(sqlcond);
			return (EX_USAGE);
		}
		sbuf_finish(sqlcond);
	}

	ret = pkgdb_access(PKGDB_MODE_READ, PKGDB_DB_LOCAL);
	if (ret == EPKG_ENOACCESS) {
		warnx("Insufficient privileges to query the package database");
		return (EX_NOPERM);
	} else if (ret == EPKG_ENODB) {
		if (!quiet)
			warnx("No packages installed");
		return (EX_OK);
	} else if (ret != EPKG_OK)
		return (EX_IOERR);

	ret = pkgdb_open(&db, PKGDB_DEFAULT);
	if (ret != EPKG_OK)
		return (EX_IOERR);

	if (pkgdb_obtain_lock(db, PKGDB_LOCK_READONLY) != EPKG_OK) {
		pkgdb_close(db);
		warnx("Cannot get a read lock on a database, it is locked by another process");
		return (EX_TEMPFAIL);
	}

	if (match == MATCH_ALL || match == MATCH_CONDITION) {
		const char *condition_sql = NULL;
		if (match == MATCH_CONDITION && sqlcond)
			condition_sql = sbuf_data(sqlcond);
		if ((it = pkgdb_query(db, condition_sql, match)) == NULL)
			return (EX_IOERR);

		while ((ret = pkgdb_it_next(it, &pkg, query_flags)) == EPKG_OK)
			print_query(pkg, argv[0],  multiline);

		if (ret != EPKG_END)
			retcode = EX_SOFTWARE;

		pkgdb_it_free(it);
	} else {
		int nprinted = 0;
		for (i = 1; i < argc; i++) {
			pkgname = argv[i];

			if ((it = pkgdb_query(db, pkgname, match)) == NULL) {
				retcode = EX_IOERR;
				goto cleanup;
			}

			while ((ret = pkgdb_it_next(it, &pkg, query_flags)) == EPKG_OK) {
				nprinted++;
				print_query(pkg, argv[0], multiline);
			}

			if (ret != EPKG_END) {
				retcode = EX_SOFTWARE;
				break;
			}

			pkgdb_it_free(it);
		}
		if (nprinted == 0 && retcode == EX_OK) {
			/* ensure to return a non-zero status when no package
			 were found. */
			retcode = EX_UNAVAILABLE;
		}
	}

cleanup:
	pkg_free(pkg);

	pkgdb_release_lock(db, PKGDB_LOCK_READONLY);
	pkgdb_close(db);

	return (retcode);
}
Esempio n. 10
0
int
exec_delete(int argc, char **argv)
{
	struct pkg_jobs	*jobs = NULL;
	struct pkgdb	*db = NULL;
	match_t		 match = MATCH_EXACT;
	pkg_flags	 f = PKG_FLAG_NONE;
	bool		 recursive_flag = false, rc = false;
	int		 retcode = EX_SOFTWARE;
	int		 ch;
	int		 i;
	int		 lock_type = PKGDB_LOCK_ADVISORY;

	struct option longopts[] = {
		{ "all",			no_argument,	NULL,	'a' },
		{ "case-sensitive",		no_argument,	NULL,	'C' },
		{ "no-deinstall-script",	no_argument,	NULL,	'D' },
		{ "force",			no_argument,	NULL,	'f' },
		{ "glob",			no_argument,	NULL,	'g' },
		{ "case-insensitive",		no_argument,	NULL,	'i' },
		{ "dry-run",			no_argument,	NULL,	'n' },
		{ "quiet",			no_argument,	NULL,	'q' },
		{ "recursive",			no_argument,	NULL,	'R' },
		{ "regex",			no_argument,	NULL,	'x' },
		{ "yes",			no_argument,	NULL,	'y' },
		{ NULL,				0,		NULL,	0   },
	};

	nbactions = nbdone = 0;

	while ((ch = getopt_long(argc, argv, "+aCDfginqRxy", longopts, NULL)) != -1) {
		switch (ch) {
		case 'a':
			match = MATCH_ALL;
			break;
		case 'C':
			pkgdb_set_case_sensitivity(true);
			break;
		case 'D':
			f |= PKG_FLAG_NOSCRIPT;
			break;
		case 'f':
			f |= PKG_FLAG_FORCE;
			force = true;
			break;
		case 'g':
			match = MATCH_GLOB;
			break;
		case 'i':
			pkgdb_set_case_sensitivity(false);
			break;
		case 'n':
			f |= PKG_FLAG_DRY_RUN;
			lock_type = PKGDB_LOCK_READONLY;
			dry_run = true;
			break;
		case 'q':
			quiet = true;
			break;
		case 'R':
			recursive_flag = true;
			break;
		case 'x':
			match = MATCH_REGEX;
			break;
		case 'y':
			yes = true;
			break;
		default:
			usage_delete();
			return (EX_USAGE);
		}
	}

	argc -= optind;
	argv += optind;

	if (argc < 1 && match != MATCH_ALL) {
		usage_delete();
		return (EX_USAGE);
	}

	if (dry_run)
		retcode = pkgdb_access(PKGDB_MODE_READ, PKGDB_DB_LOCAL);
	else
		retcode = pkgdb_access(PKGDB_MODE_READ|PKGDB_MODE_WRITE,
				       PKGDB_DB_LOCAL);

	if (retcode == EPKG_ENODB) {
		warnx("No packages installed.  Nothing to do!");
		return (EX_OK);
	} else if (retcode == EPKG_ENOACCESS) {
		warnx("Insufficient privileges to delete packages");
		return (EX_NOPERM);
	} else if (retcode != EPKG_OK) {
		warnx("Error accessing the package database");
		return (EX_SOFTWARE);
	}

	if (pkgdb_open(&db, PKGDB_DEFAULT) != EPKG_OK)
		return (EX_IOERR);

	if (pkgdb_obtain_lock(db, lock_type) != EPKG_OK) {
		pkgdb_close(db);
		warnx("Cannot get an advisory lock on a database, it is locked by another process");
		return (EX_TEMPFAIL);
	}


	if (pkg_jobs_new(&jobs, PKG_JOBS_DEINSTALL, db) != EPKG_OK) {
		pkgdb_close(db);
		return (EX_IOERR);
	}

	/*
	 * By default delete packages recursively.
	 * If force mode is enabled then we try to remove packages non-recursively.
	 * However, if -f and -R flags are both enabled then we return to
	 * recursive deletion.
	 */
	if (!force || recursive_flag)
		f |= PKG_FLAG_RECURSIVE;

	pkg_jobs_set_flags(jobs, f);

	if (match == MATCH_EXACT) {
		for (i = 0; i < argc; i++) {
			if (strchr(argv[i], '*') != NULL) {
				match = MATCH_GLOB;
				break;
			}
		}
	}

	if (pkg_jobs_add(jobs, match, argv, argc) == EPKG_FATAL)
		goto cleanup;

	if (pkg_jobs_solve(jobs) != EPKG_OK) {
		fprintf(stderr, "Cannot perform request\n");
		retcode = EX_NOPERM;
		goto cleanup;
	}

	/* check if we have something to deinstall */
	if ((nbactions = pkg_jobs_count(jobs)) == 0) {
		if (argc == 0) {
			if (!quiet)
				printf("Nothing to do.\n");
			retcode = EX_OK;
		} else {
			fprintf(stderr, "Package(s) not found!\n");
			retcode = EX_DATAERR;
		}
		goto cleanup;
	}

	if (!quiet || dry_run) {
		if (!quiet) {
			print_jobs_summary(jobs, NULL, NULL,
				"Deinstallation has been requested for the following %d packages "
				"(of %d packages in the universe):\n\n", nbactions,
				pkg_jobs_total(jobs));
		}
		if (dry_run) {
			retcode = EX_OK;
			goto cleanup;
		}
		rc = query_yesno(false,
		            "\nProceed with deinstalling packages? ");
	}
	else
		rc = yes;

	if (!rc || (retcode = pkg_jobs_apply(jobs)) != EPKG_OK)
		goto cleanup;

	if (messages != NULL) {
		sbuf_finish(messages);
		printf("%s", sbuf_data(messages));
	}
	pkgdb_compact(db);

	retcode = EX_OK;

cleanup:
	pkgdb_release_lock(db, lock_type);
	pkg_jobs_free(jobs);
	pkgdb_close(db);

	return (retcode);
}
Esempio n. 11
0
int
exec_register(int argc, char **argv)
{
	struct pkg	*pkg = NULL;
	struct pkgdb	*db  = NULL;

	struct pkg_manifest_key *keys = NULL;

	regex_t		 preg;
	regmatch_t	 pmatch[2];

	char		*arch = NULL;
	char		 myarch[BUFSIZ];
	char		*www  = NULL;
	char		 fpath[MAXPATHLEN + 1];

	const char	*plist      = NULL;
	const char	*mdir       = NULL;
	const char	*mfile      = NULL;
	const char	*input_path = NULL;
	const char	*desc       = NULL;

	size_t		 size;

	bool		 developer;
	bool		 legacy        = false;
	bool		 old           = false;
	bool		 __unused metadata_only = false;
	bool		 testing_mode  = false;

	int		 ch;
	int		 i;
	int		 ret     = EPKG_OK;
	int		 retcode = EX_OK;

	pkg_config_bool(PKG_CONFIG_DEVELOPER_MODE, &developer);

	if (pkg_new(&pkg, PKG_INSTALLED) != EPKG_OK)
		err(EX_OSERR, "malloc");
	while ((ch = getopt(argc, argv, "df:i:lM:m:Ot")) != -1) {
		switch (ch) {
		case 'd':
			pkg_set(pkg, PKG_AUTOMATIC, (int64_t)true);
			break;
		case 'f':
			plist = optarg;
			break;
		case 'i':
			input_path = optarg;
			break;
		case 'l':
			legacy = true;
			break;
		case 'M':
			metadata_only = true;
			mfile = optarg;
			break;
		case 'm':
			mdir = optarg;
			break;
		case 'O':
			old = true;
			break;
		case 't':
			testing_mode = true;
			break;
		default:
			warnx("Unrecognised option -%c\n", ch);
			usage_register();
			return (EX_USAGE);
		}
	}

	if (!old) {
		retcode = pkgdb_access(PKGDB_MODE_READ  |
				       PKGDB_MODE_WRITE |
				       PKGDB_MODE_CREATE,
				       PKGDB_DB_LOCAL);
		if (retcode == EPKG_ENOACCESS) {
			warnx("Insufficient privilege to register packages");
			return (EX_NOPERM);
		} else if (retcode != EPKG_OK)
			return (EX_IOERR);
		else
			retcode = EX_OK;
	}

	/*
         * Ideally, the +MANIFEST should be all that is necessary,
	 * since it can contain all of the meta-data supplied by the
	 * other files mentioned below.  These are here for backwards
	 * compatibility with the way the ports tree works with
	 * pkg_tools.
	 * 
	 * The -M option specifies one manifest file to read the
	 * meta-data from, and overrides the use of legacy meta-data
	 * inputs.
	 *
	 * Dependencies, shlibs, files etc. may be derived by
	 * analysing the package files (maybe discovered as the
	 * content of the staging directory) unless -t (testing_mode)
	 * is used.
	 */

	if (mfile != NULL && mdir != NULL) {
		warnx("Cannot use both -m and -M together");
		usage_register();
		return (EX_USAGE);
	}


	if (mfile == NULL && mdir == NULL) {
		warnx("one of either -m or -M flags is required");
		usage_register();
		return (EX_USAGE);
	}

	if (mfile != NULL && plist != NULL) {
		warnx("-M incompatible with -f option");
		usage_register();
		return (EX_USAGE);
	}

	if (testing_mode && input_path != NULL) {
		warnx("-i incompatible with -t option");
		usage_register();
		return (EX_USAGE);
	}

	pkg_manifest_keys_new(&keys);

	if (mfile != NULL) {
		ret = pkg_load_manifest_file(pkg, mfile, keys);
		pkg_manifest_keys_free(keys);
		if (ret != EPKG_OK) 
			return (EX_IOERR);

	} else {
		snprintf(fpath, sizeof(fpath), "%s/+MANIFEST", mdir);
		ret = pkg_load_manifest_file(pkg, fpath, keys);
		pkg_manifest_keys_free(keys);
		if (ret != EPKG_OK)
			return (EX_IOERR);


		snprintf(fpath, sizeof(fpath), "%s/+DESC", mdir);
		pkg_set_from_file(pkg, PKG_DESC, fpath, false);

		snprintf(fpath, sizeof(fpath), "%s/+DISPLAY", mdir);
		if (access(fpath, F_OK) == 0)
			pkg_set_from_file(pkg, PKG_MESSAGE, fpath, false);

		snprintf(fpath, sizeof(fpath), "%s/+MTREE_DIRS", mdir);
		if (access(fpath, F_OK) == 0)
			pkg_set_from_file(pkg, PKG_MTREE, fpath, false);

		for (i = 0; scripts[i] != NULL; i++) {
			snprintf(fpath, sizeof(fpath), "%s/%s", mdir,
			    scripts[i]);
			if (access(fpath, F_OK) == 0)
				pkg_addscript_file(pkg, fpath);
		}

		if (www != NULL) {
			pkg_set(pkg, PKG_WWW, www);
			free(www);
		}

		pkg_get(pkg, PKG_WWW, &www);

		/* 
		 * if www is not given then try to determine it from
		 * description
		 */

		if (www == NULL) {
			pkg_get(pkg, PKG_DESC, &desc);
			regcomp(&preg, "^WWW:[[:space:]]*(.*)$",
			    REG_EXTENDED|REG_ICASE|REG_NEWLINE);
			if (regexec(&preg, desc, 2, pmatch, 0) == 0) {
				size = pmatch[1].rm_eo - pmatch[1].rm_so;
				www = strndup(&desc[pmatch[1].rm_so], size);
				pkg_set(pkg, PKG_WWW, www);
				free(www);
			} else {
				pkg_set(pkg, PKG_WWW, "UNKNOWN");
			}
			regfree(&preg);
		}

		if (plist != NULL)
			ret += ports_parse_plist(pkg, plist, input_path);
	}

	if (ret != EPKG_OK) {
		return (EX_IOERR);
	}


	if (!old && pkgdb_open(&db, PKGDB_DEFAULT) != EPKG_OK) {
		return (EX_IOERR);
	}

	/*
         * testing_mode allows updating the local package database
	 * without any check that the files etc. listed in the meta
	 * data actually exist on the system.  Inappropriate use of
	 * testing_mode can really screw things up.
	 */

	if (!testing_mode)
		pkg_analyse_files(db, pkg);

	pkg_get(pkg, PKG_ARCH, &arch);
	if (arch == NULL) {
		/*
		 * do not take the one from configuration on purpose
		 * but the real abi of the package.
		 */
		pkg_get_myarch(myarch, BUFSIZ);
		if (developer)
			pkg_suggest_arch(pkg, myarch, true);
		pkg_set(pkg, PKG_ARCH, myarch);
	} else {
		if (developer)
			pkg_suggest_arch(pkg, arch, false);
	}

	if (!testing_mode && input_path != NULL)
		pkg_copy_tree(pkg, input_path, "/");

	if (old) {
		if (pkg_register_old(pkg) != EPKG_OK)
			retcode = EX_SOFTWARE;
	} else {
		if (pkgdb_register_ports(db, pkg) != EPKG_OK)
			retcode = EX_SOFTWARE;
	}

	if (!legacy && pkg_has_message(pkg))
		pkg_printf("%M\n", pkg);

	if (!old)
		pkgdb_close(db);

	pkg_free(pkg);

	return (retcode);
}
Esempio n. 12
0
File: audit.c Progetto: grembo/pkg
int
exec_audit(int argc, char **argv)
{
	struct pkg_audit	*audit;
	struct pkgdb		*db = NULL;
	struct pkgdb_it		*it = NULL;
	struct pkg		*pkg = NULL;
	const char		*db_dir;
	char			*name;
	char			*version;
	char			 audit_file_buf[MAXPATHLEN];
	char			*audit_file = audit_file_buf;
	unsigned int		 vuln = 0;
	bool			 fetch = false, recursive = false;
	int			 ch, i;
	int			 ret = EX_OK;
	const char		*portaudit_site = NULL;
	struct sbuf		*sb;
	kh_pkgs_t		*check = NULL;

	db_dir = pkg_object_string(pkg_config_get("PKG_DBDIR"));
	snprintf(audit_file_buf, sizeof(audit_file_buf), "%s/vuln.xml", db_dir);

	struct option longopts[] = {
		{ "fetch",	no_argument,		NULL,	'F' },
		{ "file",	required_argument,	NULL,	'f' },
		{ "recursive",	no_argument,	NULL,	'r' },
		{ "quiet",	no_argument,		NULL,	'q' },
		{ NULL,		0,			NULL,	0   },
	};

	while ((ch = getopt_long(argc, argv, "+Ff:qr", longopts, NULL)) != -1) {
		switch (ch) {
		case 'F':
			fetch = true;
			break;
		case 'f':
			audit_file = optarg;
			break;
		case 'q':
			quiet = true;
			break;
		case 'r':
			recursive = true;
			break;
		default:
			usage_audit();
			return(EX_USAGE);
		}
	}
	argc -= optind;
	argv += optind;

	audit = pkg_audit_new();

	if (fetch == true) {
		portaudit_site = pkg_object_string(pkg_config_get("VULNXML_SITE"));
		if (pkg_audit_fetch(portaudit_site, audit_file) != EPKG_OK) {
			pkg_audit_free(audit);
			return (EX_IOERR);
		}
	}

	if (pkg_audit_load(audit, audit_file) != EPKG_OK) {
		if (errno == ENOENT)
			warnx("vulnxml file %s does not exist. "
					"Try running 'pkg audit -F' first",
					audit_file);
		else
			warn("unable to open vulnxml file %s",
					audit_file);

		pkg_audit_free(audit);
		return (EX_DATAERR);
	}

	check = kh_init_pkgs();
	if (argc >= 1) {
		for (i = 0; i < argc; i ++) {
			name = argv[i];
			version = strrchr(name, '-');
			if (version != NULL) {
				version[0] = '\0';
				version++;
			}
			if (pkg_new(&pkg, PKG_FILE) != EPKG_OK)
				err(EX_OSERR, "malloc");
			if (version != NULL)
				pkg_set(pkg, PKG_NAME, name, PKG_VERSION, version);
			else
				pkg_set(pkg, PKG_NAME, name);
			/* Fake uniqueid */
			pkg_set(pkg, PKG_UNIQUEID, name);
			add_to_check(check, pkg);
			pkg = NULL;
		}
	}
	else {

		/*
		 * if the database doesn't exist it just means there are no
		 * packages to audit.
		 */

		ret = pkgdb_access(PKGDB_MODE_READ, PKGDB_DB_LOCAL);
		if (ret == EPKG_ENODB) {
			pkg_audit_free(audit);
			kh_destroy_pkgs(check);
			return (EX_OK);
		} else if (ret == EPKG_ENOACCESS) {
			warnx("Insufficient privileges to read the package database");
			pkg_audit_free(audit);
			kh_destroy_pkgs(check);
			return (EX_NOPERM);
		} else if (ret != EPKG_OK) {
			warnx("Error accessing the package database");
			pkg_audit_free(audit);
			kh_destroy_pkgs(check);
			return (EX_IOERR);
		}

		if (pkgdb_open(&db, PKGDB_DEFAULT) != EPKG_OK) {
			pkg_audit_free(audit);
			kh_destroy_pkgs(check);
			return (EX_IOERR);
		}

		if (pkgdb_obtain_lock(db, PKGDB_LOCK_READONLY) != EPKG_OK) {
			pkgdb_close(db);
			pkg_audit_free(audit);
			kh_destroy_pkgs(check);
			warnx("Cannot get a read lock on a database, it is locked by another process");
			return (EX_TEMPFAIL);
		}

		if ((it = pkgdb_query(db, NULL, MATCH_ALL)) == NULL) {
			warnx("Error accessing the package database");
			ret = EX_IOERR;
		}
		else {
			while ((ret = pkgdb_it_next(it, &pkg, PKG_LOAD_BASIC|PKG_LOAD_RDEPS))
							== EPKG_OK) {
				add_to_check(check, pkg);
				pkg = NULL;
			}
			ret = EX_OK;
		}
		if (db != NULL) {
			pkgdb_it_free(it);
			pkgdb_release_lock(db, PKGDB_LOCK_READONLY);
			pkgdb_close(db);
		}
		if (ret != EX_OK) {
			pkg_audit_free(audit);
			kh_destroy_pkgs(check);
			return (ret);
		}
	}

	/* Now we have vulnxml loaded and check list formed */
#ifdef HAVE_CAPSICUM
	if (cap_enter() < 0 && errno != ENOSYS) {
		warn("cap_enter() failed");
		pkg_audit_free(audit);
		kh_destroy_pkgs(check);
		return (EPKG_FATAL);
	}
#endif

	if (pkg_audit_process(audit) == EPKG_OK) {
		kh_foreach_value(check, pkg, {
			if (pkg_audit_is_vulnerable(audit, pkg, quiet, &sb)) {
				vuln ++;
				printf("%s", sbuf_data(sb));

				if (recursive) {
					const char *name;
					kh_pkgs_t *seen = kh_init_pkgs();

					pkg_get(pkg, PKG_NAME, &name);
					sbuf_clear(sb);
					sbuf_printf(sb, "Packages that depend on %s: ", name);
					print_recursive_rdeps(check, pkg , sb, seen, true);
					sbuf_finish(sb);
					printf("%s\n\n", sbuf_data(sb));

					kh_destroy_pkgs(seen);
				}
				sbuf_delete(sb);
			}
			pkg_free(pkg);
		});
Esempio n. 13
0
File: clean.c Progetto: grembo/pkg
int
exec_clean(int argc, char **argv)
{
	struct pkgdb	*db = NULL;
	kh_sum_t	*sumlist = NULL;
	dl_list		 dl;
	const char	*cachedir;
	bool		 all = false;
	int		 retcode;
	int		 ch;
	int		 cachefd = -1;
	size_t		 total = 0;
	char		 size[8];
	char		*cksum;
	struct pkg_manifest_key *keys = NULL;
#ifdef HAVE_CAPSICUM
	cap_rights_t rights;
#endif

	struct option longopts[] = {
		{ "all",	no_argument,	NULL,	'a' },
		{ "dry-run",	no_argument,	NULL,	'n' },
		{ "quiet",	no_argument,	NULL,	'q' },
		{ "yes",	no_argument,	NULL,	'y' },
		{ NULL,		0,		NULL,	0   },
	};

	while ((ch = getopt_long(argc, argv, "+anqy", longopts, NULL)) != -1) {
		switch (ch) {
		case 'a':
			all = true;
			break;
		case 'n':
			dry_run = true;
			break;
		case 'q':
			quiet = true;
			break;
		case 'y':
			yes = true;
			break;
		default:
			usage_clean();
			return (EX_USAGE);
		}
	}
	argc -= optind;
	argv += optind;

	cachedir = pkg_object_string(pkg_config_get("PKG_CACHEDIR"));
	cachefd = open(cachedir, O_DIRECTORY);
	if (cachefd == -1) {
		warn("Impossible to open %s", cachedir);
		return (EX_IOERR);
	}

	retcode = pkgdb_access(PKGDB_MODE_READ, PKGDB_DB_REPO);

	if (retcode == EPKG_ENOACCESS) {
		warnx("Insufficient privileges to clean old packages");
		close(cachefd);
		return (EX_NOPERM);
	} else if (retcode == EPKG_ENODB) {
		warnx("No package database installed.  Nothing to do!");
		close(cachefd);
		return (EX_OK);
	} else if (retcode != EPKG_OK) {
		warnx("Error accessing the package database");
		close(cachefd);
		return (EX_SOFTWARE);
	}

	retcode = EX_SOFTWARE;

	if (pkgdb_open(&db, PKGDB_REMOTE) != EPKG_OK) {
		close(cachefd);
		return (EX_IOERR);
	}

	if (pkgdb_obtain_lock(db, PKGDB_LOCK_READONLY) != EPKG_OK) {
		pkgdb_close(db);
		close(cachefd);
		warnx("Cannot get a read lock on a database, it is locked by "
		    "another process");
		return (EX_TEMPFAIL);
	}

#ifdef HAVE_CAPSICUM
		cap_rights_init(&rights, CAP_READ, CAP_LOOKUP, CAP_FSTATFS,
		    CAP_FSTAT, CAP_UNLINKAT);
		if (cap_rights_limit(cachefd, &rights) < 0 && errno != ENOSYS ) {
			warn("cap_rights_limit() failed");
			close(cachefd);
			return (EX_SOFTWARE);
		}

		if (cap_enter() < 0 && errno != ENOSYS) {
			warn("cap_enter() failed");
			close(cachefd);
			return (EX_SOFTWARE);
		}
#endif

	kv_init(dl);

	/* Build the list of out-of-date or obsolete packages */

	pkg_manifest_keys_new(&keys);
	recursive_analysis(cachefd, db, cachedir, cachedir, &dl, &sumlist, all,
	    &total);
	if (sumlist != NULL) {
		kh_foreach_value(sumlist, cksum, free(cksum));
		kh_destroy_sum(sumlist);
	}

	if (kv_size(dl) == 0) {
		if (!quiet)
			printf("Nothing to do.\n");
		retcode = EX_OK;
		goto cleanup;
	}

	humanize_number(size, sizeof(size), total, "B",
	    HN_AUTOSCALE, HN_IEC_PREFIXES);

	if (!quiet)
		printf("The cleanup will free %s\n", size);
	if (!dry_run) {
			if (query_yesno(false,
			  "\nProceed with cleaning the cache? ")) {
				retcode = delete_dellist(cachefd, cachedir, &dl, kv_size(dl));
			}
	} else {
		retcode = EX_OK;
	}

cleanup:
	pkgdb_release_lock(db, PKGDB_LOCK_READONLY);
	pkgdb_close(db);
	pkg_manifest_keys_free(keys);
	free_dellist(&dl);

	if (cachefd != -1)
		close(cachefd);

	return (retcode);
}
Esempio n. 14
0
int
exec_upgrade(int argc, char **argv)
{
	struct pkgdb	*db = NULL;
	struct pkg_jobs	*jobs = NULL;
	const char	*reponame = NULL;
	int		 retcode;
	int		 updcode;
	int		 ch;
	int		 lock_type = PKGDB_LOCK_ADVISORY;
	match_t		 match = MATCH_EXACT;
	int		 done = 0;
	bool	rc = true;
	pkg_flags	 f = PKG_FLAG_NONE | PKG_FLAG_PKG_VERSION_TEST;
	size_t dlbytes, diffbytes, limbytes;

	limbytes = pkg_object_int(pkg_config_get("WARN_SIZE_LIMIT"));

	struct option longopts[] = {
		{ "case-sensitive",	no_argument,		NULL,	'C' },
		{ "force",		no_argument,		NULL,	'f' },
		{ "fetch-only",		no_argument,		NULL,	'F' },
		{ "glob",		no_argument,		NULL,	'g' },
		{ "case-insensitive",	no_argument,		NULL,	'i' },
		{ "no-install-scripts",	no_argument,		NULL,	'I' },
		{ "dry-run",		no_argument,		NULL,	'n' },
		{ "quiet",		no_argument,		NULL,	'q' },
		{ "repository",		required_argument,	NULL,	'r' },
		{ "no-repo-update",	no_argument,		NULL,	'U' },
		{ "regex",		no_argument,		NULL,	'x' },
		{ "yes",		no_argument,		NULL,	'y' },
		{ NULL,			0,			NULL,	0   },
	};

	nbactions = nbdone = 0;

	while ((ch = getopt_long(argc, argv, "+CfFgiInqr:Uxy", longopts, NULL)) != -1) {
		switch (ch) {
		case 'C':
			pkgdb_set_case_sensitivity(true);
			break;
		case 'f':
			f |= PKG_FLAG_FORCE;
			break;
		case 'F':
			f |= PKG_FLAG_SKIP_INSTALL;
			lock_type = PKGDB_LOCK_READONLY;
			break;
		case 'g':
			match = MATCH_GLOB;
			break;
		case 'i':
			pkgdb_set_case_sensitivity(false);
			break;
		case 'I':
			f |= PKG_FLAG_NOSCRIPT;
			break;
		case 'n':
			f |= PKG_FLAG_DRY_RUN;
			lock_type = PKGDB_LOCK_READONLY;
			dry_run = true;
			break;
		case 'q':
			quiet = true;
			break;
		case 'r':
			reponame = optarg;
			break;
		case 'U':
			auto_update = false;
			break;
		case 'x':
			match = MATCH_REGEX;
			break;
		case 'y':
			yes = true;
			break;
		default:
			usage_upgrade();
			return (EX_USAGE);
			/* NOTREACHED */
		}
	}
	argc -= optind;
	argv += optind;

	if (dry_run && !auto_update)
		retcode = pkgdb_access(PKGDB_MODE_READ,
				       PKGDB_DB_LOCAL|PKGDB_DB_REPO);
	else
		retcode = pkgdb_access(PKGDB_MODE_READ  |
				       PKGDB_MODE_WRITE |
				       PKGDB_MODE_CREATE,
				       PKGDB_DB_LOCAL|PKGDB_DB_REPO);
	if (retcode == EPKG_ENOACCESS && dry_run) {
		auto_update = false;
		retcode = pkgdb_access(PKGDB_MODE_READ,
				       PKGDB_DB_LOCAL|PKGDB_DB_REPO);
	}

	if (retcode == EPKG_ENOACCESS) {
		warnx("Insufficient privilege to upgrade packages");
		return (EX_NOPERM);
	} else if (retcode != EPKG_OK)
		return (EX_IOERR);
	else
		retcode = EX_SOFTWARE;

	/* first update the remote repositories if needed */
	if (auto_update &&
	    (updcode = pkgcli_update(false, false, reponame)) != EPKG_OK)
		return (updcode);

	if (pkgdb_open_all(&db, PKGDB_REMOTE, reponame) != EPKG_OK)
		return (EX_IOERR);

	if (pkgdb_obtain_lock(db, lock_type) != EPKG_OK) {
		pkgdb_close(db);
		warnx("Cannot get an advisory lock on a database, it is locked by another process");
		return (EX_TEMPFAIL);
	}

	if (pkg_jobs_new(&jobs, PKG_JOBS_UPGRADE, db) != EPKG_OK)
		goto cleanup;

	if (reponame != NULL && pkg_jobs_set_repository(jobs, reponame) != EPKG_OK)
		goto cleanup;

	pkg_jobs_set_flags(jobs, f);

	if (argc > 0)
		if (pkg_jobs_add(jobs, match, argv, argc) == EPKG_FATAL)
				goto cleanup;

	if (pkg_jobs_solve(jobs) != EPKG_OK)
		goto cleanup;

	while ((nbactions = pkg_jobs_count(jobs)) > 0) {
		/* print a summary before applying the jobs */
		rc = yes;
		if (!quiet || dry_run) {
			print_jobs_summary(jobs, &diffbytes, &dlbytes,
				"The following %d package(s) will be affected (of %d checked):\n\n",
				nbactions, pkg_jobs_total(jobs));

			if (!dry_run) {
				if (limbytes && (diffbytes > limbytes || dlbytes > limbytes)) {
					rc = query_yesno(false, "\nProceed with this "
							"action? ");
				}
				else {
					rc = true;
				}
			}
			else {
				rc = false;
			}
		}

		if (rc) {
			retcode = pkg_jobs_apply(jobs);
			done = 1;
			if (retcode == EPKG_CONFLICT) {
				printf("Conflicts with the existing packages "
				    "have been found.\nOne more solver "
				    "iteration is needed to resolve them.\n");
				continue;
			}
			else if (retcode != EPKG_OK)
				goto cleanup;
		}

		if (messages != NULL) {
			sbuf_finish(messages);
			printf("%s", sbuf_data(messages));
		}
		break;
	}

	if (done == 0 && rc && !quiet)
		printf("Your packages are up to date.\n");

	retcode = EX_OK;

cleanup:
	pkg_jobs_free(jobs);
	pkgdb_release_lock(db, lock_type);
	pkgdb_close(db);

	if (!dry_run)
		pkg_cache_full_clean();

	if (!rc && newpkgversion)
		newpkgversion = false;

	return (retcode);
}
Esempio n. 15
0
File: query.c Progetto: renchap/pkg
int
exec_query(int argc, char **argv)
{
	struct pkgdb *db = NULL;
	struct pkgdb_it *it = NULL;
	struct pkg *pkg = NULL;
	struct pkg_manifest_key *keys = NULL;
	char *pkgname = NULL;
	int query_flags = PKG_LOAD_BASIC;
	match_t match = MATCH_EXACT;
	int ch;
	int ret;
	int retcode = EX_OK;
	int i;
	char multiline = 0;
	char *condition = NULL;
	struct sbuf *sqlcond = NULL;
	const unsigned int q_flags_len = (sizeof(accepted_query_flags)/sizeof(accepted_query_flags[0]));

	while ((ch = getopt(argc, argv, "agixF:e:")) != -1) {
		switch (ch) {
		case 'a':
			match = MATCH_ALL;
			break;
		case 'g':
			match = MATCH_GLOB;
			break;
		case 'i':
			pkgdb_set_case_sensitivity(false);
			break;
		case 'x':
			match = MATCH_REGEX;
			break;
		case 'F':
			pkgname = optarg;
			break;
		case 'e':
			match = MATCH_CONDITION;
			condition = optarg;
			break;
		default:
			usage_query();
			return (EX_USAGE);
		}
	}

	argc -= optind;
	argv += optind;

	if (argc == 0) {
		usage_query();
		return (EX_USAGE);
	}

	/* Default to all packages if no pkg provided */
	if (argc == 1 && pkgname == NULL && condition == NULL && match == MATCH_EXACT) {
		match = MATCH_ALL;
	} else if ((argc == 1) ^ (match == MATCH_ALL) && pkgname == NULL && condition == NULL) {
		usage_query();
		return (EX_USAGE);
	}

	if (analyse_query_string(argv[0], accepted_query_flags, q_flags_len, &query_flags, &multiline) != EPKG_OK)
		return (EX_USAGE);

	if (pkgname != NULL) {
		pkg_manifest_keys_new(&keys);
		if (pkg_open(&pkg, pkgname, keys, 0) != EPKG_OK) {
			return (EX_IOERR);
		}

		pkg_manifest_keys_free(keys);
		print_query(pkg, argv[0], multiline);
		pkg_free(pkg);
		return (EX_OK);
	}

	if (condition != NULL) {
		sqlcond = sbuf_new_auto();
		if (format_sql_condition(condition, sqlcond, false) != EPKG_OK) {
			sbuf_delete(sqlcond);
			return (EX_USAGE);
		}
		sbuf_finish(sqlcond);
	}

	ret = pkgdb_access(PKGDB_MODE_READ, PKGDB_DB_LOCAL);
	if (ret == EPKG_ENOACCESS) {
		warnx("Insufficient privilege to query package database");
		return (EX_NOPERM);
	} else if (ret == EPKG_ENODB) {
		if (!quiet)
			warnx("No packages installed");
		return (EX_OK);
	} else if (ret != EPKG_OK)
		return (EX_IOERR);

	ret = pkgdb_open(&db, PKGDB_DEFAULT);
	if (ret != EPKG_OK)
		return (EX_IOERR);

	if (match == MATCH_ALL || match == MATCH_CONDITION) {
		const char *condition_sql = NULL;
		if (match == MATCH_CONDITION && sqlcond)
			condition_sql = sbuf_data(sqlcond);
		if ((it = pkgdb_query(db, condition_sql, match)) == NULL)
			return (EX_IOERR);

		while ((ret = pkgdb_it_next(it, &pkg, query_flags)) == EPKG_OK)
			print_query(pkg, argv[0],  multiline);

		if (ret != EPKG_END)
			retcode = EX_SOFTWARE;

		pkgdb_it_free(it);
	} else {
		int nprinted = 0;
		for (i = 1; i < argc; i++) {
			pkgname = argv[i];

			if ((it = pkgdb_query(db, pkgname, match)) == NULL)
				return (EX_IOERR);

			while ((ret = pkgdb_it_next(it, &pkg, query_flags)) == EPKG_OK) {
				nprinted++;
				print_query(pkg, argv[0], multiline);
			}

			if (ret != EPKG_END) {
				retcode = EX_SOFTWARE;
				break;
			}

			pkgdb_it_free(it);
		}
		if (nprinted == 0 && retcode == EX_OK) {
			/* ensure to return a non-zero status when no package
			 were found. */
			retcode = EX_UNAVAILABLE;
		}
	}

	pkg_free(pkg);
	pkgdb_close(db);

	return (retcode);
}
Esempio n. 16
0
File: info.c Progetto: rakhij/pkg
int
exec_info(int argc, char **argv)
{
    struct pkgdb *db = NULL;
    struct pkgdb_it *it = NULL;
    int query_flags;
    struct pkg *pkg = NULL;
    uint64_t opt = INFO_TAG_NAMEVER;
    match_t match = MATCH_GLOB;
    char *pkgname;
    char *pkgversion = NULL, *pkgversion2 = NULL;
    const char *file = NULL;
    int ch, fd;
    int ret = EPKG_OK;
    int retcode = 0;
    bool gotone = false;
    int i, j;
    int sign = 0;
    int sign2 = 0;
    int open_flags = 0;
    bool pkg_exists = false;
    bool origin_search = false;
    bool e_flag = false;
    struct pkg_manifest_key *keys = NULL;
#ifdef HAVE_CAPSICUM
    cap_rights_t rights;
#endif

    /* TODO: exclusive opts ? */
    while ((ch = getopt(argc, argv, "aADegixEIdrklbBsqopOfF:R")) != -1) {
        switch (ch) {
        case 'a':
            match = MATCH_ALL;
            break;
        case 'A':
            opt |= INFO_ANNOTATIONS;
            break;
        case 'O':
            origin_search = true;  /* only for ports compat */
            break;
        case 'e':
            pkg_exists = true;;
            retcode = 1;
            break;
        case 'g':
            match = MATCH_GLOB;
            break;
        case 'i':
            pkgdb_set_case_sensitivity(false);
            break;
        case 'x':
            match = MATCH_REGEX;
            break;
        case 'D':
            opt |= INFO_MESSAGE;
            break;
        case 'd':
            opt |= INFO_DEPS;
            break;
        case 'I':
            opt |= INFO_COMMENT;
            break;
        case 'r':
            opt |= INFO_RDEPS;
            break;
        case 'k':
            opt |= INFO_LOCKED;
            break;
        case 'l':
            opt |= INFO_FILES;
            break;
        case 'b':
            opt |= INFO_SHLIBS_PROVIDED;
            break;
        case 'B':
            opt |= INFO_SHLIBS_REQUIRED;
            break;
        case 's':
            opt |= INFO_FLATSIZE;
            break;
        case 'E': /* ports compatibility */
            e_flag = true;
            break;
        case 'q':
            quiet = true;
            break;
        case 'o':
            opt |= INFO_ORIGIN;
            break;
        case 'p':
            opt |= INFO_PREFIX;
            break;
        case 'f':
            opt |= INFO_FULL;
            break;
        case 'F':
            file = optarg;
            break;
        case 'R':
            opt |= INFO_RAW;
            break;
        default:
            usage_info();
            return(EX_USAGE);
        }
    }

    if (argc == 1 || (argc == 2 && quiet))
        match = MATCH_ALL;

    argc -= optind;
    argv += optind;

    if (argc == 0 && file == NULL && match != MATCH_ALL) {
        /* which -O bsd.*.mk always execpt clean output */
        if (origin_search)
            return (EX_OK);
        usage_info();
        return (EX_USAGE);
    }

    /* When no other data is requested, default is to print
     * 'name-ver comment' For -O, just print name-ver */
    if (!origin_search && (opt & INFO_ALL) == 0 && match == MATCH_ALL &&
            !quiet)
        opt |= INFO_COMMENT;

    /* Special compatibility: handle -O and -q -O */
    if (origin_search) {
        if (quiet) {
            opt = INFO_TAG_NAMEVER;
            quiet = false;
        } else {
            opt = INFO_TAG_NAMEVER|INFO_COMMENT;
        }
    }

    if (match == MATCH_ALL && opt == INFO_TAG_NAMEVER)
        quiet = false;

    if (file != NULL) {
        if ((fd = open(file, O_RDONLY)) == -1) {
            warn("Unable to open %s", file);
            return (EX_IOERR);
        }

#ifdef HAVE_CAPSICUM
        cap_rights_init(&rights, CAP_READ, CAP_FSTAT);
        if (cap_rights_limit(fd, &rights) < 0 && errno != ENOSYS ) {
            warn("cap_rights_limit() failed");
            return (EX_SOFTWARE);
        }

        if (cap_enter() < 0 && errno != ENOSYS) {
            warn("cap_enter() failed");
            return (EX_SOFTWARE);
        }
#endif
        if (opt == INFO_TAG_NAMEVER)
            opt |= INFO_FULL;
        pkg_manifest_keys_new(&keys);
        if ((opt & (INFO_RAW | INFO_FILES |
                    INFO_DIRS)) == 0)
            open_flags = PKG_OPEN_MANIFEST_COMPACT;

        if (pkg_open_fd(&pkg, fd, keys, open_flags) != EPKG_OK) {
            close(fd);
            return (1);
        }
        pkg_manifest_keys_free(keys);
        print_info(pkg, opt);
        close(fd);
        pkg_free(pkg);
        return (EX_OK);
    }

    ret = pkgdb_access(PKGDB_MODE_READ, PKGDB_DB_LOCAL);
    if (ret == EPKG_ENOACCESS) {
        warnx("Insufficient privileges to query the package database");
        return (EX_NOPERM);
    } else if (ret == EPKG_ENODB) {
        if (match == MATCH_ALL)
            return (EX_OK);
        if (origin_search)
            return (EX_OK);
        if (!quiet)
            warnx("No packages installed");
        return (EX_UNAVAILABLE);
    } else if (ret != EPKG_OK)
        return (EX_IOERR);

    ret = pkgdb_open(&db, PKGDB_DEFAULT);
    if (ret != EPKG_OK)
        return (EX_IOERR);

    if (pkgdb_obtain_lock(db, PKGDB_LOCK_READONLY, 0, 0) != EPKG_OK) {
        pkgdb_close(db);
        warnx("Cannot get a read lock on a database, it is locked by another process");
        return (EX_TEMPFAIL);
    }

    i = 0;
    do {
        gotone = false;
        pkgname = argv[i];

        /*
         * allow to search for origin with a trailing /
         * likes audio/linux-vsound depending on ${PORTSDIR}/audio/sox/
         */
        if (argc > 0 && pkgname[strlen(pkgname) -1] == '/')
            pkgname[strlen(pkgname) -1] = '\0';

        if (argc > 0) {
            j=0;
            while (pkgname[j] != '\0') {
                if (pkgname[j] == '<') {
                    if (pkgversion) {
                        pkgversion2 = pkgname + j;
                        sign2 = LT;
                        pkgversion2[0] = '\0';
                        pkgversion2++;
                        if (pkgversion2[0] == '=') {
                            pkgversion2++;
                            sign=LE;
                            j++;
                        }
                    } else {
                        pkgversion = pkgname + j;
                        sign = LT;
                        pkgversion[0] = '\0';
                        pkgversion++;
                        if (pkgversion[0] == '=') {
                            pkgversion++;
                            sign=LE;
                            j++;
                        }
                    }
                } else if (pkgname[j] == '>') {
                    if (pkgversion) {
                        pkgversion2 = pkgname + j;
                        sign2 = GT;
                        pkgversion2[0] = '\0';
                        pkgversion2++;
                        if (pkgversion2[0] == '=') {
                            pkgversion2++;
                            sign=GE;
                            j++;
                        }
                    } else {
                        pkgversion = pkgname + j;
                        sign = GT;
                        pkgversion[0] = '\0';
                        pkgversion++;
                        if (pkgversion[0] == '=') {
                            pkgversion++;
                            sign=GE;
                            j++;
                        }
                    }
                } else if (pkgname[j] == '=') {
                    if (pkgversion) {
                        pkgversion2 = pkgname + j;
                        sign2 = EQ;
                        pkgversion2[0] = '\0';
                        pkgversion2++;
                        if (pkgversion2[0] == '=') {
                            pkgversion2++;
                            sign=EQ;
                            j++;
                        }
                    } else {
                        pkgversion = pkgname + j;
                        sign = EQ;
                        pkgversion[0] = '\0';
                        pkgversion++;
                        if (pkgversion[0] == '=') {
                            pkgversion++;
                            sign=EQ;
                            j++;
                        }
                    }
                }
                j++;
            }
        }

        if (match != MATCH_ALL && pkgname[0] == '\0') {
            fprintf(stderr, "Pattern must not be empty.\n");
            i++;
            continue;
        }

        if ((it = pkgdb_query(db, pkgname, match)) == NULL) {
            goto cleanup;
        }

        /* this is place for compatibility hacks */

        /* ports infrastructure expects pkg info -q -O to always return 0 even
         * if the ports doesn't exists */
        if (origin_search)
            gotone = true;

        /* end of compatibility hacks */

        /*
         * only show full version in case of match glob with a single argument specified
         * which does not contains any glob pattern
         */
        if (argc == 1 && !origin_search && !quiet && !e_flag &&
                match == MATCH_GLOB &&
                strcspn(pkgname, "*[]{}()") == strlen(pkgname) &&
                opt == INFO_TAG_NAMEVER)
            opt |= INFO_FULL;

        query_flags = info_flags(opt, false);
        while ((ret = pkgdb_it_next(it, &pkg, query_flags)) == EPKG_OK) {
            gotone = true;
            const char *version;

            pkg_get(pkg, PKG_VERSION, &version);
            if (pkgversion != NULL) {
                switch (pkg_version_cmp(version, pkgversion)) {
                case -1:
                    if (sign != LT && sign != LE) {
                        gotone = false;
                        continue;
                    }
                    break;
                case 0:
                    if (sign != LE &&
                            sign != GE &&
                            sign != EQ) {
                        gotone = false;
                        continue;
                    }
                    break;
                case 1:
                    if (sign != GT && sign != GE) {
                        gotone = false;
                        continue;
                    }
                    break;
                }
            }
            if (pkgversion2 != NULL) {
                switch (pkg_version_cmp(version, pkgversion2)) {
                case -1:
                    if (sign2 != LT && sign2 != LE) {
                        gotone = false;
                        continue;
                    }
                    break;
                case 0:
                    if (sign2 != LE &&
                            sign2 != GE &&
                            sign2 != EQ) {
                        gotone = false;
                        continue;
                    }
                    break;
                case 1:
                    if (sign2 != GT && sign2 != GE) {
                        gotone = false;
                        continue;
                    }
                    break;
                }
            }
            if (pkg_exists)
                retcode = EX_OK;
            else
                print_info(pkg, opt);
        }
        if (ret != EPKG_END) {
            retcode = EX_IOERR;
        }

        if (retcode == EX_OK && !gotone && match != MATCH_ALL) {
            if (!quiet)
                warnx("No package(s) matching %s", argv[i]);
            retcode = EX_SOFTWARE;
        }

        pkgdb_it_free(it);

        i++;
    } while (i < argc);

cleanup:
    if (pkg != NULL)
        pkg_free(pkg);

    pkgdb_release_lock(db, PKGDB_LOCK_READONLY);
    pkgdb_close(db);

    return (retcode);
}
Esempio n. 17
0
File: info.c Progetto: aklv/pkgng
int
exec_info(int argc, char **argv)
{
	struct pkgdb *db = NULL;
	struct pkgdb_it *it = NULL;
	int query_flags;
	struct pkg *pkg = NULL;
	unsigned int opt = INFO_TAG_NAMEVER;
	match_t match = MATCH_EXACT;
	char *pkgname;
	char *pkgversion = NULL, *pkgversion2 = NULL;
	const char *file = NULL;
	int ch;
	int ret = EPKG_OK;
	int retcode = 0;
	bool gotone = false;
	int i, j;
	int sign = 0;
	int sign2 = 0;
	bool pkg_exists = false;
	bool origin_search = false;

	/* TODO: exclusive opts ? */
	while ((ch = getopt(argc, argv, "aDegixEIdrklBsqopOfF:R")) != -1) {
		switch (ch) {
		case 'a':
			match = MATCH_ALL;
			break;
		case 'O':
			origin_search = true;  /* only for ports compat */
			break;
		case 'e':
			pkg_exists = true;;
			retcode = 1;
			break;
		case 'g':
			match = MATCH_GLOB;
			break;
		case 'i':
			pkgdb_set_case_sensitivity(false);
			break;
		case 'x':
			match = MATCH_REGEX;
			break;
		case 'D':
			opt |= INFO_MESSAGE;
			break;
		case 'd':
			opt |= INFO_DEPS;
			break;
		case 'I':
			opt |= INFO_COMMENT;
			break;
		case 'r':
			opt |= INFO_RDEPS;
			break;
		case 'k':
			opt |= INFO_LOCKED;
			break;
		case 'l':
			opt |= INFO_FILES;
			break;
		case 'B':
			opt |= INFO_SHLIBS;
			break;
		case 's':
			opt |= INFO_FLATSIZE;
			break;
		case 'E': /* ports compatibility */
			/* FALLSTHROUGH */
		case 'q':
			quiet = true;
			break;
		case 'o':
			opt |= INFO_ORIGIN;
			break;
		case 'p':
			opt |= INFO_PREFIX;
			break;
		case 'f':
			opt |= INFO_FULL;
			break;
		case 'F':
			file = optarg;
			break;
		case 'R':
			opt |= INFO_RAW;
			break;
		default:
			usage_info();
			return(EX_USAGE);
		}
	}

	if (argc == 1)
		match = MATCH_ALL;

	argc -= optind;
	argv += optind;

	if (argc == 0 && file == NULL && match != MATCH_ALL) {
		/* which -O bsd.*.mk always execpt clean output */
		if (origin_search)
			return (EX_OK);
		usage_info();
		return (EX_USAGE);
	}

	/* When no other data is requested, default is to print
	 * 'name-ver comment' For -O, just print name-ver */
	if (!origin_search && (opt & INFO_ALL) == 0 && match == MATCH_ALL &&
	    !quiet)
		opt |= INFO_COMMENT;

	/* Special compatibility: handle -O and -q -O */
	if (origin_search) {
		if (quiet) {
			opt = INFO_TAG_NAMEVER;
			quiet = false;
		} else {
			opt = INFO_TAG_NAMEVER|INFO_COMMENT;
		}
	}

	if (match == MATCH_ALL && opt == INFO_TAG_NAMEVER)
		quiet = false;

	if (file != NULL) {
		if (pkg_open(&pkg, file) != EPKG_OK) {
			return (1);
		}
		print_info(pkg, opt);
		pkg_free(pkg);
		return (0);
	}

	ret = pkgdb_access(PKGDB_MODE_READ, PKGDB_DB_LOCAL);
	if (ret == EPKG_ENOACCESS) {
		warnx("Insufficient privilege to query package database");
		return (EX_NOPERM);
	} else if (ret == EPKG_ENODB) {
		if (match == MATCH_ALL)
			return (EX_OK);
		if (!quiet)
			warnx("No packages installed");
		return (EX_UNAVAILABLE);
	} else if (ret != EPKG_OK)
		return (EX_IOERR);
		
	ret = pkgdb_open(&db, PKGDB_DEFAULT);
	if (ret != EPKG_OK)
		return (EX_IOERR);

	i = 0;
	do {
		gotone = false;
		pkgname = argv[i];
		if (match != MATCH_ALL && pkgname[0] == '\0') {
			fprintf(stderr, "Pattern must not be empty.\n");
			i++;
			continue;
		}

		/*
		 * allow to search for origin with a trailing /
		 * likes audio/linux-vsound depending on ${PORTSDIR}/audio/sox/
		 */

		if (argc > 0 && pkgname[strlen(pkgname) -1] == '/')
			pkgname[strlen(pkgname) -1] = '\0';

		if (argc > 0) {
			j=0;
			while (pkgname[j] != '\0') {
				if (pkgname[j] == '<') {
					if (pkgversion) {
						pkgversion2 = pkgname + j;
						sign2 = LT;
						pkgversion2[0] = '\0';
						pkgversion2++;
						if (pkgversion2[0] == '=') {
							pkgversion2++;
							sign=LE;
							j++;
						}
					} else {
						pkgversion = pkgname + j;
						sign = LT;
						pkgversion[0] = '\0';
						pkgversion++;
						if (pkgversion[0] == '=') {
							pkgversion++;
							sign=LE;
							j++;
						}
					}
				} else if (pkgname[j] == '>') {
					if (pkgversion) {
						pkgversion2 = pkgname + j;
						sign2 = GT;
						pkgversion2[0] = '\0';
						pkgversion2++;
						if (pkgversion2[0] == '=') {
							pkgversion2++;
							sign=GE;
							j++;
						}
					} else {
						pkgversion = pkgname + j;
						sign = GT;
						pkgversion[0] = '\0';
						pkgversion++;
						if (pkgversion[0] == '=') {
							pkgversion++;
							sign=GE;
							j++;
						}
					}
				} else if (pkgname[j] == '=') {
					if (pkgversion) {
						pkgversion2 = pkgname + j;
						sign2 = EQ;
						pkgversion2[0] = '\0';
						pkgversion2++;
						if (pkgversion2[0] == '=') {
							pkgversion2++;
							sign=EQ;
							j++;
						}
					} else {
						pkgversion = pkgname + j;
						sign = EQ;
						pkgversion[0] = '\0';
						pkgversion++;
						if (pkgversion[0] == '=') {
							pkgversion++;
							sign=EQ;
							j++;
						}
					}
				}
				j++;
			}
		} else
			pkgversion = NULL;

		if ((it = pkgdb_query(db, pkgname, match)) == NULL) {
			return (EX_IOERR);
		}

		/* this is place for compatibility hacks */

		/* ports infrastructure expects pkg info -q -O to always return 0 even
		 * if the ports doesn't exists */
		if (origin_search)
			gotone = true;

		/* end of compatibility hacks */

		query_flags = info_flags(opt);
		while ((ret = pkgdb_it_next(it, &pkg, query_flags)) == EPKG_OK) {
			gotone = true;
			const char *version;

			pkg_get(pkg, PKG_VERSION, &version);
			if (pkgversion != NULL) {
				switch (pkg_version_cmp(version, pkgversion)) {
				case -1:
					if (sign != LT && sign != LE) {
						gotone = false;
						continue;
					}
					break;
				case 0:
					if (sign != LE &&
					    sign != GE &&
					    sign != EQ) {
						gotone = false;
						continue;
					}
					break;
				case 1:
					if (sign != GT && sign != GE) {
						gotone = false;
						continue;
					}
					break;
				}
			}
			if (pkgversion2 != NULL) {
				switch (pkg_version_cmp(version, pkgversion2)) {
				case -1:
					if (sign2 != LT && sign2 != LE) {
						gotone = false;
						continue;
					}
					break;
				case 0:
					if (sign2 != LE &&
					    sign2 != GE &&
					    sign2 != EQ) {
						gotone = false;
						continue;
					}
					break;
				case 1:
					if (sign2 != GT && sign2 != GE) {
						gotone = false;
						continue;
					}
					break;
				}
			}
			if (pkg_exists)
				retcode = EX_OK;
			else
				print_info(pkg, opt);
		}
		if (ret != EPKG_END) {
			retcode = EX_IOERR;
		}

		if (retcode == EX_OK && !gotone && match != MATCH_ALL) {
			if (!quiet)
				warnx("No package(s) matching %s", argv[i]);
			retcode = EX_SOFTWARE;
		}

		pkgdb_it_free(it);

		i++;
	} while (i < argc);

	pkg_free(pkg);
	pkgdb_close(db);

	return (retcode);
}