コード例 #1
0
ファイル: info.c プロジェクト: grembo/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

	struct option longopts[] = {
		{ "all",		no_argument,		NULL,	'a' },
		{ "annotations",	no_argument,		NULL,	'A' },
		{ "provided-shlibs",	no_argument,		NULL,	'b' },
		{ "required-shlibs",	no_argument,		NULL,	'B' },
		{ "case-sensitive",	no_argument,		NULL,	'C' },
		{ "dependencies",	no_argument,		NULL,	'd' },
		{ "pkg-message",	no_argument,		NULL,	'D' },
		{ "exists",		no_argument,		NULL,	'e' },
		{ "show-name-only",	no_argument,		NULL,	'E' },
		{ "full",		no_argument,		NULL,	'f' },
		{ "file",		required_argument,	NULL,	'F' },
		{ "glob",		no_argument,		NULL,	'g' },
		{ "case-insensitive",	no_argument,		NULL,	'i' },
		{ "comment",		no_argument,		NULL,	'I' },
		{ "locked",		no_argument,		NULL,	'k' },
		{ "list-files",		no_argument,		NULL,	'l' },
		{ "origin",		no_argument,		NULL,	'o' },
		{ "by-origin",		no_argument,		NULL,	'O' },
		{ "prefix",		no_argument,		NULL,	'p' },
		{ "quiet",		no_argument,		NULL,	'q' },
		{ "required-by",	no_argument,		NULL,	'r' },
		{ "raw",		no_argument,		NULL,	'R' },
		{ "size",		no_argument,		NULL,	's' },
		{ "regex",		no_argument,		NULL,	'x' },
		{ "raw-format",		required_argument,	NULL, 	1   },
		{ NULL,			0,			NULL,	0   },
	};

	/* TODO: exclusive opts ? */
	while ((ch = getopt_long(argc, argv, "+aAbBCdDeEfF:giIkloOpqrRsx", longopts, NULL)) != -1) {
		switch (ch) {
		case 'a':
			match = MATCH_ALL;
			break;
		case 'A':
			opt |= INFO_ANNOTATIONS;
			break;
		case 'b':
			opt |= INFO_SHLIBS_PROVIDED;
			break;
		case 'B':
			opt |= INFO_SHLIBS_REQUIRED;
			break;
		case 'C':
			pkgdb_set_case_sensitivity(true);
			break;
		case 'd':
			opt |= INFO_DEPS;
			break;
		case 'D':
			opt |= INFO_MESSAGE;
			break;
		case 'e':
			pkg_exists = true;;
			retcode = 1;
			break;
		case 'E': /* ports compatibility */
			e_flag = true;
			break;
		case 'f':
			opt |= INFO_FULL;
			break;
		case 'F':
			file = optarg;
			break;
		case 'g':
			match = MATCH_GLOB;
			break;
		case 'i':
			pkgdb_set_case_sensitivity(false);
			break;
		case 'I':
			opt |= INFO_COMMENT;
			break;
		case 'k':
			opt |= INFO_LOCKED;
			break;
		case 'l':
			opt |= INFO_FILES;
			break;
		case 'o':
			opt |= INFO_ORIGIN;
			break;
		case 'O':
			origin_search = true;  /* only for ports compat */
			break;
		case 'p':
			opt |= INFO_PREFIX;
			break;
		case 'q':
			quiet = true;
			break;
		case 'r':
			opt |= INFO_RDEPS;
			break;
		case 'R':
			opt |= INFO_RAW;
			break;
		case 's':
			opt |= INFO_FLATSIZE;
			break;
		case 'x':
			match = MATCH_REGEX;
			break;
		case 1:
			if (strcasecmp(optarg, "json") == 0)
				opt |= INFO_RAW_JSON;
			else if (strcasecmp(optarg, "json-compact") == 0)
				opt |= INFO_RAW_JSON_COMPACT;
			else if (strcasecmp(optarg, "yaml") == 0)
				opt |= INFO_RAW_YAML;
			else if (strcasecmp(optarg, "ucl") == 0)
				opt |= INFO_RAW_UCL;
			else
				errx(EX_USAGE, "Invalid format '%s' for the "
				    "raw output, expecting json, json-compact "
				    "or yaml", optarg);
			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");
			close(fd);
			return (EX_SOFTWARE);
		}

		if (cap_enter() < 0 && errno != ENOSYS) {
			warn("cap_enter() failed");
			close(fd);
			return (EX_SOFTWARE);
		}
#endif
		if (opt == INFO_TAG_NAMEVER)
			opt |= INFO_FULL;
		pkg_manifest_keys_new(&keys);
		if (opt & INFO_RAW) {
			if ((opt & (INFO_RAW_JSON|INFO_RAW_JSON_COMPACT|INFO_RAW_UCL)) == 0)
				opt |= INFO_RAW_YAML;
		}

		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) != 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:
	pkg_free(pkg);

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

	return (retcode);
}
コード例 #2
0
ファイル: upgrade.c プロジェクト: AlexanderThaller/pkg
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;
	bool yes = true, yes_arg = false;
	bool dry_run = false;
	bool auto_update;
	int done = 0;
	nbactions = nbdone = 0;
	pkg_flags f = PKG_FLAG_NONE | PKG_FLAG_PKG_VERSION_TEST;

	yes_arg = pkg_object_bool(pkg_config_get("ASSUME_ALWAYS_YES"));
	auto_update = pkg_object_bool(pkg_config_get("REPO_AUTOUPDATE"));

	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;
			lock_type = PKGDB_LOCK_READONLY;
			dry_run = true;
			break;
		case 'F':
			f |= PKG_FLAG_SKIP_INSTALL;
			lock_type = PKGDB_LOCK_READONLY;
			break;
		case 'q':
			quiet = true;
			break;
		case 'r':
			reponame = optarg;
			break;
		case 'y':
			yes_arg = 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, 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, 0, 0) != 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 (pkg_jobs_solve(jobs) != EPKG_OK)
		goto cleanup;

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

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

		if (yes) {
			retcode = pkg_jobs_apply(jobs);
			done = 1;
			if (retcode == EPKG_CONFLICT) {
				printf ("The conflicts with the existing packages have been found.\n"
						"We need to run one more solver iteration 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 && yes)
		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 (!yes && newpkgversion)
		newpkgversion = false;

	return (retcode);
}
コード例 #3
0
ファイル: add.c プロジェクト: jillest/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;
			force = true;
			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);
}
コード例 #4
0
ファイル: set.c プロジェクト: dlandry/GitEducation
int
exec_set(int argc, char **argv)
{
	struct pkgdb	*db = NULL;
	struct pkgdb_it	*it = NULL;
	struct pkg	*pkg = NULL;
	int		 ch;
	int		 i;
	match_t		 match = MATCH_EXACT;
	int64_t		 newautomatic = -1;
	bool		 automatic = false;
	bool		 rc = false;
	const char	*changed = NULL;
	char		*newvalue = NULL;
	char		*oldvalue = NULL;
	unsigned int	 loads = PKG_LOAD_BASIC;
	unsigned int	 sets = 0;
	unsigned int	 field = 0, depfield = 0;
	int		 retcode;

	struct option longopts[] = {
		{ "automatic",		required_argument,	NULL,	'A' },
		{ "all",		no_argument,		NULL,	'a' },
		{ "case-sensitive",	no_argument,		NULL,	'C' },
		{ "glob",		no_argument,		NULL,	'g' },
		{ "case-insensitive",	no_argument,		NULL,	'i' },
		{ "change-origin",	required_argument,	NULL,	'o' },
		{ "change-name",	required_argument,	NULL,	'n' },
		{ "regex",		no_argument,		NULL,	'x' },
		{ "yes",		no_argument,		NULL,	'y' },
		{ NULL,			0,			NULL,	0   },
	};

	while ((ch = getopt_long(argc, argv, "+A:aCgio:xyn:", longopts, NULL)) != -1) {
		switch (ch) {
		case 'A':
			sets |= AUTOMATIC;
			newautomatic = optarg[0] - '0';
			if (newautomatic != 0 && newautomatic != 1)
				errx(EX_USAGE, "Wrong value for -A. "
				    "Expecting 0 or 1, got: %s",
				    optarg);
			break;
		case 'a':
			match = MATCH_ALL;
			break;
		case 'C':
			pkgdb_set_case_sensitivity(true);
			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;
			changed = "origin";
			if (!check_change_values(optarg, &oldvalue, &newvalue, '/')) {
				 errx(EX_USAGE, "Wrong format for -o. "
					 "Expecting oldorigin:neworigin, got: %s",
					 optarg);
			}
			break;
		case 'n':
			sets |= NAME;
			loads |= PKG_LOAD_DEPS;
			match = MATCH_ALL;
			changed = "name";
			if (!check_change_values(optarg, &oldvalue, &newvalue, '\0')) {
				 errx(EX_USAGE, "Wrong format for -n. "
					 "Expecting oldname:newname, got: %s",
					 optarg);
			}
			break;
		case 'x':
			match = MATCH_REGEX;
			break;
		case 'y':
			yes = true;
			break;
		default:
			free(oldvalue);
			
			usage_set();
			return (EX_USAGE);
		}
	}

	argc -= optind;
	argv += optind;

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

	if (sets & NAME) {
		field = PKG_SET_NAME;
		depfield = PKG_SET_DEPNAME;
	}
	else if (sets & ORIGIN) {
		field = PKG_SET_ORIGIN;
		depfield = PKG_SET_DEPORIGIN;
	}

	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 privileges to modify the 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) {
		free(newvalue);
		return (EX_IOERR);
	}

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

	if (pkgdb_transaction_begin(db, NULL) != EPKG_OK) {
		pkgdb_close(db);
		free(newvalue);
		warnx("Cannot start transaction for update");
		return (EX_TEMPFAIL);
	}

 
	if (oldvalue != NULL) {
		match = MATCH_ALL;
		if ((it = pkgdb_query(db, oldvalue, MATCH_EXACT)) == NULL) {
			retcode = EX_IOERR;
			goto cleanup;
		}

		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);*/
		}

		rc = yes;
		if (!yes) {
			if (pkg != NULL)
				rc = query_yesno(false, "Change %S from %S to %S for %n-%v? ",
						changed, oldvalue, newvalue, pkg, pkg);
			else
				rc = query_yesno(false, "Change %S from %S to %S for all dependencies? ",
						changed, oldvalue, newvalue);
		}
		if (pkg != NULL && rc) {
			if (pkgdb_set(db, pkg, field, newvalue) != EPKG_OK) {
				retcode = EX_IOERR;
				goto cleanup;
			}
		}
		pkgdb_it_free(it);
	}
	i = 0;
	do {
		bool saved_rc = rc;

		if ((it = pkgdb_query(db, argv[i], match)) == NULL) {
			retcode = EX_IOERR;
			goto cleanup;
		}

		while (pkgdb_it_next(it, &pkg, loads) == EPKG_OK) {
			if ((sets & AUTOMATIC) == AUTOMATIC) {
				pkg_get(pkg, PKG_AUTOMATIC, &automatic);
				if (automatic == newautomatic)
					continue;
				if (!rc) {
					if (newautomatic)
						rc = query_yesno(false,
								"Mark %n-%v as automatically installed? ",
								pkg, pkg);
					else
						rc = query_yesno(false,
								"Mark %n-%v as not automatically installed? ",
								pkg, pkg);
				}
				if (rc)
					pkgdb_set(db, pkg, PKG_SET_AUTOMATIC, (int)newautomatic);
				rc = saved_rc;
			}
			if (sets & (ORIGIN|NAME)) {
				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, depfield, oldvalue, newvalue) != EPKG_OK) {
						retcode = EX_IOERR;
						goto cleanup;
					}
				}
			}
		}
		pkgdb_it_free(it);
		i++;
	} while (i < argc);

