static int shlib_list_add(kh_shlib_t **shlib_list, const char *dir, const char *shlib_file) { struct shlib *sl; size_t path_len, dir_len; /* If shlib_file is already in the shlib_list table, don't try * and add it again */ if (kh_contains(shlib, *shlib_list, shlib_file)) return (EPKG_OK); path_len = strlen(dir) + strlen(shlib_file) + 2; sl = xcalloc(1, sizeof(struct shlib) + path_len); strlcpy(sl->path, dir, path_len); dir_len = strlcat(sl->path, "/", path_len); strlcat(sl->path, shlib_file, path_len); sl->name = sl->path + dir_len; kh_add(shlib, *shlib_list, sl, sl->name, free); return (EPKG_OK); }
int pkg_analyse_files(struct pkgdb *db, struct pkg *pkg, const char *stage) { struct pkg_file *file = NULL; char *sh; khint_t k; int ret = EPKG_OK; char fpath[MAXPATHLEN]; const char *lib; bool failures = false; if (kh_count(pkg->shlibs_required) != 0) pkg_list_free(pkg, PKG_SHLIBS_REQUIRED); if (kh_count(pkg->shlibs_provided) != 0) pkg_list_free(pkg, PKG_SHLIBS_PROVIDED); if (elf_version(EV_CURRENT) == EV_NONE) return (EPKG_FATAL); shlib_list_init(); if (stage != NULL && pkg_object_bool(pkg_config_get("ALLOW_BASE_SHLIBS"))) { /* Do not check the return */ shlib_list_from_stage(stage); } ret = shlib_list_from_elf_hints(_PATH_ELF_HINTS); if (ret != EPKG_OK) goto cleanup; /* Assume no architecture dependence, for contradiction */ if (developer_mode) pkg->flags &= ~(PKG_CONTAINS_ELF_OBJECTS | PKG_CONTAINS_STATIC_LIBS | PKG_CONTAINS_H_OR_LA); while (pkg_files(pkg, &file) == EPKG_OK) { if (stage != NULL) snprintf(fpath, sizeof(fpath), "%s/%s", stage, file->path); else strlcpy(fpath, file->path, sizeof(fpath)); ret = analyse_elf(pkg, fpath); if (developer_mode) { if (ret != EPKG_OK && ret != EPKG_END) { failures = true; continue; } analyse_fpath(pkg, fpath); } } /* * Do not depend on libraries that a package provides itself */ kh_each_value(pkg->shlibs_required, sh, { if (kh_contains(strings, pkg->shlibs_provided, sh)) { pkg_debug(2, "remove %s from required shlibs as the " "package %s provides this library itself", sh, pkg->name); k = kh_get_strings(pkg->shlibs_required, sh); kh_del_strings(pkg->shlibs_required, k); continue; } file = NULL; while (pkg_files(pkg, &file) == EPKG_OK) { if ((lib = strstr(file->path, sh)) != NULL && strlen(lib) == strlen(sh) && lib[-1] == '/') { pkg_debug(2, "remove %s from required shlibs as " "the package %s provides this library itself", sh, pkg->name); k = kh_get_strings(pkg->shlibs_required, sh); kh_del_strings(pkg->shlibs_required, k); break; } } });