Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions libpkg/backup_lib.c
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,12 @@ register_backup(struct pkgdb *db, struct pkg *orig, int fd, const char *path)
pkg->www = xstrdup("N/A");
pkg->prefix = xstrdup("/");
pkg->abi = xstrdup(orig->abi);
vec_foreach(orig->shlibs_provided_ignore, i) {
pkg_addshlib_provided_ignore(pkg, orig->shlibs_provided_ignore.d[i]);
}
vec_foreach(orig->shlibs_required_ignore, i) {
pkg_addshlib_required_ignore(pkg, orig->shlibs_required_ignore.d[i]);
}
} else {
free(name);
name = NULL;
Expand Down
44 changes: 43 additions & 1 deletion libpkg/pkg.c
Original file line number Diff line number Diff line change
Expand Up @@ -94,8 +94,12 @@ pkg_free(struct pkg *pkg)
pkg->flags &= ~PKG_LOAD_GROUPS;
vec_free_and_free(&pkg->shlibs_required, free);
pkg->flags &= ~PKG_LOAD_SHLIBS_REQUIRED;
vec_free_and_free(&pkg->shlibs_required_ignore, free);
pkg->flags &= ~PKG_LOAD_SHLIBS_REQUIRED_IGNORE;
vec_free_and_free(&pkg->shlibs_provided, free);
pkg->flags &= ~PKG_LOAD_SHLIBS_REQUIRED;
pkg->flags &= ~PKG_LOAD_SHLIBS_PROVIDED;
vec_free_and_free(&pkg->shlibs_provided_ignore, free);
pkg->flags &= ~PKG_LOAD_SHLIBS_PROVIDED_IGNORE;
vec_free_and_free(&pkg->provides, free);
pkg->flags &= ~PKG_LOAD_PROVIDES;
vec_free_and_free(&pkg->requires, free);
Expand Down Expand Up @@ -953,6 +957,25 @@ pkg_addshlib_required(struct pkg *pkg, const char *name,
return (EPKG_OK);
}

int
pkg_addshlib_required_ignore(struct pkg *pkg, const char *name)
{
assert(pkg != NULL);
assert(name != NULL && name[0] != '\0');

char *owned_name = xstrdup(name);

/* silently ignore duplicates in case of shlibs */
if (charv_insert_sorted(&pkg->shlibs_required_ignore, owned_name) != NULL) {
free(owned_name);
return (EPKG_OK);
}

dbg(3, "added shlib required ignore for %s on %s", pkg->name, owned_name);

return (EPKG_OK);
}

int
pkg_addshlib_provided(struct pkg *pkg, const char *name,
enum pkg_shlib_flags flags)
Expand All @@ -973,6 +996,25 @@ pkg_addshlib_provided(struct pkg *pkg, const char *name,
return (EPKG_OK);
}

int
pkg_addshlib_provided_ignore(struct pkg *pkg, const char *name)
{
assert(pkg != NULL);
assert(name != NULL && name[0] != '\0');

char *owned_name = xstrdup(name);

/* silently ignore duplicates in case of shlibs */
if (charv_insert_sorted(&pkg->shlibs_provided_ignore, owned_name) != NULL) {
free(owned_name);
return (EPKG_OK);
}

dbg(3, "added shlib provided ignore %s for %s", owned_name, pkg->name);

return (EPKG_OK);
}

int
pkg_addconflict(struct pkg *pkg, const char *uniqueid)
{
Expand Down
4 changes: 4 additions & 0 deletions libpkg/pkg.h.in
Original file line number Diff line number Diff line change
Expand Up @@ -312,6 +312,8 @@ typedef enum {
PKG_ATTR_REQUIRES,
PKG_ATTR_CONFLICTS,
PKG_ATTR_NUM_FIELDS, /* end of fields */
PKG_ATTR_SHLIBS_REQUIRED_IGNORE,
PKG_ATTR_SHLIBS_PROVIDED_IGNORE,
} pkg_attr;

typedef enum {
Expand Down Expand Up @@ -1004,6 +1006,8 @@ int pkgdb_delete_annotation(struct pkgdb *db, struct pkg *pkg,
#define PKG_LOAD_PROVIDES (1U << 14)
#define PKG_LOAD_REQUIRES (1U << 15)
#define PKG_LOAD_LUA_SCRIPTS (1u << 16)
#define PKG_LOAD_SHLIBS_REQUIRED_IGNORE (1U << 17)
#define PKG_LOAD_SHLIBS_PROVIDED_IGNORE (1U << 18)
/* Make sure new PKG_LOAD don't conflict with PKG_CONTAINS_* */

/**
Expand Down
9 changes: 7 additions & 2 deletions libpkg/pkg/vec.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,15 +74,20 @@
#define vec_pop(v) \
(v)->d[--(v)->len]

#define vec_remove_and_free(v, cnt, free_func) \
#define vec_remove(v, cnt) \
do { \
free_func((v)->d[cnt]); \
for (size_t _i = cnt; _i < (v)->len - 1; _i++) { \
(v)->d[_i] = (v)->d[_i + 1]; \
} \
(v)->len--; \
} while (0)

#define vec_remove_and_free(v, cnt, free_func) \
do { \
free_func((v)->d[cnt]); \
vec_remove(v, cnt); \
} while (0)

/*
* Remove the element at the given index and replace it with the last
* element in the vec. Does not preserve order, but is O(1).
Expand Down
47 changes: 40 additions & 7 deletions libpkg/pkg_abi.c
Original file line number Diff line number Diff line change
Expand Up @@ -462,7 +462,7 @@ pkg_cleanup_shlibs_required(struct pkg *pkg, charv_t *internal_provided)
const char *lib;

vec_foreach(pkg->shlibs_required, i) {
const char *s = pkg->shlibs_required.d[i];
char *s = pkg->shlibs_required.d[i];
if (charv_search(&pkg->shlibs_provided, s) != NULL ||
charv_search(internal_provided, s) != NULL) {
pkg_debug(2,
Expand All @@ -473,14 +473,26 @@ pkg_cleanup_shlibs_required(struct pkg *pkg, charv_t *internal_provided)
i--;
continue;
}
if (charv_search(&pkg->shlibs_required_ignore, s) != NULL) {
pkg_debug(2,
"remove %s from required shlibs for package %s as it "
"is listed in shlibs_required_ignore.",
s, pkg->name);
vec_remove_and_free(&pkg->shlibs_required, i, free);
i--;
continue;
}
if (match_ucl_lists(s,
pkg_config_get("SHLIB_REQUIRE_IGNORE_GLOB"),
pkg_config_get("SHLIB_REQUIRE_IGNORE_REGEX"))) {
pkg_debug(2,
"remove %s from required shlibs for package %s as it "
"is matched by SHLIB_REQUIRE_IGNORE_GLOB/REGEX.",
s, pkg->name);
vec_remove_and_free(&pkg->shlibs_required, i, free);
vec_remove(&pkg->shlibs_required, i);
if (charv_insert_sorted(&pkg->shlibs_required_ignore, s) != NULL) {
free(s);
}
i--;
continue;
}
Expand Down Expand Up @@ -589,12 +601,12 @@ pkg_analyse_files(struct pkgdb *db __unused, struct pkg *pkg, const char *stage)

if (lstat(fpath, &st) != 0) {
pkg_emit_errno("lstat() failed for", fpath);
free(provided);
continue;
}
/* If the corresponding PATHS option isn't set (i.e. an empty ucl array)
don't do any filtering for backwards compatibility. */
if (ucl_array_size(paths) == 0 || pkg_match_paths_list(paths, file->path)) {
lstat(fpath, &st);
if (S_ISREG(st.st_mode)) {
pkg_addshlib_provided(pkg, provided, provided_flags);
} else {
Expand All @@ -612,26 +624,47 @@ pkg_analyse_files(struct pkgdb *db __unused, struct pkg *pkg, const char *stage)
if (STREQ(maybe_provided.d[i], internal_provided.d[j])) {
pkg_addshlib_provided(pkg, maybe_provided.d[i], PKG_SHLIB_FLAGS_NONE);
vec_remove_and_free(&internal_provided, j, free);
j--;
}
}
vec_remove_and_free(&maybe_provided, i, free);
i--;
}
vec_free(&maybe_provided);
/*
* Do not depend on libraries that a package provides itself
*/
pkg_cleanup_shlibs_required(pkg, &internal_provided);
vec_free_and_free(&internal_provided, free);
while (internal_provided.len > 0) {
char *s = vec_pop(&internal_provided);
if (charv_insert_sorted(&pkg->shlibs_provided_ignore, s) != NULL) {
free(s);
}
}

vec_foreach(pkg->shlibs_provided, i) {
if (match_ucl_lists(pkg->shlibs_provided.d[i],
char *s = pkg->shlibs_provided.d[i];
if (charv_search(&pkg->shlibs_provided_ignore, s) != NULL) {
pkg_debug(2,
"remove %s from provided shlibs for package %s as it "
"is listed in shlibs_provided_ignore.",
s, pkg->name);
vec_remove_and_free(&pkg->shlibs_provided, i, free);
i--;
continue;
}
if (match_ucl_lists(s,
pkg_config_get("SHLIB_PROVIDE_IGNORE_GLOB"),
pkg_config_get("SHLIB_PROVIDE_IGNORE_REGEX"))) {
pkg_debug(2,
"remove %s from provided shlibs for package %s as it "
"is matched by SHLIB_PROVIDE_IGNORE_GLOB/REGEX.",
pkg->shlibs_provided.d[i], pkg->name);
vec_remove_and_free(&pkg->shlibs_provided, i, free);
s, pkg->name);
vec_remove(&pkg->shlibs_provided, i);
if (charv_insert_sorted(&pkg->shlibs_provided_ignore, s) != NULL) {
free(s);
}
i--;
continue;
}
}
Expand Down
10 changes: 10 additions & 0 deletions libpkg/pkg_attributes.c
Original file line number Diff line number Diff line change
Expand Up @@ -320,11 +320,21 @@ pkg_get_element(struct pkg *p, pkg_attr a)
e->stringlist->list = &p->shlibs_required;
e->type = PKG_STRINGLIST;
break;
case PKG_ATTR_SHLIBS_REQUIRED_IGNORE:
e->stringlist = xcalloc(1, sizeof(struct pkg_stringlist *));
e->stringlist->list = &p->shlibs_required_ignore;
e->type = PKG_STRINGLIST;
break;
case PKG_ATTR_SHLIBS_PROVIDED:
e->stringlist = xcalloc(1, sizeof(struct pkg_stringlist *));
e->stringlist->list = &p->shlibs_provided;
e->type = PKG_STRINGLIST;
break;
case PKG_ATTR_SHLIBS_PROVIDED_IGNORE:
e->stringlist = xcalloc(1, sizeof(struct pkg_stringlist *));
e->stringlist->list = &p->shlibs_provided;
e->type = PKG_STRINGLIST;
break;
case PKG_ATTR_PROVIDES:
e->stringlist = xcalloc(1, sizeof(struct pkg_stringlist *));
e->stringlist->list = &p->provides;
Expand Down
40 changes: 40 additions & 0 deletions libpkg/pkg_manifest.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ enum {
MANIFEST_SHLIBS_PROVIDED,
MANIFEST_SHLIBS_REQUIRED,
MANIFEST_USERS,
MANIFEST_SHLIBS_REQUIRED_IGNORE,
MANIFEST_SHLIBS_PROVIDED_IGNORE,
};

#define PKG_MESSAGE_LEGACY 1
Expand Down Expand Up @@ -180,9 +182,15 @@ static const struct pkg_manifest_key {
{ "shlibs_provided", MANIFEST_SHLIBS_PROVIDED,
TYPE_SHIFT(UCL_ARRAY), pkg_array},

{ "shlibs_provided_ignore", MANIFEST_SHLIBS_PROVIDED_IGNORE,
TYPE_SHIFT(UCL_ARRAY), pkg_array},

{ "shlibs_required", MANIFEST_SHLIBS_REQUIRED,
TYPE_SHIFT(UCL_ARRAY), pkg_array},

{ "shlibs_required_ignore", MANIFEST_SHLIBS_REQUIRED_IGNORE,
TYPE_SHIFT(UCL_ARRAY), pkg_array},

{ "sum", offsetof(struct pkg, sum),
TYPE_SHIFT(UCL_STRING), pkg_string},

Expand Down Expand Up @@ -394,12 +402,24 @@ pkg_array(struct pkg *pkg, const ucl_object_t *obj, uint32_t attr)
else
pkg_addshlib_required(pkg, ucl_object_tostring(cur), PKG_SHLIB_FLAGS_NONE);
break;
case MANIFEST_SHLIBS_REQUIRED_IGNORE:
if (cur->type != UCL_STRING)
pkg_emit_error("Skipping malformed required shared library ignore");
else
pkg_addshlib_required_ignore(pkg, ucl_object_tostring(cur));
break;
case MANIFEST_SHLIBS_PROVIDED:
if (cur->type != UCL_STRING)
pkg_emit_error("Skipping malformed provided shared library");
else
pkg_addshlib_provided(pkg, ucl_object_tostring(cur), PKG_SHLIB_FLAGS_NONE);
break;
case MANIFEST_SHLIBS_PROVIDED_IGNORE:
if (cur->type != UCL_STRING)
pkg_emit_error("Skipping malformed provided shared library ignore");
else
pkg_addshlib_provided_ignore(pkg, ucl_object_tostring(cur));
break;
case MANIFEST_CONFLICTS:
if (cur->type != UCL_STRING)
pkg_emit_error("Skipping malformed conflict name");
Expand Down Expand Up @@ -1075,6 +1095,16 @@ pkg_emit_object(struct pkg *pkg, short flags)
if (seq)
ucl_object_insert_key(top, seq, "shlibs_required", 15, false);

dbg(4, "Emitting shibs_required_ignore");
seq = NULL;
vec_foreach(pkg->shlibs_required_ignore, i) {
if (seq == NULL)
seq = ucl_object_typed_new(UCL_ARRAY);
ucl_array_append(seq, ucl_object_fromstring(pkg->shlibs_required_ignore.d[i]));
}
if (seq)
ucl_object_insert_key(top, seq, "shlibs_required_ignore", 22, false);

dbg(4, "Emitting shlibs_provided");
seq = NULL;
vec_foreach(pkg->shlibs_provided, i) {
Expand All @@ -1085,6 +1115,16 @@ pkg_emit_object(struct pkg *pkg, short flags)
if (seq)
ucl_object_insert_key(top, seq, "shlibs_provided", 15, false);

dbg(4, "Emitting shlibs_provided_ignore");
seq = NULL;
vec_foreach(pkg->shlibs_provided_ignore, i) {
if (seq == NULL)
seq = ucl_object_typed_new(UCL_ARRAY);
ucl_array_append(seq, ucl_object_fromstring(pkg->shlibs_provided_ignore.d[i]));
}
if (seq)
ucl_object_insert_key(top, seq, "shlibs_provided_ignore", 22, false);

dbg(4, "Emitting conflicts");
seq = NULL;
while (pkg_conflicts(pkg, &conflict) == EPKG_OK) {
Expand Down
Loading
Loading