cleanup:
	free(oldvalue);
	free(newvalue);
	pkg_free(pkg);

	if (retcode == 0) {
		pkgdb_transaction_commit(db, NULL);
	}
	else {
		pkgdb_transaction_rollback(db, NULL);
	}

	pkgdb_release_lock(db, PKGDB_LOCK_EXCLUSIVE);
	pkgdb_close(db);

	return (retcode);
}
コード例 #5
0
ファイル: audit.c プロジェクト: 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);
		});
コード例 #6
0
ファイル: register.c プロジェクト: ppentchev/pkg
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];

	const char	*plist      = NULL;
	const char	*mdir       = NULL;
	const char	*mfile      = NULL;
	const char	*input_path = NULL;
	const char	*desc       = NULL;
	const char	*location   = 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;

	/* options descriptor */
	struct option longopts[] = {
		{ "automatic",	no_argument,		NULL,	'A' },
		{ "plist",	required_argument,	NULL,	'f' },
		{ "root",	required_argument,	NULL,	'i' },
		{ "legacy",	no_argument,		NULL,	'l' },
		{ "manifest",	required_argument,	NULL,	'M' },
		{ "metadata",	required_argument,	NULL,	'm' },
		{ "old",	no_argument,		NULL,	'O' },
		{ "test",	no_argument,		NULL,	't' },
		{ "relocate",	required_argument,	NULL, 	1 },
		{ NULL,		0,			NULL,	0},
	};

	developer = pkg_object_bool(pkg_config_get("DEVELOPER_MODE"));

	if (pkg_new(&pkg, PKG_INSTALLED) != EPKG_OK)
		err(EX_OSERR, "malloc");

	while ((ch = getopt_long(argc, argv, "Adf:i:lM:m:Ot", longopts, NULL)) != -1) {
		switch (ch) {
		case 'A':
		case 'd':
			pkg_set(pkg, PKG_AUTOMATIC, (bool)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;
		case 1:
			location = optarg;
			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 privileges 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_parse_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_parse_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) {
		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);
		}
	}

	/*
	 * 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, input_path);

	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, location ? location : "/");
	
	if (location != NULL)
		pkg_addannotation(pkg, "relocated", location);

	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_release_lock(db, PKGDB_LOCK_EXCLUSIVE);
		pkgdb_close(db);
	}

	pkg_free(pkg);

	return (retcode);
}
コード例 #7
0
ファイル: delete.c プロジェクト: AMDmi3/pkg
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,
				"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;

	pkgdb_compact(db);

	retcode = EX_OK;

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

	return (retcode);
}
コード例 #8
0
ファイル: check.c プロジェクト: AlexanderThaller/pkg
int
exec_check(int argc, char **argv)
{
	struct pkg *pkg = NULL;
	struct pkgdb_it *it = NULL;
	struct pkgdb *db = NULL;
	match_t match = MATCH_EXACT;
	int flags = PKG_LOAD_BASIC;
	int ret, rc = EX_OK;
	int ch;
	bool yes;
	bool dcheck = false;
	bool checksums = false;
	bool recompute = false;
	bool reanalyse_shlibs = false;
	bool noinstall = false;
	int nbpkgs = 0;
	int i;
	int verbose = 0;

	yes = pkg_object_bool(pkg_config_get("ASSUME_ALWAYS_YES"));

        /* Set default case sensitivity for searching */
        pkgdb_set_case_sensitivity(
                pkg_object_bool(pkg_config_get("CASE_SENSITIVE_MATCH"))
                );

	struct deps_head dh = STAILQ_HEAD_INITIALIZER(dh);

	while ((ch = getopt(argc, argv, "aBCdginrsvxy")) != -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 '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) {
		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);
	}

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

	if (pkgdb_obtain_lock(db, PKGDB_LOCK_ADVISORY, 0, 0) != 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;
	do {
		if ((it = pkgdb_query(db, argv[i], match)) == NULL) {
			rc = EX_IOERR;
			goto cleanup;
		}

		while (pkgdb_it_next(it, &pkg, flags) == EPKG_OK) {
			/* check for missing dependencies */
			if (dcheck) {
				if (verbose)
					pkg_printf("Checking dependencies: %n\n", pkg);
				nbpkgs += check_deps(db, pkg, &dh, noinstall);
				if (noinstall && nbpkgs > 0) {
					rc = EX_UNAVAILABLE;
				}
			}
			if (checksums) {
				if (verbose)
					pkg_printf("Checking checksums: %n\n", pkg);
				if (pkg_test_filesum(pkg) != EPKG_OK) {
					rc = EX_DATAERR;
				}
			}
			if (recompute) {
				if (pkgdb_upgrade_lock(db, PKGDB_LOCK_ADVISORY,
						PKGDB_LOCK_EXCLUSIVE, 0.5, 20) == EPKG_OK) {
					if (verbose)
						pkg_printf("Recomputing size and checksums: %n\n", pkg);
					if (pkg_recompute(db, pkg) != EPKG_OK) {
						rc = EX_DATAERR;
					}
					pkgdb_release_lock(db, PKGDB_LOCK_EXCLUSIVE);
				}
				else {
					rc = EX_TEMPFAIL;
				}
			}
			if (reanalyse_shlibs) {
				if (pkgdb_upgrade_lock(db, PKGDB_LOCK_ADVISORY,
						PKGDB_LOCK_EXCLUSIVE, 0.5, 20) == EPKG_OK) {
					if (verbose)
						pkg_printf("Reanalyzing files for shlibs: %n\n", pkg);
					if (pkgdb_reanalyse_shlibs(db, pkg) != EPKG_OK) {
						pkg_printf("Failed to reanalyse for shlibs: %n\n", pkg);
						rc = EX_UNAVAILABLE;
					}
					pkgdb_release_lock(db, PKGDB_LOCK_EXCLUSIVE);
				}
				else {
					rc = EX_TEMPFAIL;
				}
			}
		}

		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, 0.5, 20) == EPKG_OK) {
				ret = fix_deps(db, &dh, nbpkgs, yes);
				if (ret == EPKG_OK)
					check_summary(db, &dh);
				else if (ret == EPKG_ENODB) {
					db = NULL;
					rc = EX_IOERR;
				}
				pkgdb_release_lock(db, PKGDB_LOCK_EXCLUSIVE);
				if (rc == EX_IOERR)
					goto cleanup;
			}
			else {
				rc = EX_TEMPFAIL;
				goto cleanup;
			}
		}
		pkgdb_it_free(it);
		i++;
	} while (i < argc);

