示例#1
0
int
exec_search(int argc, char **argv)
{
	const char	*pattern = NULL;
	const char	*reponame = NULL;
	int		 ret = EPKG_OK, ch;
	int		 flags;
	uint64_t	 opt = 0;
	match_t		 match = MATCH_REGEX;
	pkgdb_field	 search = FIELD_NONE;
	pkgdb_field	 label = FIELD_NONE;
	struct pkgdb	*db = NULL;
	struct pkgdb_it	*it = NULL;
	struct pkg	*pkg = NULL;
	bool		 atleastone = false;
	bool		 old_quiet;

	struct option longopts[] = {
		{ "case-sensitive",	no_argument,		NULL,	'C' },
		{ "comment",		no_argument,		NULL,	'c' },
		{ "description",	no_argument,		NULL,	'D' },
		{ "depends-on",		no_argument,		NULL,	'd' },
		{ "exact",		no_argument,		NULL,	'e' },
		{ "full",		no_argument,		NULL,	'f' },
		{ "glob",		no_argument,		NULL,	'g' },
		{ "case-insensitive",	no_argument,		NULL,	'i' },
		{ "label",		required_argument,	NULL,	'L' },
		{ "origins",		no_argument,		NULL,	'o' },
		{ "prefix",		no_argument,		NULL,	'p' },
		{ "quiet",		no_argument,		NULL,	'q' },
		{ "query-modifier",	required_argument,	NULL,	'Q' },
		{ "repository",		required_argument,	NULL,	'r' },
		{ "raw",		no_argument,		NULL,	'R' },
		{ "search",		required_argument,	NULL,	'S' },
		{ "size",		no_argument,		NULL,	's' },
		{ "no-repo-update",	no_argument,		NULL,	'U' },
		{ "regex",		no_argument,		NULL,	'x' },
		{ "raw-format",		required_argument,	NULL, 	1   },
		{ NULL,			0,			NULL,	0   },
	};

	while ((ch = getopt_long(argc, argv, "+CcDdefgiL:opqQ:r:RS:sUx", longopts, NULL)) != -1) {
		switch (ch) {
		case 'C':
			pkgdb_set_case_sensitivity(true);
			break;
		case 'c':	/* Same as -S comment */
			search = search_label_opt("comment");
			break;
		case 'D':	/* Same as -S description */
			search = search_label_opt("description");
			break;
		case 'd':	/* Same as -Q depends-on  */
			opt |= modifier_opt("depends-on");
			break;
		case 'e':
			match = MATCH_EXACT;
			break;
		case 'f':	/* Same as -Q full */
			opt |= modifier_opt("full");
			break;
		case 'g':
			match = MATCH_GLOB;
			break;
		case 'i':
			pkgdb_set_case_sensitivity(false);
			break;
		case 'L':
			label = search_label_opt(optarg);
			break;
		case 'o':	/* Same as -L origin */
			label = search_label_opt("origin");
			break;
		case 'p':	/* Same as -Q prefix */
			opt |= modifier_opt("prefix");
			break;
		case 'q':
			quiet = true;
			break;
		case 'Q':
			opt |= modifier_opt(optarg);
			break;
		case 'r':
			reponame = optarg;
			break;
		case 'R':
			opt = INFO_RAW;
			break;
		case 'S':
			search = search_label_opt(optarg);
			break;
		case 's':	/* Same as -Q size */
			opt |= modifier_opt("size");
			break;
		case 'U':
			auto_update = false;
			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_search();
			return (EX_USAGE);
		}
	}

	argc -= optind;
	argv += optind;

	if (argc != 1) {
		usage_search();
		return (EX_USAGE);
	}

	pattern = argv[0];
	if (pattern[0] == '\0') {
		fprintf(stderr, "Pattern must not be empty.\n");
		return (EX_USAGE);
	}
	if (search == FIELD_NONE) {
		if (strchr(pattern, '/') != NULL)
			search = FIELD_ORIGIN;
		else
			search = FIELD_NAMEVER; /* Default search */
	}
	if (label == FIELD_NONE)
		label = search; /* By default, show what was searched  */

	switch(label) {
	case FIELD_NONE:
		break;		/* should never happen */
	case FIELD_ORIGIN:
		opt |= INFO_TAG_ORIGIN|INFO_COMMENT;
		break;
	case FIELD_NAME:
		opt |= INFO_TAG_NAME|INFO_COMMENT;
		break;
	case FIELD_NAMEVER:
		opt |= INFO_TAG_NAMEVER|INFO_COMMENT;
		break;
	case FIELD_COMMENT:
		opt |= INFO_TAG_NAMEVER|INFO_COMMENT;
		break;
	case FIELD_DESC:
		opt |= INFO_TAG_NAMEVER|INFO_DESCR;
		break;
	}

	if (quiet) {
		opt = INFO_TAG_NAMEVER;
		quiet = false;
	}

	ret = pkgdb_access(PKGDB_MODE_READ, PKGDB_DB_REPO);
	switch(ret) {
	case EPKG_ENOACCESS:
		warnx("Insufficient privileges to query the package database");
		return (EX_NOPERM);
	case EPKG_ENODB:
		if (!auto_update) {
			warnx("Unable to open remote repository catalogues. Try running '%s update' first.", getprogname());
			return (EX_IOERR);
		}
		break;
	case EPKG_OK:
		break;
	default:
		return (EX_IOERR);
	}

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

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

	if ((it = pkgdb_repo_search(db, pattern, match, search, search,
	    reponame)) == NULL) {
		pkgdb_close(db);
		return (EX_IOERR);
	}

	if (opt & INFO_RAW) {
		if ((opt & (INFO_RAW_JSON|INFO_RAW_JSON_COMPACT)) == 0)
			opt |= INFO_RAW_YAML;
	}

	flags = info_flags(opt, true);
	while ((ret = pkgdb_it_next(it, &pkg, flags)) == EPKG_OK) {
		print_info(pkg, opt);
		atleastone = true;
	}

	pkg_free(pkg);
	pkgdb_it_free(it);
	pkgdb_close(db);

	if (!atleastone)
		ret = EPKG_FATAL;

	return ((ret == EPKG_OK || ret == EPKG_END) ? EX_OK : EX_SOFTWARE);
}
示例#2
0
文件: search.c 项目: aklv/pkgng
int
exec_search(int argc, char **argv)
{
	const char *pattern = NULL;
	const char *reponame = NULL;
	int ret = EPKG_OK, ch;
	int flags;
	unsigned int opt = 0;
	match_t match = MATCH_REGEX;
	pkgdb_field search = FIELD_NONE;
	pkgdb_field label = FIELD_NONE;
	struct pkgdb *db = NULL;
	struct pkgdb_it *it = NULL;
	struct pkg *pkg = NULL;
	bool atleastone = false;

	while ((ch = getopt(argc, argv, "cDdefgiL:opqQ:r:S:sx")) != -1) {
		switch (ch) {
		case 'c':	/* Same as -S comment */
			search = search_label_opt("comment");
			break;
		case 'D':	/* Same as -S description */
			search = search_label_opt("description");
			break;
		case 'd':	/* Same as -Q depends-on  */
			opt |= modifier_opt("depends-on");
			break;
		case 'e':
			match = MATCH_EXACT;
			break;
		case 'f':	/* Same as -Q full */
			opt |= modifier_opt("full");
			break;
		case 'g':
			match = MATCH_GLOB;
			break;
		case 'i':
			pkgdb_set_case_sensitivity(false);
			break;
		case 'L':
			label = search_label_opt(optarg);
			break;
		case 'o':	/* Same as -L origin */
			label = search_label_opt("origin");
			break;
		case 'p':	/* Same as -Q prefix */
			opt |= modifier_opt("prefix");
			break;
		case 'q':
			quiet = true;
			break;
		case 'Q':
			opt |= modifier_opt(optarg);
			break;
		case 'r':
			reponame = optarg;
			break;
		case 'S':
			search = search_label_opt(optarg);
			break;
		case 's':	/* Same as -Q size */
			opt |= modifier_opt("size");
			break;
		case 'x':
			match = MATCH_REGEX;
			break;
		default:
			usage_search();
			return (EX_USAGE);
		}
	}

	argc -= optind;
	argv += optind;

	if (argc != 1) {
		usage_search();
		return (EX_USAGE);
	}

	pattern = argv[0];
	if (pattern[0] == '\0') {
		fprintf(stderr, "Pattern must not be empty!\n");
		return (EX_USAGE);
	}
	if (search == FIELD_NONE) {
		if (strchr(pattern, '/') != NULL)
			search = FIELD_ORIGIN;
		else
			search = FIELD_NAMEVER; /* Default search */
	}
	if (label == FIELD_NONE)
		label = search; /* By default, show what was searched  */

	switch(label) {
	case FIELD_NONE:
		break;		/* should never happen */
	case FIELD_ORIGIN:
		opt |= INFO_TAG_ORIGIN;
		break;
	case FIELD_NAME:
		opt |= INFO_TAG_NAME;
		break;
	case FIELD_NAMEVER:
		opt |= INFO_TAG_NAMEVER;
		break;
	case FIELD_COMMENT:
		opt |= INFO_TAG_NAMEVER|INFO_COMMENT;
		break;
	case FIELD_DESC:
		opt |= INFO_TAG_NAMEVER|INFO_DESCR;
		break;
	}

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

	if ((it = pkgdb_search(db, pattern, match, search, search,
	    reponame)) == NULL) {
		pkgdb_close(db);
		return (EX_IOERR);
	}

	flags = info_flags(opt);
	while ((ret = pkgdb_it_next(it, &pkg, flags)) == EPKG_OK) {
		print_info(pkg, opt);
		atleastone = true;
	}

	pkg_free(pkg);
	pkgdb_it_free(it);
	pkgdb_close(db);

	if (!atleastone)
		ret = EPKG_FATAL;

	return ((ret == EPKG_OK || ret == EPKG_END) ? EX_OK : EX_SOFTWARE);
}