Example #1
0
File: pkg_elf.c Project: namore/pkg
static int
test_depends(void *actdata, struct pkg *pkg, const char *fpath,
	     const char *name, bool is_shlib)
{
	struct pkgdb *db = actdata;
	struct pkg_dep *dep = NULL;
	struct pkgdb_it *it = NULL;
	struct pkg *d;
	const char *deporigin, *depname, *depversion;
	const char *pkgname, *pkgversion;
	bool deplocked;
	char pathbuf[MAXPATHLEN];

	assert(db != NULL);

	switch(filter_system_shlibs(name, pathbuf, sizeof(pathbuf))) {
	case EPKG_OK:		/* A non-system library */
		break;
	case EPKG_END:		/* A system library */
		return (EPKG_OK);
	default:
		/* Ignore link resolution errors if we're analysing a
		   shared library. */
		if (is_shlib)
			return (EPKG_OK);

		pkg_get(pkg, PKG_NAME, &pkgname, PKG_VERSION, &pkgversion);
		warnx("(%s-%s) %s - shared library %s not found",
		      pkgname, pkgversion, fpath, name);
		return (EPKG_FATAL);
	}

	pkg_addshlib_required(pkg, name);

	if ((it = pkgdb_query_which(db, pathbuf, false)) == NULL)
		return (EPKG_OK);

	d = NULL;
	if (pkgdb_it_next(it, &d, PKG_LOAD_BASIC) == EPKG_OK) {
		pkg_get(d, PKG_ORIGIN,  &deporigin,
			   PKG_NAME,    &depname,
			   PKG_VERSION, &depversion,
			   PKG_LOCKED,  &deplocked);

		dep = pkg_dep_lookup(pkg, deporigin);

		if (dep == NULL) {
			pkg_debug(1, "Autodeps: adding unlisted depends (%s): %s-%s",
			    pathbuf, depname, depversion);
			pkg_adddep(pkg, depname, deporigin, depversion,
			    deplocked);
		}
		pkg_free(d);
	}

	pkgdb_it_free(it);
	return (EPKG_OK);
}
Example #2
0
int
exec_which(int argc, char **argv)
{
	struct pkgdb *db;
	struct pkgdb_it *it;
	struct pkg *pkg = NULL;
	char pathabs[MAXPATHLEN + 1];
	int ret = EPKG_OK, retcode = EPKG_OK;
	const char *name, *version;

	if (argc != 2) {
		usage_which();
		return (EX_USAGE);
	}

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

	absolutepath(argv[1], pathabs, sizeof(pathabs));

	if ((it = pkgdb_query_which(db, pathabs)) == NULL) {
		return (EX_IOERR);
	}

	if (( ret = pkgdb_it_next(it, &pkg, PKG_LOAD_BASIC)) == EPKG_OK) {
		retcode = EPKG_OK;
		pkg_get(pkg, PKG_NAME, &name, PKG_VERSION, &version);
		printf("%s was installed by package %s-%s\n", pathabs, name, version);
	} else if (ret != EPKG_END) {
		retcode = EPKG_WARN;
	} else {
		printf("%s was not found in the database\n", pathabs);
		retcode = EPKG_WARN;
	}
		
	pkg_free(pkg);
	pkgdb_it_free(it);

	pkgdb_close(db);
	return (retcode);
}
Example #3
0
File: pkg_elf.c Project: flz/pkgng
static int
analyse_elf(struct pkgdb *db, struct pkg *pkg, const char *fpath)
{
	struct pkg **deps;
	struct pkg *p = NULL;
	struct pkgdb_it *it = NULL;
	Elf *e;
	Elf_Scn *scn = NULL;
	GElf_Shdr shdr;
	Elf_Data *data;
	GElf_Dyn *dyn, dyn_mem;
	size_t numdyn;
	size_t dynidx;
	void *handle;
	Link_map *map;
	char *name;
	bool found=false;

	int fd, i;

	if ((fd = open(fpath, O_RDONLY, 0)) < 0)
		return (EPKG_FATAL);

	if (( e = elf_begin(fd, ELF_C_READ, NULL)) == NULL)
		return (EPKG_FATAL);

	if (elf_kind(e) != ELF_K_ELF)
		return (EPKG_FATAL);

	while (( scn = elf_nextscn(e, scn)) != NULL) {
		if (gelf_getshdr(scn, &shdr) != &shdr)
			return (EPKG_FATAL);

		if (shdr.sh_type == SHT_DYNAMIC)
			break;
	}

	data = elf_getdata(scn, NULL);
	numdyn = shdr.sh_size / shdr.sh_entsize;

	for (dynidx = 0; dynidx < numdyn; dynidx++) {
		if ((dyn = gelf_getdyn(data, dynidx, &dyn_mem)) == NULL)
			return (EPKG_FATAL);

		if (dyn->d_tag != DT_NEEDED)
			continue;

		name = elf_strptr(e, shdr.sh_link, dyn->d_un.d_val);
		handle = dlopen(name, RTLD_LAZY);

		if (handle != NULL) {
			dlinfo(handle, RTLD_DI_LINKMAP, &map);
			if ((it = pkgdb_query_which(db, map->l_name)) == NULL)
				return (EPKG_FATAL);

			if (pkgdb_it_next(it, &p, PKG_LOAD_BASIC) == EPKG_OK) {
				found = false;
				if (( deps = pkg_deps(pkg) ) != NULL) {
					for (i = 0; deps[i]; i++) {
						if (strcmp(pkg_get(deps[i], PKG_ORIGIN), pkg_get(p, PKG_ORIGIN)) == 0)
							found = true;
					}
				}
				if (!found) {
					warnx("adding forgotten depends (%s): %s-%s", map->l_name, pkg_get(p, PKG_NAME), pkg_get(p, PKG_VERSION));
					pkg_adddep(pkg, pkg_get(p, PKG_NAME), pkg_get(p, PKG_ORIGIN), pkg_get(p, PKG_VERSION));
				}
			}
			dlclose(handle);
		}
		pkgdb_it_free(it);
	}
	pkg_free(p);
	close(fd);

	return (EPKG_OK);

}
Example #4
0
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);
}
Example #5
0
File: which.c Project: afb/pkgng
int
exec_which(int argc, char **argv)
{
	struct pkgdb *db = NULL;
	struct pkgdb_it *it = NULL;
	struct pkg *pkg = NULL;
	char pathabs[MAXPATHLEN + 1];
	int ret = EPKG_OK, retcode = EX_OK;
	const char *name, *version, *origin;
	int ch;
	bool orig = false;
	bool glob = false;

	while ((ch = getopt(argc, argv, "qgo")) != -1) {
		switch (ch) {
		case 'q':
			quiet = true;
			break;
		case 'g':
			glob = true;
			break;
		case 'o':
			orig = 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) {
		pkgdb_close(db);
		return (EX_IOERR);
	}

	if (!glob)
		absolutepath(argv[0], pathabs, sizeof(pathabs));
	else
		strlcpy(pathabs, argv[0], sizeof(pathabs));

	if ((it = pkgdb_query_which(db, pathabs, glob)) == NULL)
		return (EX_IOERR);

	while ((ret = pkgdb_it_next(it, &pkg, PKG_LOAD_BASIC)) == EPKG_OK) {
		pkg_get(pkg, PKG_NAME, &name, PKG_VERSION, &version, PKG_ORIGIN, &origin);
		if (quiet && orig)
			printf("%s\n", origin);
		else if (quiet && !orig)
			printf("%s-%s\n", name, version);
		else if (!quiet && orig)
			printf("%s was installed by package %s\n", pathabs, origin);
		else if (!quiet && !orig)
			printf("%s was installed by package %s-%s\n", pathabs, name, version);
		if (!glob)
			break;
	}

	if (ret != EPKG_END) {
		retcode = EX_SOFTWARE;
	}
	else if (!glob) {
		if (!quiet)
			printf("%s was not found in the database\n", pathabs);
		retcode = EX_DATAERR;
	}
		
	pkg_free(pkg);
	pkgdb_it_free(it);

	pkgdb_close(db);
	return (retcode);
}
Example #6
0
static int
test_depends(void *actdata, struct pkg *pkg, const char *fpath,
	     const char *name, bool is_shlib)
{
	struct pkgdb *db = actdata;
	struct pkg_dep *dep = NULL;
	struct pkgdb_it *it = NULL;
	struct pkg *d;
	const char *deporigin, *depname, *depversion;
	bool deplocked;
	char pathbuf[MAXPATHLEN];
	bool found;
	bool shlibs = false;

	assert(db != NULL);

	pkg_config_bool(PKG_CONFIG_SHLIBS, &shlibs);

	switch(filter_system_shlibs(name, pathbuf, sizeof(pathbuf))) {
	case EPKG_OK:		/* A non-system library */
		break;
	case EPKG_END:		/* A system library */
		return (EPKG_OK);
	default:
		/* Ignore link resolution errors if we're analysing a
		   shared library. */
		if (is_shlib)
			return (EPKG_OK);

		warnx("(%s-%s) %s - shared library %s not found",
		      pkg_name(pkg), pkg_version(pkg), fpath, name);
		return (EPKG_FATAL);
	}

	if (shlibs)
		pkg_addshlib_required(pkg, name);

	if ((it = pkgdb_query_which(db, pathbuf)) == NULL)
		return (EPKG_OK);

	d = NULL;
	if (pkgdb_it_next(it, &d, PKG_LOAD_BASIC) == EPKG_OK) {
		found = false;
		pkg_get(d, PKG_ORIGIN,  &deporigin,
			   PKG_NAME,    &depname,
			   PKG_VERSION, &depversion,
			   PKG_LOCKED,  &deplocked);

		dep = NULL;
		found = false;
		while (pkg_deps(pkg, &dep) == EPKG_OK) {
			if (strcmp(pkg_dep_origin(dep), deporigin) == 0) {
				found = true;
				break;
			}
		}
		if (!found) {
			pkg_emit_error("adding forgotten depends (%s): %s-%s",
			    pathbuf, depname, depversion);
			pkg_adddep(pkg, depname, deporigin, depversion,
			    deplocked);
		}
		pkg_free(d);
	}

	pkgdb_it_free(it);
	return (EPKG_OK);
}
Example #7
0
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);
}