cleanup:
	deps_free(&dh);
	pkg_free(pkg);
	pkgdb_release_lock(db, PKGDB_LOCK_ADVISORY);
	pkgdb_close(db);

	return (rc);
}
コード例 #9
0
ファイル: create.c プロジェクト: TetragrammatonHermit/pkg
static int
pkg_create_matches(int argc, char **argv, match_t match, pkg_formats fmt,
    const char * const outdir, bool overwrite)
{
	int i, ret = EPKG_OK, retcode = EPKG_OK;
	struct pkg *pkg = NULL;
	struct pkgdb *db = NULL;
	struct pkgdb_it *it = NULL;
	int query_flags = PKG_LOAD_DEPS | PKG_LOAD_FILES |
	    PKG_LOAD_CATEGORIES | PKG_LOAD_DIRS | PKG_LOAD_SCRIPTS |
	    PKG_LOAD_OPTIONS | PKG_LOAD_LICENSES |
	    PKG_LOAD_USERS | PKG_LOAD_GROUPS | PKG_LOAD_SHLIBS_REQUIRED |
	    PKG_LOAD_SHLIBS_PROVIDED | PKG_LOAD_ANNOTATIONS;
	struct pkg_head head = STAILQ_HEAD_INITIALIZER(head);
	struct pkg_entry *e = NULL;
	char pkgpath[MAXPATHLEN];
	const char *format = NULL;
	bool foundone;

	if (pkgdb_open(&db, PKGDB_DEFAULT) != EPKG_OK) {
		pkgdb_close(db);
		return (EX_IOERR);
	}
	/* XXX: get rid of hardcoded timeouts */
	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);
	}

	switch (fmt) {
	case TXZ:
		format = "txz";
		break;
	case TBZ:
		format = "tbz";
		break;
	case TGZ:
		format = "tgz";
		break;
	case TAR:
		format = "tar";
		break;
	}

	for (i = 0; i < argc || match == MATCH_ALL; i++) {
		if (match == MATCH_ALL) {
			printf("Loading the package list...\n");
			if ((it = pkgdb_query(db, NULL, match)) == NULL)
				goto cleanup;
			match = !MATCH_ALL;
		} else
			if ((it = pkgdb_query(db, argv[i], match)) == NULL)
				goto cleanup;

		foundone = false;
		while ((ret = pkgdb_it_next(it, &pkg, query_flags)) == EPKG_OK) {
			if ((e = malloc(sizeof(struct pkg_entry))) == NULL)
				err(1, "malloc(pkg_entry)");
			e->pkg = pkg;
			pkg = NULL;
			STAILQ_INSERT_TAIL(&head, e, next);
			foundone = true;
		}
		if (!foundone) {
			warnx("No installed package matching \"%s\" found\n",
			    argv[i]);
			retcode++;
		}

		pkgdb_it_free(it);
		if (ret != EPKG_END)
			retcode++;
	}

	while (!STAILQ_EMPTY(&head)) {
		e = STAILQ_FIRST(&head);
		STAILQ_REMOVE_HEAD(&head, next);

		if (!overwrite) {
			pkg_snprintf(pkgpath, sizeof(pkgpath), "%S/%n-%v.%S",
			    outdir, e->pkg, e->pkg, format);
			if (access(pkgpath, F_OK) == 0) {
				pkg_printf("%n-%v already packaged, skipping...\n",
				    e->pkg, e->pkg);
				pkg_free(e->pkg);
				free(e);
				continue;
			}
		}
		pkg_printf("Creating package for %n-%v\n", e->pkg, e->pkg);
		if (pkg_create_installed(outdir, fmt, e->pkg) !=
		    EPKG_OK)
			retcode++;
		pkg_free(e->pkg);
		free(e);
	}

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

	return (retcode);
}
コード例 #10
0
ファイル: which.c プロジェクト: AlexanderThaller/pkg
int
exec_which(int argc, char **argv)
{
	struct pkgdb *db = NULL;
	struct pkgdb_it *it = NULL;
	struct pkg *pkg = NULL;
	char pathabs[MAXPATHLEN];
	char *p, *path, *match;
	int ret = EPKG_OK, retcode = EX_SOFTWARE;
	int ch;
	int res, pathlen;
	bool orig = false;
	bool glob = false;
	bool search = false;
	bool search_s = false;

	while ((ch = getopt(argc, argv, "qgop")) != -1) {
		switch (ch) {
		case 'q':
			quiet = true;
			break;
		case 'g':
			glob = true;
			break;
		case 'o':
			orig = true;
			break;
		case 'p':
			search_s = true;
			break;
		default:
			usage_which();
			return (EX_USAGE);
		}
	}

	argc -= optind;
	argv += optind;

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

	if (pkgdb_open(&db, PKGDB_DEFAULT) != 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);
	}

	if (search_s) {
		if ((path = getenv("PATH")) == NULL) {
			printf("$PATH is not set, falling back to non-search behaviour\n");
			search_s = false;
		} else {
			pathlen = strlen(path) + 1;
		}
	}

	while (argc >= 1) {
		retcode = EX_SOFTWARE;
		if (search_s) {
			if ((argv[0][0] == '.') || (argv[0][0] == '/')) {
				search = false;
			} else {
				search = true;

				if (strlen(argv[0]) >= FILENAME_MAX) {
					retcode = EX_USAGE;
					goto cleanup;
				}

				p = malloc(pathlen);
				if (p == NULL) {
					retcode = EX_OSERR;
					goto cleanup;
				}
				strlcpy(p, path, pathlen);

				match = NULL;
				res = get_match(&match, p, argv[0]);
				free(p);

				if (res == (EX_USAGE)) {
					printf("%s was not found in PATH, falling back to non-search behaviour\n", argv[0]);
					search = false;
				} else if (res == (EX_OSERR)) {
					retcode = EX_OSERR;
					goto cleanup;
				} else {
					absolutepath(match, pathabs, sizeof(pathabs));
					free(match);
				}
			}
		}

		if (!glob && !search)
			absolutepath(argv[0], pathabs, sizeof(pathabs));
		else if (!search) {
			if (strlcpy(pathabs, argv[0], sizeof(pathabs)) >= sizeof(pathabs))
				retcode = EX_USAGE;
				goto cleanup;
		}


		if ((it = pkgdb_query_which(db, pathabs, glob)) == NULL) {
			retcode = EX_IOERR;
			goto cleanup;
		}

		pkg = NULL;
		while ((ret = pkgdb_it_next(it, &pkg, PKG_LOAD_BASIC)) == EPKG_OK) {
			retcode = EX_OK;
			if (quiet && orig)
				pkg_printf("%o\n", pkg);
			else if (quiet && !orig)
				pkg_printf("%n-%v\n", pkg, pkg);
			else if (!quiet && orig)
				pkg_printf("%S was installed by package %o\n", pathabs, pkg);
			else if (!quiet && !orig)
				pkg_printf("%S was installed by package %n-%v\n", pathabs, pkg, pkg);
		}

		if (retcode != EX_OK && !quiet)
			printf("%s was not found in the database\n", pathabs);

		pkg_free(pkg);
		pkgdb_it_free(it);

		argc--;
		argv++;

	}

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

	return (retcode);
}
コード例 #11
0
ファイル: check.c プロジェクト: AlexanderThaller/pkg
static int
fix_deps(struct pkgdb *db, struct deps_head *dh, int nbpkgs, bool yes)
{
	struct pkg_jobs *jobs = NULL;
	struct deps_entry *e = NULL;
	char **pkgs = NULL;
	int i = 0;
	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->origin;

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

	if (pkgdb_obtain_lock(db, PKGDB_LOCK_ADVISORY, 0, 0) != 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;
	}

	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");
	
	if (!yes)
		yes = query_yesno(false, "\n>>> Try to fix the missing dependencies [y/N]: ");

	if (yes) {
		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:
	if (pkgs != NULL)
		free(pkgs);
	if (jobs != NULL)
		pkg_jobs_free(jobs);
	pkgdb_release_lock(db, PKGDB_LOCK_ADVISORY);
	pkgdb_close(db);

	return (EPKG_OK);
}
コード例 #12
0
ファイル: convert.c プロジェクト: TetragrammatonHermit/pkg
static int
convert_from_old(const char *pkg_add_dbdir, bool dry_run)
{
	DIR		*d;
	struct dirent	*dp;
	struct pkg	*p = NULL;
	char		 path[MAXPATHLEN];
	struct pkgdb	*db = NULL;
	struct stat	 sb;
	int		lock_type = PKGDB_LOCK_EXCLUSIVE;
	int		ret;

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

	if (ret == EPKG_ENOACCESS) {
		warnx("Insufficient privileges to convert packages");
		return (EX_NOPERM);
	} else if (ret != EPKG_OK && ret != EPKG_ENODB) {
		warnx("Error accessing the package database");
		return (EX_SOFTWARE);
	}

	if ((d = opendir(pkg_add_dbdir)) == NULL)
		err(EX_NOINPUT, "%s", pkg_add_dbdir);

	if (pkgdb_open(&db, PKGDB_DEFAULT) != EPKG_OK) {
		return (EX_IOERR);
	}
	if (dry_run)
		lock_type = PKGDB_LOCK_READONLY;
	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);
	}
	while ((dp = readdir(d)) != NULL) {
		if (fstatat(dirfd(d), dp->d_name, &sb, 0) == 0 &&
		    S_ISDIR(sb.st_mode)) {
			if (strcmp(dp->d_name, ".") == 0 ||
			    strcmp(dp->d_name, "..") == 0)
				continue;
			if (p != NULL)
				pkg_free(p);
			if (pkg_new(&p, PKG_OLD_FILE) != EPKG_OK)
				err(EX_OSERR, "malloc");
			printf("Converting %s...\n", dp->d_name);
			snprintf(path, sizeof(path), "%s/%s", pkg_add_dbdir, dp->d_name);
			if (pkg_old_load_from_path(p, path) != EPKG_OK) {
				fprintf(stderr, "Skipping invalid package: %s\n", path);
				continue;
			}
			pkg_from_old(p);
			if (!dry_run)
				pkgdb_register_ports(db, p);
		}
	}

	pkg_free(p);
	pkgdb_release_lock(db, lock_type);
	pkgdb_close(db);
	return (EX_OK);
}
コード例 #13
0
ファイル: fetch.c プロジェクト: nwhitehorn/pkg
int
exec_fetch(int argc, char **argv)
{
	struct pkgdb	*db = NULL;
	struct pkg_jobs	*jobs = NULL;
	const char	*reponame = NULL;
	int		 ch;
	int		 retcode = EX_SOFTWARE;
	bool		 upgrades_for_installed = false, rc;
	unsigned	 mode;
	match_t		 match = MATCH_EXACT;
	pkg_flags	 f = PKG_FLAG_NONE;

	struct option longopts[] = {
		{ "all",		no_argument,		NULL,	'a' },
		{ "case-sensitive",	no_argument,		NULL,	'C' },
		{ "dependencies",	no_argument,		NULL,	'd' },
		{ "glob",		no_argument,		NULL,	'g' },
		{ "case-insensitive",	no_argument,		NULL,	'i' },
		{ "quiet",		no_argument,		NULL,	'q' },
		{ "repository",		required_argument,	NULL,	'r' },
		{ "avaialbe-updates",	no_argument,		NULL,	'u' },
		{ "no-repo-update",	no_argument,		NULL,	'U' },
		{ "regex",		no_argument,		NULL,	'x' },
		{ "yes",		no_argument,		NULL,	'y' },
		{ NULL,			0,			NULL,	0   },
	};

	while ((ch = getopt_long(argc, argv, "aCdgiqr:Uuxy", longopts, NULL)) != -1) {
		switch (ch) {
		case 'a':
			match = MATCH_ALL;
			break;
		case 'C':
			pkgdb_set_case_sensitivity(true);
			break;
		case 'd':
			f |= PKG_FLAG_WITH_DEPS | PKG_FLAG_RECURSIVE;
			break;
		case 'g':
			match = MATCH_GLOB;
			break;
		case 'i':
			pkgdb_set_case_sensitivity(false);
			break;
		case 'q':
			quiet = true;
			break;
		case 'r':
			reponame = optarg;
			break;
		case 'u':
			f |= PKG_FLAG_UPGRADES_FOR_INSTALLED;
			upgrades_for_installed = true;
			break;
		case 'U':
			auto_update = false;
			break;
		case 'x':
			match = MATCH_REGEX;
			break;
		case 'y':
			yes = true;
			break;
		default:
			usage_fetch();
			return (EX_USAGE);
		}
	}
	argc -= optind;
	argv += optind;
	
	if (argc < 1 && match != MATCH_ALL && !upgrades_for_installed) {
		usage_fetch();
		return (EX_USAGE);
	}

        if (match == MATCH_ALL && upgrades_for_installed) {
		usage_fetch();
		return (EX_USAGE);
	}

	/* TODO: Allow the user to specify an output directory via -o
	   outdir */

	if (auto_update)
		mode = PKGDB_MODE_READ|PKGDB_MODE_WRITE|PKGDB_MODE_CREATE;
	else
		mode = PKGDB_MODE_READ;

	retcode = pkgdb_access(mode, PKGDB_DB_REPO);

	if (retcode == EPKG_ENOACCESS) {
		warnx("Insufficient privileges to access repo catalogue");
		return (EX_NOPERM);
	} else if (retcode != EPKG_OK)
		return (EX_IOERR);

	if (upgrades_for_installed) {
		retcode = pkgdb_access(PKGDB_MODE_READ, PKGDB_DB_LOCAL);

		if (retcode == EPKG_ENOACCESS) {
			warnx("Insufficient privileges to access the package database");
			return (EX_NOPERM);
		} else if (retcode != EPKG_OK)
			return (EX_IOERR);
	}

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

	if (pkgdb_open_all(&db, PKGDB_REMOTE, reponame) != 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 (pkg_jobs_new(&jobs, PKG_JOBS_FETCH, 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 (!upgrades_for_installed &&
	    pkg_jobs_add(jobs, match, argv, argc) != EPKG_OK)
		goto cleanup;

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

	if (pkg_jobs_count(jobs) == 0)
		goto cleanup;

	if (!quiet) {
		print_jobs_summary(jobs, "The following packages will be fetched:\n\n");
		rc = query_yesno(false, "\nProceed with fetching packages [y/N]: ");
	}
	else {
		rc = true;
	}
	
	if (!rc || pkg_jobs_apply(jobs) != EPKG_OK)
		goto cleanup;

	retcode = EX_OK;

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

	return (retcode);
}
コード例 #14
0
ファイル: upgrade.c プロジェクト: ChunHungLiu/pkg
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);
}
コード例 #15
0
ファイル: install.c プロジェクト: AsherBond/pkg
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' },
		{ "from-root",		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 &&
	    (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 packages will be affected (of %d checked):\n\n",
			    nbactions, pkg_jobs_total(jobs));

			if (!dry_run) {
				rc = query_yesno(false,
				    "\nProceed with this action? [y/N]: ");
			}
			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)
		printf("The most recent version of packages are already installed\n");

	retcode = EX_OK;

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

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

	return (retcode);
}
コード例 #16
0
ファイル: annotate.c プロジェクト: dpl0/pkg
int
exec_annotate(int argc, char **argv)
{
	struct pkgdb	*db       = NULL;
	struct pkgdb_it	*it       = NULL;
	struct pkg	*pkg      = NULL;
	enum action	 action   = NONE;
	const char	*tag;
	const char	*value;
	const char	*pkgname;
	struct sbuf	*input    = NULL;
	int		 ch;
	int		 match    = MATCH_EXACT;
	int		 retcode;
	int		 exitcode = EX_OK;
	int		 flags = 0;

	struct option longopts[] = {
		{ "all",		no_argument,	NULL,	'a' },
		{ "add",		no_argument,	NULL,	'A' },
		{ "case-insensitive",	no_argument,	NULL,	'C' },
		{ "delete",		no_argument,	NULL,	'D' },
		{ "glob",		no_argument,	NULL,	'g' },
		{ "case-insensitive",	no_argument,	NULL,	'i' },
		{ "modify",		no_argument,	NULL,	'M' },
		{ "quiet",		no_argument,	NULL,	'q' },
		{ "show",		no_argument,	NULL,	'S' },
		{ "regex",		no_argument,	NULL,	'x' },
		{ "yes",		no_argument,	NULL,	'y' },
		{ NULL,			0,		NULL,	0   },
	};

        /* Set default case sensitivity for searching */
        pkgdb_set_case_sensitivity(
                pkg_object_bool(pkg_config_get("CASE_SENSITIVE_MATCH"))
                );

	while ((ch = getopt_long(argc, argv, "+aACDgiMqSxy", longopts, NULL))
	       != -1) {
		switch (ch) {
		case 'a':
			match = MATCH_ALL;
			break;
		case 'A':
			action = ADD;
			break;
		case 'C':
			pkgdb_set_case_sensitivity(true);
			break;
		case 'D':
			action = DELETE;
			break;
		case 'g':
			match = MATCH_GLOB;
			break;
		case 'i':
			pkgdb_set_case_sensitivity(false);
			break;
		case 'M':
			action = MODIFY;
			break;
		case 'q':
			quiet = true;
			break;
		case 'S':
			action = SHOW;
			flags |= PKG_LOAD_ANNOTATIONS;
			break;
		case 'x':
			match = MATCH_REGEX;
			break;
		case 'y':
			yes = true;
			break;
		default:
			usage_annotate();
			return (EX_USAGE);
		}
        }
	argc -= optind;
	argv += optind;

	if (action == NONE || 
	    (match == MATCH_ALL && argc < 1) ||
	    (match != MATCH_ALL && argc < 2)) {
		usage_annotate();
		return (EX_USAGE);
	}

	if (match == MATCH_ALL) {
		pkgname = NULL;
		tag     = argv[0];
		value   = (argc > 1) ? argv[1] : NULL;
	} else {
		pkgname = argv[0];
		tag     = argv[1];
		value   = (argc > 2) ? argv[2] : NULL;
	}

	if ((action == ADD || action == MODIFY) && value == NULL) {
		/* try and read data for the value from stdin. */
		input = read_input();
		value = sbuf_data(input);
	}

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

	retcode = pkgdb_open(&db, PKGDB_DEFAULT);
	if (retcode != 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);
	}

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

	while ((retcode = pkgdb_it_next(it, &pkg, flags)) == EPKG_OK) {

		switch(action) {
		case NONE:	/* Should never happen */
			usage_annotate();
			exitcode = EX_USAGE;
			break;
		case ADD:
			retcode = do_add(db, pkg, tag, value);
			break;
		case MODIFY:
			retcode = do_modify(db, pkg, tag, value);
			break;
		case DELETE:
			retcode = do_delete(db, pkg, tag);
			break;
		case SHOW:
			retcode = do_show(pkg, tag);
			break;
		}

		if (retcode == EPKG_WARN)
			exitcode = EX_DATAERR;

		if (retcode != EPKG_OK && retcode != EPKG_WARN) {
			exitcode = EX_IOERR;
			goto cleanup;
		}
	}

