コード例 #1
0
ファイル: qsearch.c プロジェクト: radhermit/portage-utils
int qsearch_main(int argc, char **argv)
{
	FILE *fp;
	char *ebuild = NULL;
	char last[126] = "";
	char *p, *q, *str;
	char *search_me = NULL;
	char show_homepage = 0, show_name_only = 0;
	char search_desc = 0, search_all = 0, search_name = 1, search_cache = CACHE_EBUILD;
	const char *search_vars[] = { "DESCRIPTION=", "HOMEPAGE=" };
	size_t search_len, ebuild_len;
	int i, idx=0;

	DBG("argc=%d argv[0]=%s argv[1]=%s",
	    argc, argv[0], argc > 1 ? argv[1] : "NULL?");

	while ((i = GETOPT_LONG(QSEARCH, qsearch, "")) != -1) {
		switch (i) {
		COMMON_GETOPTS_CASES(qsearch)
		case 'a': search_all = 1; break;
		case 'c': search_cache = CACHE_METADATA; break;
		case 'e': search_cache = CACHE_EBUILD; break;
		case 's': search_desc = 0; search_name = 1; break;
		case 'S': search_desc = 1; search_name = 0; break;
		case 'N': show_name_only = 1; break;
		case 'H': show_homepage = 1, idx = 1; break;
		}
	}

	if (search_all) {
		search_desc = 1;
		search_name = 0;
	} else {
		if (argc == optind)
			qsearch_usage(EXIT_FAILURE);
		search_me = argv[optind];
	}
#ifdef TESTING
	/* FIXME: hardcoded */
	if ((search_cache == CACHE_EBUILD) && (access("/usr/portage/.qsearch.x", R_OK) == 0)) {
		if ((fp = fopen("/usr/portage/.qsearch.x", "r")) != NULL) {
			search_len = strlen(search_me);
			while (fgets(buf, sizeof(buf), fp) != NULL) {
				if (strlen(buf) <= search_len)
					continue;
				/* add regexp, color highlighting and basename checks */
				if (strncmp(buf, search_me, search_len) == 0) {
					fputs(buf, stdout);
				}
			}
			fclose(fp);
			return 0;
		}
	}
#endif
	last[0] = 0;
	fp = fopen(initialize_flat(search_cache, false), "r");
	if (!fp)
		return 1;

	int portdir_fd = open(portdir, O_RDONLY|O_CLOEXEC|O_PATH);
	if (portdir_fd < 0)
		errp("open(%s) failed", portdir);

	q = NULL; /* Silence a gcc warning. */
	search_len = strlen(search_vars[idx]);

	while (getline(&ebuild, &ebuild_len, fp) != -1) {
		if ((p = strchr(ebuild, '\n')) != NULL)
			*p = 0;
		if (!ebuild[0])
			continue;

		switch (search_cache) {

		case CACHE_METADATA: {
			portage_cache *pcache;
			if ((pcache = cache_read_file(ebuild)) != NULL) {
				if (strcmp(pcache->atom->PN, last) != 0) {
					strncpy(last, pcache->atom->PN, sizeof(last));
					if ((rematch(search_me, (search_desc ? pcache->DESCRIPTION : ebuild), REG_EXTENDED | REG_ICASE) == 0) || search_all)
						printf("%s%s/%s%s%s %s\n", BOLD, pcache->atom->CATEGORY, BLUE,
						       pcache->atom->PN, NORM,
						       (show_name_only ? "" :
						        (show_homepage ? pcache->HOMEPAGE : pcache->DESCRIPTION)));
				}
				cache_free(pcache);
			} else {
				if (!reinitialize)
					warnf("(cache update pending) %s", ebuild);
				reinitialize = 1;
			}
			break;
		}

		case CACHE_EBUILD: {
			FILE *ebuildfp;
			str = xstrdup(ebuild);
			p = dirname(str);

			if (strcmp(p, last) != 0) {
				bool show_it = false;
				strncpy(last, p, sizeof(last));
				if (search_name) {
					if (rematch(search_me, basename(last), REG_EXTENDED | REG_ICASE) != 0) {
						goto no_cache_ebuild_match;
					} else {
						q = NULL;
						show_it = true;
					}
				}

				int fd = openat(portdir_fd, ebuild, O_RDONLY|O_CLOEXEC);
				if (fd != -1) {
					ebuildfp = fdopen(fd, "r");
					if (ebuildfp == NULL) {
						close(fd);
						continue;
					}
				} else {
					if (!reinitialize)
						warnfp("(cache update pending) %s", ebuild);
					reinitialize = 1;
					goto no_cache_ebuild_match;
				}

				char *buf = NULL;
				size_t buflen;
				while (getline(&buf, &buflen, ebuildfp) != -1) {
					if (strlen(buf) <= search_len)
						continue;
					if (strncmp(buf, search_vars[idx], search_len) != 0)
						continue;
					if ((q = strrchr(buf, '"')) != NULL)
						*q = 0;
					if (strlen(buf) <= search_len)
						break;
					q = buf + search_len + 1;
					if (!search_all && !search_name && rematch(search_me, q, REG_EXTENDED | REG_ICASE) != 0)
						break;
					show_it = true;
					break;
				}

				if (show_it) {
					printf("%s%s/%s%s%s %s\n",
						BOLD, dirname(p), BLUE, basename(p), NORM,
						(show_name_only ? "" : q ? : "<no DESCRIPTION found>"));
				}

				free(buf);
				fclose(ebuildfp);
			}
no_cache_ebuild_match:
			free(str);

			break;
		} /* case CACHE_EBUILD */
		} /* switch (search_cache) */
	}
コード例 #2
0
ファイル: q.c プロジェクト: gentoo/portage-utils
int q_main(int argc, char **argv)
{
	int i, install;
	const char *p;
	APPLET func;

	if (argc == 0)
		return 1;

	argv0 = p = basename(argv[0]);

	if ((func = lookup_applet(p)) == NULL)
		return 1;
	if (strcmp("q", p) != 0)
		return (func)(argc, argv);

	if (argc == 1)
		q_usage(EXIT_FAILURE);

	install = 0;

	while ((i = GETOPT_LONG(Q, q, "+")) != -1) {
		switch (i) {
		COMMON_GETOPTS_CASES(q)
		case 'M': modpath = optarg; break;
		case 'i': install = 1; break;
		}
	}

	if (install) {
		char buf[_Q_PATH_MAX];
		const char *prog, *dir;
		ssize_t rret;
		int fd, ret;

		if (!quiet)
			printf("Installing symlinks:\n");

#if defined(__MACH__)
		rret = proc_pidpath(getpid(), buf, sizeof(buf));
		if (rret != -1)
			rret = strlen(buf);
#elif defined(__sun) && defined(__SVR4)
		prog = getexecname();
		rret = strlen(prog);
		if ((size_t)rret > sizeof(buf) - 1) {
			rret = -1;
		} else {
			snprintf(buf, sizeof(buf), "%s", prog);
		}
#else
		rret = readlink("/proc/self/exe", buf, sizeof(buf) - 1);
#endif
		if (rret == -1) {
			warnfp("haha no symlink love for you");
			return 1;
		}
		buf[rret] = '\0';

		prog = basename(buf);
		dir = dirname(buf);
		fd = open(dir, O_RDONLY|O_CLOEXEC|O_PATH);
		if (fd < 0) {
			warnfp("open(%s) failed", dir);
			return 1;
		}

		ret = 0;
		for (i = 1; applets[i].desc; ++i) {
			int r = symlinkat(prog, fd, applets[i].name);
			if (!quiet)
				printf(" %s ...\t[%s]\n",
						applets[i].name, r ? strerror(errno) : "OK");
			if (r && errno != EEXIST)
				ret = 1;
		}

		close(fd);

		return ret;
	}

	if (argc == optind)
		q_usage(EXIT_FAILURE);
	if ((func = lookup_applet(argv[optind])) == NULL)
		return 1;

	/* In case of "q --option ... appletname ...", remove appletname from the
	 * applet's args. */
	if (optind > 1) {
		argv[0] = argv[optind];
		for (i = optind; i < argc; ++i)
			argv[i] = argv[i + 1];
	} else
		++argv;

	optind = 0; /* reset so the applets can call getopt */

	return (func)(argc - 1, argv);
}