cleanup:
	pkg_free(pkg);
	pkgdb_it_free(it);

	pkgdb_release_lock(db, PKGDB_LOCK_EXCLUSIVE);
	pkgdb_close(db);
	if (input != NULL)
		sbuf_delete(input);

	return (exitcode);
}
コード例 #17
0
ファイル: set.c プロジェクト: rakhij/pkg
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;
	int64_t newautomatic = -1;
	bool automatic = false;
	const char *errstr;
	char *neworigin = NULL;
	char *oldorigin = NULL;
	unsigned int loads = PKG_LOAD_BASIC;
	unsigned int sets = 0;
	int retcode;

	yes = pkg_object_bool(pkg_config_get("ASSUME_ALWAYS_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 privileges to modify the 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 (pkgdb_obtain_lock(db, PKGDB_LOCK_EXCLUSIVE, 0, 0) != EPKG_OK) {
		pkgdb_close(db);
		warnx("Cannot get an exclusive lock on a database, it is locked by another process");
		return (EX_TEMPFAIL);
	}

 
	if (oldorigin != NULL) {
		match = MATCH_ALL;
		if ((it = pkgdb_query(db, oldorigin, MATCH_EXACT)) == NULL) {
			retcode = EX_IOERR;
			goto cleanup;
		}

		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 (!yes) {
			if (pkg != NULL)
				yes = query_yesno(false, "Change origin from %S to %S for %n-%v? [y/N]: ",
				    oldorigin, neworigin, pkg, pkg);
			else
				yes = query_yesno(false, "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) {
				retcode = EX_IOERR;
				goto cleanup;
			}
		}
		pkgdb_it_free(it);
	}
	i = 0;
	do {
		bool save_yes = yes;

		if ((it = pkgdb_query(db, argv[i], match)) == NULL) {
			retcode = EX_IOERR;
			goto cleanup;
		}

		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) {
					if (newautomatic)
						yes = query_yesno(false, "Mark %n-%v as automatically installed? [y/N]: ", pkg, pkg);
					else
						yes = query_yesno(false, "Mark %n-%v as not automatically installed? [y/N]: ", pkg, pkg);
				}
				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) {
						retcode = EX_IOERR;
						goto cleanup;
					}
				}
			}
		}
		pkgdb_it_free(it);
		i++;
	} while (i < argc);

cleanup:
	if (oldorigin)
		free(oldorigin);

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

	pkgdb_release_lock(db, PKGDB_LOCK_EXCLUSIVE);
	pkgdb_close(db);

	return (retcode);
}
コード例 #18
0
ファイル: autoremove.c プロジェクト: derekschrock/pkg
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);
		if (!dry_run)
			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);
}
コード例 #19
0
ファイル: query.c プロジェクト: dlandry/GitEducation
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);
}
コード例 #20
0
ファイル: check.c プロジェクト: dpl0/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' },
		{ "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, "+aBCdginrsvxy", 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 '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) {
		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);
	}

	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 (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;
		}

		while (pkgdb_it_next(it, &pkg, flags) == EPKG_OK) {
			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 (verbose)
					printf(" dependencies...");
				nbpkgs += check_deps(db, pkg, &dh, noinstall);
				if (noinstall && nbpkgs > 0) {
					rc = EX_UNAVAILABLE;
				}
			}
			if (checksums) {
				if (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 (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 (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 (!verbose)
				++processed;
			else
				printf(" done\n");
		}
		if (!verbose)
			progressbar_tick(processed, total);
		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, yes);
				if (ret == EPKG_OK)
					check_summary(db, &dh);
				else if (ret == EPKG_ENODB) {
					db = NULL;
					rc = EX_IOERR;
				}
				pkgdb_downgrade_lock(db, PKGDB_LOCK_EXCLUSIVE,
				    PKGDB_LOCK_ADVISORY);
				if (rc == EX_IOERR)
					goto cleanup;
			}
			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);
}
コード例 #21
0
ファイル: stats.c プロジェクト: AsherBond/pkg
int
exec_stats(int argc, char **argv)
{
	struct pkgdb	*db = NULL;
	int64_t		 flatsize = 0;
	unsigned int	 opt = 0;
	char		 size[7];
	int		 ch;
	bool		 show_bytes = false;

	struct option longopts[] = {
		{ "bytes",	no_argument,	NULL,	'b' },
		{ "local",	no_argument,	NULL,	'l' },
		{ "quiet",	no_argument,	NULL,	'q' },
		{ "remote",	no_argument,	NULL,	'r' },
		{ NULL,		0,		NULL,	0   },
	};
	
	while ((ch = getopt_long(argc, argv, "+blqr", longopts, NULL)) != -1) {
                switch (ch) {
		case 'b':
			show_bytes = true;
			break;
		case 'l':
			opt |= STATS_LOCAL;
			break;
		case 'q':
			quiet = true;
			break;
		case 'r':
			opt |= STATS_REMOTE;
			break;
		default:
			usage_stats();
			return (EX_USAGE);
                }
        }
        argc -= optind;
        argv += optind;

	/* default is to show everything we have */
	if (opt == 0)
		opt |= (STATS_LOCAL | STATS_REMOTE);

	if (pkgdb_open(&db, PKGDB_REMOTE) != 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 (opt & STATS_LOCAL) {
		printf("Local package database:\n");
		printf("\tInstalled packages: %" PRId64 "\n", pkgdb_stats(db, PKG_STATS_LOCAL_COUNT));

		flatsize = pkgdb_stats(db, PKG_STATS_LOCAL_SIZE);

		if (show_bytes)
			printf("\tDisk space occupied: %" PRId64 "\n\n", flatsize);
		else {
			humanize_number(size, sizeof(size), flatsize, "B", HN_AUTOSCALE, 0);
			printf("\tDisk space occupied: %s\n\n", size);
		}
	}

	if ((opt & STATS_REMOTE) && pkg_repos_total_count() > 0) {
		printf("Remote package database(s):\n");
		printf("\tNumber of repositories: %" PRId64 "\n", pkgdb_stats(db, PKG_STATS_REMOTE_REPOS));
		printf("\tPackages available: %" PRId64 "\n", pkgdb_stats(db, PKG_STATS_REMOTE_COUNT));
		printf("\tUnique packages: %" PRId64 "\n", pkgdb_stats(db, PKG_STATS_REMOTE_UNIQUE));

		flatsize = pkgdb_stats(db, PKG_STATS_REMOTE_SIZE);

		if (show_bytes)
			printf("\tTotal size of packages: %" PRId64 "\n", flatsize);
		else {
			humanize_number(size, sizeof(size), flatsize, "B", HN_AUTOSCALE, 0);
			printf("\tTotal size of packages: %s\n", size);
		}
	}

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

	return (EX_OK);
}
コード例 #22
0
ファイル: which.c プロジェクト: dlandry/GitEducation
int
exec_which(int argc, char **argv)
{
	struct pkgdb	*db = NULL;
	struct pkgdb_it	*it = NULL;
	struct pkg	*pkg = NULL;
	char		 pathabs[MAXPATHLEN];
	char		*p, *path, *match, *savedpath;
	int		 ret = EPKG_OK, retcode = EX_SOFTWARE;
	int		 ch, i;
	int		 res, pathlen = 0;
	bool		 orig = false;
	bool		 glob = false;
	bool		 search = false;
	bool		 search_s = false;
	charlist	 patterns;

	struct option longopts[] = {
		{ "glob",		no_argument,	NULL,	'g' },
		{ "origin",		no_argument,	NULL,	'o' },
		{ "path-search",	no_argument,	NULL,	'p' },
		{ "quiet",		no_argument,	NULL,	'q' },
		{ NULL,			0,		NULL,	0   },
	};

	path = NULL;

	while ((ch = getopt_long(argc, argv, "+gopq", longopts, NULL)) != -1) {
		switch (ch) {
		case 'g':
			glob = true;
			break;
		case 'o':
			orig = true;
			break;
		case 'p':
			search_s = true;
			break;
		case 'q':
			quiet = true;
			break;
		default:
			usage_which();
			return (EX_USAGE);
		}
	}

	argc -= optind;
	argv += optind;

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

	if (pkgdb_open(&db, PKGDB_DEFAULT) != 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 (search_s) {
		if ((path = getenv("PATH")) == NULL) {
			printf("$PATH is not set, falling back to non-search behaviour\n");
			search_s = false;
		} else {
			pathlen = strlen(path) + 1;
		}
	}

	while (argc >= 1) {
		kv_init(patterns);
		retcode = EX_SOFTWARE;
		if (search_s) {
			if ((argv[0][0] == '.') || (argv[0][0] == '/')) {
				search = false;
			} else {
				search = true;

				if (strlen(argv[0]) >= FILENAME_MAX) {
					retcode = EX_USAGE;
					goto cleanup;
				}

				p = malloc(pathlen);
				if (p == NULL) {
					retcode = EX_OSERR;
					goto cleanup;
				}
				strlcpy(p, path, pathlen);

				match = NULL;
				savedpath=p;
				for (;;) {
					res = get_match(&match, &p, argv[0]);
					if (p == NULL)
						break;

					if (res == (EX_USAGE)) {
						printf("%s was not found in PATH, falling back to non-search behaviour\n", argv[0]);
						search = false;
					} else if (res == (EX_OSERR)) {
						retcode = EX_OSERR;
						free(savedpath);
						goto cleanup;
					} else {
						pkg_absolutepath(match, pathabs, sizeof(pathabs));
						/* ensure not not append twice an entry if PATH is messy */
						if (already_in_list(&patterns, pathabs))
							continue;
						kv_push(char *, patterns, strdup(pathabs));
						free(match);
					}
				}
				free(savedpath);
			}
		}

		if (!glob && !search) {
			pkg_absolutepath(argv[0], pathabs, sizeof(pathabs));
			kv_push(char *, patterns, strdup(pathabs));
		} else if (!search) {
			if (strlcpy(pathabs, argv[0], sizeof(pathabs)) >= sizeof(pathabs)) {
				retcode = EX_USAGE;
				goto cleanup;
                        }
		}


		for (i = 0; i < kv_size(patterns); i++) {
			if ((it = pkgdb_query_which(db, kv_A(patterns, i), glob)) == NULL) {
				retcode = EX_IOERR;
				goto cleanup;
			}

			pkg = NULL;
			while ((ret = pkgdb_it_next(it, &pkg, PKG_LOAD_BASIC)) == EPKG_OK) {
				retcode = EX_OK;
				if (quiet && orig)
					pkg_printf("%o\n", pkg);
				else if (quiet && !orig)
					pkg_printf("%n-%v\n", pkg, pkg);
				else if (!quiet && orig)
					pkg_printf("%S was installed by package %o\n", kv_A(patterns, i), pkg);
				else if (!quiet && !orig)
					pkg_printf("%S was installed by package %n-%v\n", kv_A(patterns, i), pkg, pkg);
			}
			if (retcode != EX_OK && !quiet)
				printf("%s was not found in the database\n", kv_A(patterns, i));

			pkg_free(pkg);
			pkgdb_it_free(it);

		}
		kv_destroy(patterns);

		argc--;
		argv++;

	}

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

	return (retcode);
}
コード例 #23
0
ファイル: lock.c プロジェクト: jillest/pkg
static int
exec_lock_unlock(int argc, char **argv, enum action action)
{
	struct pkgdb	*db = NULL;
	struct pkgdb_it	*it = NULL;
	struct pkg	*pkg = NULL;
	const char	*pkgname;
	int		 match = MATCH_EXACT;
	int		 retcode;
	int		 exitcode = EX_OK;
	int		 ch;
	bool		 show_locked = false;

	struct option longopts[] = {
		{ "all",		no_argument,	NULL,	'a' },
		{ "case-sensitive",	no_argument,	NULL,	'C' },
		{ "glob",		no_argument,	NULL,	'g' },
		{ "show-locked",	no_argument,	NULL,	'l' },
		{ "quiet",		no_argument,	NULL,	'q' },
		{ "regex",		no_argument,	NULL,	'x' },
		{ "yes",		no_argument,	NULL,	'y' },
		{ NULL,		0,			NULL,	0   },
	};

	while ((ch = getopt_long(argc, argv, "aCgilqxy", longopts, NULL)) != -1) {
		switch (ch) {
		case 'a':
			match = MATCH_ALL;
			break;
		case 'C':
			pkgdb_set_case_sensitivity(true);
			break;
		case 'g':
			match = MATCH_GLOB;
			break;
		case 'i':
			pkgdb_set_case_sensitivity(false);
			break;
		case 'l':
			show_locked = true;
			break;
		case 'q':
			quiet = true;
			break;
		case 'x':
			match = MATCH_REGEX;
			break;
		case 'y':
			yes = true;
			break;
		default:
			usage_lock();
			return (EX_USAGE);
		}
        }
	argc -= optind;
	argv += optind;

	

	if (!(match == MATCH_ALL && argc == 0) && argc != 1 && !show_locked) {
		usage_lock();
		return (EX_USAGE);
	}

	if (match == MATCH_ALL)
		pkgname = NULL;
	else
		pkgname = argv[0];

	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 privileges to modify the package database");
		return (EX_NOPERM);
	} else if (retcode != EPKG_OK) {
		warnx("Error accessing the package database");
		return (EX_SOFTWARE);
	}

	retcode = pkgdb_open(&db, PKGDB_DEFAULT);
	if (retcode != 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 database. "
		      "It is locked by another process");
		return (EX_TEMPFAIL);
	}

	if (match == MATCH_ALL || argc != 0) {
		if ((it = pkgdb_query(db, pkgname, match)) == NULL) {
			exitcode = EX_IOERR;
			goto cleanup;
		}

		while ((retcode = pkgdb_it_next(it, &pkg, 0)) == EPKG_OK) {
			if (action == LOCK)
				retcode = do_lock(db, pkg);
			else
				retcode = do_unlock(db, pkg);

			if (retcode != EPKG_OK) {
				exitcode = EX_IOERR;
				goto cleanup;
			}
		}
	}

	if (show_locked) 
		retcode = list_locked(db);

	if (retcode != EPKG_END)
		exitcode = EX_IOERR;

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

	pkgdb_release_lock(db, PKGDB_LOCK_EXCLUSIVE);
	pkgdb_close(db);

	return (exitcode);
}
コード例 #24
0
ファイル: clean.c プロジェクト: 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);
}