Radish alpha
H
rad:z3QDZAW2FAfuLvihrhiyDC9fAD8G9
HardenedBSD Package Manager
Radicle
Git
API: convert all abused hash table into stringlist
Baptiste Daroussin committed 4 years ago
commit 9b49b83ce2485c48e2b338c99e9796dc31821de6
parent a37bc66
18 files changed +311 -367
modified libpkg/libpkg.ver
@@ -61,7 +61,6 @@ global:
	pkg_get_dbdirfd;
	pkg_get_dir;
	pkg_get_file;
-
	pkg_groups;
	pkg_has_dir;
	pkg_has_file;
	pkg_has_message;
@@ -129,7 +128,6 @@ global:
	pkg_plugins_init;
	pkg_plugins_shutdown;
	pkg_printf;
-
	pkg_provides;
	pkg_rdeps;
	pkg_recompute;
	pkg_repo_cached_name;
@@ -146,13 +144,10 @@ global:
	pkg_repos;
	pkg_repos_activated_count;
	pkg_repos_total_count;
-
	pkg_requires;
	pkg_script_get;
	pkg_set2;
	pkg_set_debug_level;
	pkg_set_rootdir;
-
	pkg_shlibs_provided;
-
	pkg_shlibs_required;
	pkg_shutdown;
	pkg_snprintf;
	pkg_solve_dimacs_export;
@@ -168,7 +163,6 @@ global:
	pkg_try_installed;
	pkg_type;
	pkg_update;
-
	pkg_users;
	pkg_utils_count_spaces;
	pkg_utils_tokenize;
	pkg_vasprintf;
modified libpkg/pkg.c
@@ -94,12 +94,19 @@ pkg_free(struct pkg *pkg)
	pkg_list_free(pkg, PKG_FILES);
	pkg_list_free(pkg, PKG_DIRS);
	pkg_list_free(pkg, PKG_OPTIONS);
-
	pkg_list_free(pkg, PKG_USERS);
-
	pkg_list_free(pkg, PKG_GROUPS);
-
	pkg_list_free(pkg, PKG_SHLIBS_REQUIRED);
-
	pkg_list_free(pkg, PKG_SHLIBS_PROVIDED);
-
	pkg_list_free(pkg, PKG_PROVIDES);
-
	pkg_list_free(pkg, PKG_REQUIRES);
+

+
	tll_free_and_free(pkg->users, free);
+
	pkg->flags &= ~PKG_LOAD_USERS;
+
	tll_free_and_free(pkg->groups, free);
+
	pkg->flags &= ~PKG_LOAD_GROUPS;
+
	tll_free_and_free(pkg->shlibs_required, free);
+
	pkg->flags &= ~PKG_LOAD_SHLIBS_REQUIRED;
+
	tll_free_and_free(pkg->shlibs_provided, free);
+
	pkg->flags &= ~PKG_LOAD_SHLIBS_REQUIRED;
+
	tll_free_and_free(pkg->provides, free);
+
	pkg->flags &= ~PKG_LOAD_PROVIDES;
+
	tll_free_and_free(pkg->requires, free);
+
	pkg->flags &= ~PKG_LOAD_REQUIRES;
	tll_free_and_free(pkg->categories, free);
	pkg->flags &= ~PKG_LOAD_CATEGORIES;
	tll_free_and_free(pkg->licenses, free);
@@ -378,44 +385,24 @@ pkg_each(options, struct pkg_option, options);
pkg_each(conflicts, struct pkg_conflict, conflicts);
pkg_each(config_files, struct pkg_config_file, config_files);

-
#define pkg_each_string_hash(name)                   \
-
int                                                  \
-
pkg_##name(const struct pkg *pkg, char **c) {        \
-
	if ((*c) == NULL)                            \
-
		pkghash_loopinit(pkg->name);         \
-
	pkghash_entry *e = pkghash_inext(pkg->name); \
-
	if (e == NULL) {                             \
-
		(*c) = NULL;                         \
-
		return (EPKG_END);                   \
-
	}                                            \
-
	(*c) = e->key;                               \
-
	return (EPKG_OK);                            \
-
}
-

-
pkg_each_string_hash(requires);
-
pkg_each_string_hash(provides);
-
pkg_each_string_hash(shlibs_required);
-
pkg_each_string_hash(shlibs_provided);
-
pkg_each_string_hash(users);
-
pkg_each_string_hash(groups);
-

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

-
	if (pkghash_get(pkg->users, name) != NULL) {
+
	tll_foreach(pkg->users, u) {
+
		if (strcmp(u->item, name) != 0)
+
			continue;
		if (ctx.developer_mode) {
			pkg_emit_error("duplicate user listing: %s, fatal (developer mode)", name);
			return (EPKG_FATAL);
-
		} else {
-
			pkg_emit_error("duplicate user listing: %s, ignoring", name);
-
			return (EPKG_OK);
		}
+
		pkg_emit_error("duplicate user listing: %s, ignoring", name);
+
		return (EPKG_OK);
	}

-
	pkghash_safe_add(pkg->users, name, NULL, NULL);
+
	tll_push_back(pkg->users, xstrdup(name));

	return (EPKG_OK);
}
@@ -426,17 +413,18 @@ pkg_addgroup(struct pkg *pkg, const char *name)
	assert(pkg != NULL);
	assert(name != NULL && name[0] != '\0');

-
	if (pkghash_get(pkg->groups, name) != NULL) {
+
	tll_foreach(pkg->groups, g) {
+
		if (strcmp(g->item, name) != 0)
+
			continue;
		if (ctx.developer_mode) {
			pkg_emit_error("duplicate group listing: %s, fatal (developer mode)", name);
			return (EPKG_FATAL);
-
		} else {
-
			pkg_emit_error("duplicate group listing: %s, ignoring", name);
-
			return (EPKG_OK);
		}
+
		pkg_emit_error("duplicate group listing: %s, ignoring", name);
+
		return (EPKG_OK);
	}

-
	pkghash_safe_add(pkg->groups, name, NULL, NULL);
+
	tll_push_back(pkg->groups, xstrdup(name));

	return (EPKG_OK);
}
@@ -905,10 +893,12 @@ pkg_addshlib_required(struct pkg *pkg, const char *name)
	assert(name != NULL && name[0] != '\0');

	/* silently ignore duplicates in case of shlibs */
-
	if (pkghash_get(pkg->shlibs_required, name) != NULL)
-
		return (EPKG_OK);
+
	tll_foreach(pkg->shlibs_required, s) {
+
		if (strcmp(s->item, name) == 0)
+
			return (EPKG_OK);
+
	}

-
	pkghash_safe_add(pkg->shlibs_required, name, NULL, NULL);
+
	tll_push_back(pkg->shlibs_required, xstrdup(name));

	pkg_debug(3, "added shlib deps for %s on %s", pkg->name, name);

@@ -926,10 +916,12 @@ pkg_addshlib_provided(struct pkg *pkg, const char *name)
		return (EPKG_OK);

	/* silently ignore duplicates in case of shlibs */
-
	if (pkghash_get(pkg->shlibs_provided, name) != NULL)
-
		return (EPKG_OK);
+
	tll_foreach(pkg->shlibs_provided, s) {
+
		if (strcmp(s->item, name) == 0)
+
			return (EPKG_OK);
+
	}

-
	pkghash_safe_add(pkg->shlibs_provided, name, NULL, NULL);
+
	tll_push_back(pkg->shlibs_provided, xstrdup(name));

	pkg_debug(3, "added shlib provide %s for %s", name, pkg->name);

@@ -966,10 +958,12 @@ pkg_addrequire(struct pkg *pkg, const char *name)
	assert(name != NULL && name[0] != '\0');

	/* silently ignore duplicates in case of conflicts */
-
	if (pkghash_get(pkg->requires, name) != NULL)
-
		return (EPKG_OK);
+
	tll_foreach(pkg->requires, p) {
+
		if (strcmp(p->item, name) == 0)
+
			return (EPKG_OK);
+
	}

-
	pkghash_safe_add(pkg->requires, name, NULL, NULL);
+
	tll_push_back(pkg->requires, xstrdup(name));

	return (EPKG_OK);
}
@@ -981,10 +975,12 @@ pkg_addprovide(struct pkg *pkg, const char *name)
	assert(name != NULL && name[0] != '\0');

	/* silently ignore duplicates in case of conflicts */
-
	if (pkghash_get(pkg->provides, name) != NULL)
-
		return (EPKG_OK);
+
	tll_foreach(pkg->provides, p) {
+
		if (strcmp(p->item, name) == 0)
+
			return (EPKG_OK);
+
	}

-
	pkghash_safe_add(pkg->provides, name, NULL, NULL);
+
	tll_push_back(pkg->provides, xstrdup(name));

	return (EPKG_OK);
}
@@ -1043,20 +1039,8 @@ pkg_list_count(const struct pkg *pkg, pkg_list list)
		return (pkghash_count(pkg->filehash));
	case PKG_DIRS:
		return (pkghash_count(pkg->dirhash));
-
	case PKG_USERS:
-
		return (pkghash_count(pkg->users));
-
	case PKG_GROUPS:
-
		return (pkghash_count(pkg->groups));
-
	case PKG_SHLIBS_REQUIRED:
-
		return (pkghash_count(pkg->shlibs_required));
-
	case PKG_SHLIBS_PROVIDED:
-
		return (pkghash_count(pkg->shlibs_provided));
	case PKG_CONFLICTS:
		return (pkghash_count(pkg->conflictshash));
-
	case PKG_PROVIDES:
-
		return (pkghash_count(pkg->provides));
-
	case PKG_REQUIRES:
-
		return (pkghash_count(pkg->requires));
	case PKG_CONFIG_FILES:
		return (pkghash_count(pkg->config_files_hash));
	}
@@ -1108,42 +1092,12 @@ pkg_list_free(struct pkg *pkg, pkg_list list) {
		pkg->dirhash = NULL;
		pkg->flags &= ~PKG_LOAD_DIRS;
		break;
-
	case PKG_USERS:
-
		pkghash_destroy(pkg->users);
-
		pkg->users = NULL;
-
		pkg->flags &= ~PKG_LOAD_USERS;
-
		break;
-
	case PKG_GROUPS:
-
		pkghash_destroy(pkg->groups);
-
		pkg->groups = NULL;
-
		pkg->flags &= ~PKG_LOAD_GROUPS;
-
		break;
-
	case PKG_SHLIBS_REQUIRED:
-
		pkghash_destroy(pkg->shlibs_required);
-
		pkg->shlibs_required = NULL;
-
		pkg->flags &= ~PKG_LOAD_SHLIBS_REQUIRED;
-
		break;
-
	case PKG_SHLIBS_PROVIDED:
-
		pkghash_destroy(pkg->shlibs_provided);
-
		pkg->shlibs_provided = NULL;
-
		pkg->flags &= ~PKG_LOAD_SHLIBS_PROVIDED;
-
		break;
	case PKG_CONFLICTS:
		DL_FREE(pkg->conflicts, pkg_conflict_free);
		pkghash_destroy(pkg->conflictshash);
		pkg->conflictshash = NULL;
		pkg->flags &= ~PKG_LOAD_CONFLICTS;
		break;
-
	case PKG_PROVIDES:
-
		pkghash_destroy(pkg->provides);
-
		pkg->provides = NULL;
-
		pkg->flags &= ~PKG_LOAD_PROVIDES;
-
		break;
-
	case PKG_REQUIRES:
-
		pkghash_destroy(pkg->requires);
-
		pkg->requires = NULL;
-
		pkg->flags &= ~PKG_LOAD_REQUIRES;
-
		break;
	}
}

modified libpkg/pkg.h.in
@@ -275,6 +275,12 @@ typedef enum {
	PKG_VITAL,
	PKG_CATEGORIES,
	PKG_LICENSES,
+
	PKG_USERS,
+
	PKG_GROUPS,
+
	PKG_PROVIDES,
+
	PKG_REQUIRES,
+
	PKG_SHLIBS_REQUIRED,
+
	PKG_SHLIBS_PROVIDED,
	PKG_NUM_FIELDS,		/* end of fields */
} pkg_attr;

@@ -306,14 +312,8 @@ typedef enum {
	PKG_OPTIONS,
	PKG_FILES,
	PKG_DIRS,
-
	PKG_USERS,
-
	PKG_GROUPS,
-
	PKG_SHLIBS_REQUIRED,
-
	PKG_SHLIBS_PROVIDED,
	PKG_CONFLICTS,
-
	PKG_PROVIDES,
	PKG_CONFIG_FILES,
-
	PKG_REQUIRES,
} pkg_list;

typedef enum {
modified libpkg/pkg_add.c
@@ -1031,7 +1031,7 @@ pkg_add_cleanup_old(struct pkgdb *db, struct pkg *old, struct pkg *new, int flag
					const char *libname;
					libname = strrchr(f->path, '/');
					if (libname != NULL &&
-
					    pkghash_get(old->shlibs_provided, libname+1) != NULL) {
+
					    stringlist_contains(&old->shlibs_provided, libname+1)) {
						backup_library(db, old, f->path);
					}
				}
modified libpkg/pkg_attributes.c
@@ -289,7 +289,47 @@ pkg_get_element(struct pkg *p, pkg_attr a)
		e->kvlist->list = &p->annotations;
		e->type = PKG_KVLIST;
		break;
+
	case PKG_SHLIBS_REQUIRED:
+
		e->stringlist = xcalloc(1, sizeof(struct pkg_stringlist *));
+
		e->stringlist->list = &p->shlibs_required;
+
		e->type = PKG_STRINGLIST;
+
		break;
+
	case PKG_SHLIBS_PROVIDED:
+
		e->stringlist = xcalloc(1, sizeof(struct pkg_stringlist *));
+
		e->stringlist->list = &p->shlibs_provided;
+
		e->type = PKG_STRINGLIST;
+
		break;
+
	case PKG_PROVIDES:
+
		e->stringlist = xcalloc(1, sizeof(struct pkg_stringlist *));
+
		e->stringlist->list = &p->provides;
+
		e->type = PKG_STRINGLIST;
+
		break;
+
	case PKG_REQUIRES:
+
		e->stringlist = xcalloc(1, sizeof(struct pkg_stringlist *));
+
		e->stringlist->list = &p->requires;
+
		e->type = PKG_STRINGLIST;
+
		break;
+
	case PKG_USERS:
+
		e->stringlist = xcalloc(1, sizeof(struct pkg_stringlist *));
+
		e->stringlist->list = &p->users;
+
		e->type = PKG_STRINGLIST;
+
		break;
+
	case PKG_GROUPS:
+
		e->stringlist = xcalloc(1, sizeof(struct pkg_stringlist *));
+
		e->stringlist->list = &p->groups;
+
		e->type = PKG_STRINGLIST;
+
		break;
	}

	return (e);
}
+

+
bool
+
stringlist_contains(stringlist_t *l, const char *name)
+
{
+
	tll_foreach(*l, e) {
+
		if (strcmp(e->item, name) == 0)
+
			return (true);
+
	}
+
	return (false);
+
}
modified libpkg/pkg_checksum.c
@@ -220,7 +220,6 @@ pkg_checksum_generate(struct pkg *pkg, char *dest, size_t destlen,
	struct pkg_option *option = NULL;
	struct pkg_dep *dep = NULL;
	struct pkg_file *f = NULL;
-
	pkghash_it	it;
	int i;

	if (pkg == NULL || type >= PKG_HASH_TYPE_UNKNOWN ||
@@ -237,24 +236,20 @@ pkg_checksum_generate(struct pkg *pkg, char *dest, size_t destlen,
		pkg_checksum_add_entry(option->key, option->value, &entries);
	}

-
	it = pkghash_iterator(pkg->shlibs_required);
-
	while (pkghash_next(&it)) {
-
		pkg_checksum_add_entry("required_shlib", it.key, &entries);
+
	tll_foreach(pkg->shlibs_required, s) {
+
		pkg_checksum_add_entry("required_shlib", s->item, &entries);
	}

-
	it = pkghash_iterator(pkg->shlibs_provided);
-
	while (pkghash_next(&it)) {
-
		pkg_checksum_add_entry("provided_shlib", it.key, &entries);
+
	tll_foreach(pkg->shlibs_provided, s) {
+
		pkg_checksum_add_entry("provided_shlib", s->item, &entries);
	}

-
	it = pkghash_iterator(pkg->users);
-
	while (pkghash_next(&it)) {
-
		pkg_checksum_add_entry("user", it.key, &entries);
+
	tll_foreach(pkg->users, u) {
+
		pkg_checksum_add_entry("user", u->item, &entries);
	}

-
	it = pkghash_iterator(pkg->groups);
-
	while (pkghash_next(&it)) {
-
		pkg_checksum_add_entry("group", it.key, &entries);
+
	tll_foreach(pkg->groups, g) {
+
		pkg_checksum_add_entry("group", g->item, &entries);
	}

	while (pkg_deps(pkg, &dep) == EPKG_OK) {
@@ -263,14 +258,12 @@ pkg_checksum_generate(struct pkg *pkg, char *dest, size_t destlen,
		free(olduid);
	}

-
	it = pkghash_iterator(pkg->provides);
-
	while (pkghash_next(&it)) {
-
		pkg_checksum_add_entry("provide", it.key, &entries);
+
	tll_foreach(pkg->provides, p) {
+
		pkg_checksum_add_entry("provide", p->item, &entries);
	}

-
	it = pkghash_iterator(pkg->requires);
-
	while (pkghash_next(&it)) {
-
		pkg_checksum_add_entry("require", it.key, &entries);
+
	tll_foreach(pkg->requires, r) {
+
		pkg_checksum_add_entry("require", r->item, &entries);
	}

	if (inc_scripts) {
modified libpkg/pkg_cudf.c
@@ -136,13 +136,12 @@ cudf_emit_pkg(struct pkg *pkg, int version, FILE *f,
	}

	column = 0;
-
	if (pkghash_count(pkg->provides) > 0) {
+
	if (tll_length(pkg->provides) > 0) {
		if (fprintf(f, "provides: ") < 0)
			return (EPKG_FATAL);
-
		pkghash_it it = pkghash_iterator(pkg->provides);
-
		while (pkghash_next(&it)) {
-
			if (cudf_print_element(f, it.key,
-
			    column + 1 == pkghash_count(pkg->provides), &column) < 0) {
+
		tll_foreach(pkg->provides, p) {
+
			if (cudf_print_element(f, p->item,
+
			    column + 1 == tll_length(pkg->provides), &column) < 0) {
				return (EPKG_FATAL);
			}
		}
modified libpkg/pkg_elf.c
@@ -472,14 +472,12 @@ pkg_analyse_files(struct pkgdb *db __unused, struct pkg *pkg, const char *stage)
	const char *lib;
	bool failures = false;

-
	if (pkghash_count(pkg->shlibs_required) != 0) {
-
		pkghash_destroy(pkg->shlibs_required);
-
		pkg->shlibs_required = NULL;
+
	if (tll_length(pkg->shlibs_required) != 0) {
+
		tll_free_and_free(pkg->shlibs_required, free);
	}

-
	if (pkghash_count(pkg->shlibs_provided) != 0) {
-
		pkghash_destroy(pkg->shlibs_provided);
-
		pkg->shlibs_provided = NULL;
+
	if (tll_length(pkg->shlibs_provided) != 0) {
+
		tll_free_and_free(pkg->shlibs_provided, free);
	}

	if (elf_version(EV_CURRENT) == EV_NONE)
@@ -521,24 +519,23 @@ pkg_analyse_files(struct pkgdb *db __unused, struct pkg *pkg, const char *stage)
	/*
	 * Do not depend on libraries that a package provides itself
	 */
-
	pkghash_it it = pkghash_iterator(pkg->shlibs_required);
-
	while (pkghash_next(&it)) {
-
		if (pkghash_get(pkg->shlibs_provided, it.key)) {
+
	tll_foreach(pkg->shlibs_required, s) {
+
		if (stringlist_contains(&pkg->shlibs_provided, s->item)) {
			pkg_debug(2, "remove %s from required shlibs as the "
			    "package %s provides this library itself",
-
			    it.key, pkg->name);
-
			pkghash_del(pkg->shlibs_required, it.key);
+
			    s->item, pkg->name);
+
			tll_remove_and_free(pkg->shlibs_required, s, free);
			continue;
		}
		file = NULL;
		while (pkg_files(pkg, &file) == EPKG_OK) {
-
			if ((lib = strstr(file->path, it.key)) != NULL &&
-
			    strlen(lib) == strlen(it.key) && lib[-1] == '/') {
+
			if ((lib = strstr(file->path, s->item)) != NULL &&
+
			    strlen(lib) == strlen(s->item) && lib[-1] == '/') {
				pkg_debug(2, "remove %s from required shlibs as "
				    "the package %s provides this file itself",
-
				    it.key, pkg->name);
+
				    s->item, pkg->name);

-
				pkghash_del(pkg->shlibs_required, it.key);
+
				tll_remove_and_free(pkg->shlibs_required, s, free);
				break;
			}
		}
@@ -549,8 +546,7 @@ pkg_analyse_files(struct pkgdb *db __unused, struct pkg *pkg, const char *stage)
	 * drop the provided one
	 */
	if (pkg_kv_get(&pkg->annotations, "no_provide_shlib") != NULL) {
-
		pkghash_destroy(pkg->shlibs_provided);
-
		pkg->shlibs_provided = NULL;
+
		tll_free_and_free(pkg->shlibs_provided, free);
	}

	if (failures)
modified libpkg/pkg_jobs.c
@@ -1090,7 +1090,8 @@ pkg_jobs_need_upgrade(struct pkg *rp, struct pkg *lp)
	struct pkg_option *lo = NULL, *ro = NULL;
	struct pkg_dep *ld = NULL, *rd = NULL;
	struct pkg_conflict *lc = NULL, *rc = NULL;
-
	pkghash_it it1, it2;
+
	const char **l1;
+
	size_t i;

	/* If no local package, then rp is obviously need to be added */
	if (lp == NULL)
@@ -1209,94 +1210,91 @@ pkg_jobs_need_upgrade(struct pkg *rp, struct pkg *lp)
	}

	/* Provides */
-
	it1 = pkghash_iterator(rp->provides);
-
	it2 = pkghash_iterator(lp->provides);
-
	for (;;) {
-
		ret1 = pkghash_next(&it1);
-
		ret2 = pkghash_next(&it2);
-
		if (ret1 != ret2) {
+
	if (tll_length(rp->provides) != tll_length(lp->provides)) {
+
		free(rp->reason);
+
		rp->reason = xstrdup("provides changed");
+
		return (true);
+
	}
+
	l1 = xcalloc(tll_length(lp->provides), sizeof (char*));
+
	i = 0;
+
	tll_foreach(lp->provides, l) {
+
		l1[i++] = l->item;
+
	}
+
	i = 0;
+
	tll_foreach(rp->provides, r) {
+
		if (strcmp(r->item, l1[i]) != 0) {
			free(rp->reason);
			rp->reason = xstrdup("provides changed");
+
			free(l1);
			return (true);
		}
-
		if (ret1) {
-
			if (strcmp(it1.key, it2.key) != 0) {
-
				free(rp->reason);
-
				rp->reason = xstrdup("provides changed");
-
				return (true);
-
			}
-
		}
-
		else
-
			break;
	}
+
	free(l1);
+

	/* Requires */
-
	it1 = pkghash_iterator(rp->requires);
-
	it2 = pkghash_iterator(lp->requires);
-
	for (;;) {
-
		ret1 = pkghash_next(&it1);
-
		ret2 = pkghash_next(&it2);
-
		if (ret1 != ret2) {
+
	if (tll_length(rp->requires) != tll_length(lp->requires)) {
+
		free(rp->reason);
+
		rp->reason = xstrdup("requires changed");
+
		return (true);
+
	}
+
	l1 = xcalloc(tll_length(lp->requires), sizeof (char*));
+
	i = 0;
+
	tll_foreach(lp->requires, l) {
+
		l1[i++] = l->item;
+
	}
+
	i = 0;
+
	tll_foreach(rp->requires, r) {
+
		if (strcmp(r->item, l1[i]) != 0) {
			free(rp->reason);
			rp->reason = xstrdup("requires changed");
+
			free(l1);
			return (true);
		}
-
		if (ret1) {
-
			if (strcmp(it1.key, it2.key) != 0) {
-
				free(rp->reason);
-
				rp->reason = xstrdup("requires changed");
-
				return (true);
-
			}
-
		}
-
		else
-
			break;
	}
+
	free(l1);

	/* Finish by the shlibs */
-
	it1 = pkghash_iterator(rp->shlibs_provided);
-
	it2 = pkghash_iterator(lp->shlibs_provided);
-
	for (;;) {
-
		ret1 = pkghash_next(&it1);
-
		ret2 = pkghash_next(&it2);
-
		if (ret1 != ret2) {
+
	if (tll_length(rp->shlibs_provided) != tll_length(lp->shlibs_provided)) {
+
		free(rp->reason);
+
		rp->reason = xstrdup("provided shared library changed");
+
		return (true);
+
	}
+
	l1 = xcalloc(tll_length(lp->shlibs_provided), sizeof (char*));
+
	i = 0;
+
	tll_foreach(lp->shlibs_provided, l) {
+
		l1[i++] = l->item;
+
	}
+
	i = 0;
+
	tll_foreach(rp->shlibs_provided, r) {
+
		if (strcmp(r->item, l1[i]) != 0) {
			free(rp->reason);
			rp->reason = xstrdup("provided shared library changed");
+
			free(l1);
			return (true);
		}
-
		if (ret1) {
-
			if (strcmp(it1.key, it2.key) != 0) {
-
				free(rp->reason);
-
				rp->reason = xstrdup("provided shared library changed");
-
				pkg_debug(1, "provided shlib changed %s -> %s",
-
				    it2.key, it1.key);
-
				return (true);
-
			}
-
		}
-
		else
-
			break;
	}
+
	free(l1);

-
	it1 = pkghash_iterator(rp->shlibs_required);
-
	it2 = pkghash_iterator(lp->shlibs_required);
-
	for (;;) {
-
		ret1 = pkghash_next(&it1);
-
		ret2 = pkghash_next(&it2);
-
		if (ret1 != ret2) {
+
	if (tll_length(rp->shlibs_required) != tll_length(lp->shlibs_required)) {
+
		free(rp->reason);
+
		rp->reason = xstrdup("required shared library changed");
+
		return (true);
+
	}
+
	l1 = xcalloc(tll_length(lp->shlibs_required), sizeof (char*));
+
	i = 0;
+
	tll_foreach(lp->shlibs_required, l) {
+
		l1[i++] = l->item;
+
	}
+
	i = 0;
+
	tll_foreach(rp->shlibs_required, r) {
+
		if (strcmp(r->item, l1[i]) != 0) {
			free(rp->reason);
-
			rp->reason = xstrdup("needed shared library changed");
+
			rp->reason = xstrdup("required shared library changed");
+
			free(l1);
			return (true);
		}
-
		if (ret1) {
-
			if (strcmp(it1.key, it2.key) != 0) {
-
				free(rp->reason);
-
				rp->reason = xstrdup("needed shared library changed");
-
				pkg_debug(1, "Required shlib changed %s -> %s",
-
				    it2.key, it1.key);
-
				return (true);
-
			}
-
		}
-
		else
-
			break;
	}
+
	free(l1);

	return (false);
}
modified libpkg/pkg_jobs_universe.c
@@ -472,38 +472,36 @@ pkg_jobs_universe_process_shlibs(struct pkg_jobs_universe *universe,
{
	struct pkgdb_it *it;
	int rc;
-
	pkghash_it hit;

-
	hit = pkghash_iterator(pkg->shlibs_required);
-
	while (pkghash_next(&hit)) {
-
		if (pkghash_get(universe->provides, hit.key) != NULL)
+
	tll_foreach(pkg->shlibs_required, s) {
+
		if (pkghash_get(universe->provides, s->item) != NULL)
			continue;

		/* Check for local provides */
-
		it = pkgdb_query_shlib_provide(universe->j->db, hit.key);
+
		it = pkgdb_query_shlib_provide(universe->j->db, s->item);
		if (it != NULL) {
			rc = pkg_jobs_universe_handle_provide(universe, it,
-
			    hit.key, true, pkg);
+
			    s->item, true, pkg);
			pkgdb_it_free(it);

			if (rc != EPKG_OK) {
				pkg_debug(1, "cannot find local packages that provide library %s "
						"required for %s",
-
						hit.key, pkg->name);
+
						s->item, pkg->name);
			}
		}
		/* Not found, search in the repos */
		it = pkgdb_repo_shlib_provide(universe->j->db,
-
			hit.key, universe->j->reponame);
+
			s->item, universe->j->reponame);

		if (it != NULL) {
-
			rc = pkg_jobs_universe_handle_provide(universe, it, hit.key, true, pkg);
+
			rc = pkg_jobs_universe_handle_provide(universe, it, s->item, true, pkg);
			pkgdb_it_free(it);

			if (rc != EPKG_OK) {
				pkg_debug(1, "cannot find remote packages that provide library %s "
						"required for %s",
-
				    hit.key, pkg->name);
+
				    s->item, pkg->name);
			}
		}
	}
@@ -517,39 +515,36 @@ pkg_jobs_universe_process_provides_requires(struct pkg_jobs_universe *universe,
{
	struct pkgdb_it *it;
	int rc;
-
	pkghash_it hit;

-

-
	hit = pkghash_iterator(pkg->requires);
-
	while(pkghash_next(&hit)) {
-
		if (pkghash_get(universe->provides, hit.key) != NULL)
+
	tll_foreach(pkg->requires, r) {
+
		if (pkghash_get(universe->provides, r->item) != NULL)
			continue;

		/* Check for local provides */
-
		it = pkgdb_query_provide(universe->j->db, hit.key);
+
		it = pkgdb_query_provide(universe->j->db, r->item);
		if (it != NULL) {
-
			rc = pkg_jobs_universe_handle_provide(universe, it, hit.key, false, pkg);
+
			rc = pkg_jobs_universe_handle_provide(universe, it, r->item, false, pkg);
			pkgdb_it_free(it);

			if (rc != EPKG_OK) {
				pkg_debug(1, "cannot find local packages that provide %s "
						"required for %s",
-
						hit.key, pkg->name);
+
						r->item, pkg->name);
			}
		}

		/* Not found, search in the repos */
		it = pkgdb_repo_provide(universe->j->db,
-
			hit.key, universe->j->reponame);
+
			r->item, universe->j->reponame);

		if (it != NULL) {
-
			rc = pkg_jobs_universe_handle_provide(universe, it, hit.key, false, pkg);
+
			rc = pkg_jobs_universe_handle_provide(universe, it, r->item, false, pkg);
			pkgdb_it_free(it);

			if (rc != EPKG_OK) {
				pkg_debug(1, "cannot find remote packages that provide %s "
						"required for %s",
-
				    hit.key, pkg->name);
+
				    r->item, pkg->name);
				return (rc);
			}
		}
modified libpkg/pkg_manifest.c
@@ -966,7 +966,6 @@ pkg_emit_object(struct pkg *pkg, short flags)
	char legacyarch[BUFSIZ];
	ucl_object_t *map, *seq, *submap;
	ucl_object_t *top = ucl_object_typed_new(UCL_OBJECT);
-
	pkghash_it it;

	if (pkg->abi == NULL && pkg->arch != NULL)
		pkg->abi = xstrdup(pkg->arch);
@@ -1073,44 +1072,40 @@ pkg_emit_object(struct pkg *pkg, short flags)

	pkg_debug(4, "Emitting users");
	seq = NULL;
-
	it = pkghash_iterator(pkg->users);
-
	while (pkghash_next(&it)) {
+
	tll_foreach(pkg->users, u) {
		if (seq == NULL)
			seq = ucl_object_typed_new(UCL_ARRAY);
-
		ucl_array_append(seq, ucl_object_fromstring(it.key));
+
		ucl_array_append(seq, ucl_object_fromstring(u->item));
	}
	if (seq)
		ucl_object_insert_key(top, seq, "users", 5, false);

	pkg_debug(4, "Emitting groups");
	seq = NULL;
-
	it = pkghash_iterator(pkg->users);
-
	while (pkghash_next(&it)) {
+
	tll_foreach(pkg->groups, g) {
		if (seq == NULL)
			seq = ucl_object_typed_new(UCL_ARRAY);
-
		ucl_array_append(seq, ucl_object_fromstring(it.key));
+
		ucl_array_append(seq, ucl_object_fromstring(g->item));
	}
	if (seq)
		ucl_object_insert_key(top, seq, "groups", 6, false);

-
	pkg_debug(4, "Emitting required");
+
	pkg_debug(4, "Emitting shibs_required");
	seq = NULL;
-
	it = pkghash_iterator(pkg->shlibs_required);
-
	while (pkghash_next(&it)) {
+
	tll_foreach(pkg->shlibs_required, s) {
		if (seq == NULL)
			seq = ucl_object_typed_new(UCL_ARRAY);
-
		ucl_array_append(seq, ucl_object_fromstring(it.key));
+
		ucl_array_append(seq, ucl_object_fromstring(s->item));
	}
	if (seq)
		ucl_object_insert_key(top, seq, "shlibs_required", 15, false);

	pkg_debug(4, "Emitting shlibs_provided");
	seq = NULL;
-
	it = pkghash_iterator(pkg->shlibs_provided);
-
	while (pkghash_next(&it)) {
+
	tll_foreach(pkg->shlibs_provided, s) {
		if (seq == NULL)
			seq = ucl_object_typed_new(UCL_ARRAY);
-
		ucl_array_append(seq, ucl_object_fromstring(it.key));
+
		ucl_array_append(seq, ucl_object_fromstring(s->item));
	}
	if (seq)
		ucl_object_insert_key(top, seq, "shlibs_provided", 15, false);
@@ -1127,22 +1122,20 @@ pkg_emit_object(struct pkg *pkg, short flags)

	pkg_debug(4, "Emitting provides");
	seq = NULL;
-
	it = pkghash_iterator(pkg->provides);
-
	while (pkghash_next(&it)) {
+
	tll_foreach(pkg->provides, p) {
		if (seq == NULL)
			seq = ucl_object_typed_new(UCL_ARRAY);
-
		ucl_array_append(seq, ucl_object_fromstring(it.key));
+
		ucl_array_append(seq, ucl_object_fromstring(p->item));
	}
	if (seq)
		ucl_object_insert_key(top, seq, "provides", 8, false);

	pkg_debug(4, "Emitting requires");
	seq = NULL;
-
	it = pkghash_iterator(pkg->requires);
-
	while (pkghash_next(&it)) {
+
	tll_foreach(pkg->requires, r) {
		if (seq == NULL)
			seq = ucl_object_typed_new(UCL_ARRAY);
-
		ucl_array_append(seq, ucl_object_fromstring(it.key));
+
		ucl_array_append(seq, ucl_object_fromstring(r->item));
	}
	if (seq)
		ucl_object_insert_key(top, seq, "requires", 8, false);
modified libpkg/pkg_printf.c
@@ -913,9 +913,8 @@ format_shlibs_required(xstring *buf, const void *data, struct percent_esc *p)
	const struct pkg	*pkg = data;

	if (p->flags & (PP_ALTERNATE_FORM1|PP_ALTERNATE_FORM2))
-
		return (list_count(buf, pkg_list_count(pkg, PKG_SHLIBS_REQUIRED), p));
+
		return (list_count(buf, tll_length(pkg->shlibs_required), p));
	else {
-
		pkghash_it it;
		int			 count;

		set_list_defaults(p, "%Bn\n", "");
@@ -923,14 +922,13 @@ format_shlibs_required(xstring *buf, const void *data, struct percent_esc *p)
		count = 1;
		fflush(p->sep_fmt->fp);
		fflush(p->item_fmt->fp);
-
		it = pkghash_iterator(pkg->shlibs_required);
-
		while (pkghash_next(&it)) {
+
		tll_foreach(pkg->shlibs_required, r) {
			if (count > 1)
				iterate_item(buf, pkg, p->sep_fmt->buf,
-
					     it.key, count, PP_B);
+
					     r->item, count, PP_B);

			iterate_item(buf, pkg, p->item_fmt->buf,
-
				     it.key, count, PP_B);
+
				     r->item, count, PP_B);
			count++;
		}
	}
@@ -1177,7 +1175,7 @@ format_groups(xstring *buf, const void *data, struct percent_esc *p)
	const struct pkg	*pkg = data;

	if (p->flags & (PP_ALTERNATE_FORM1|PP_ALTERNATE_FORM2))
-
		return (list_count(buf, pkg_list_count(pkg, PKG_GROUPS), p));
+
		return (list_count(buf, tll_length(pkg->groups), p));
	else {
		int	 count;

@@ -1186,14 +1184,13 @@ format_groups(xstring *buf, const void *data, struct percent_esc *p)
		count = 1;
		fflush(p->sep_fmt->fp);
		fflush(p->item_fmt->fp);
-
		pkghash_it it = pkghash_iterator(pkg->users);
-
		while (pkghash_next(&it)) {
+
		tll_foreach(pkg->groups, g) {
			if (count > 1)
				iterate_item(buf, pkg, p->sep_fmt->buf,
-
					     it.key, count, PP_G);
+
					     g->item, count, PP_G);

			iterate_item(buf, pkg,p->item_fmt->buf,
-
				     it.key, count, PP_G);
+
				     g->item, count, PP_G);
			count++;
		}
	}
@@ -1463,7 +1460,7 @@ format_users(xstring *buf, const void *data, struct percent_esc *p)
	const struct pkg	*pkg = data;

	if (p->flags & (PP_ALTERNATE_FORM1|PP_ALTERNATE_FORM2))
-
		return (list_count(buf, pkg_list_count(pkg, PKG_USERS), p));
+
		return (list_count(buf, tll_length(pkg->users), p));
	else {
		int	 count;

@@ -1472,14 +1469,13 @@ format_users(xstring *buf, const void *data, struct percent_esc *p)
		count = 1;
		fflush(p->sep_fmt->fp);
		fflush(p->item_fmt->fp);
-
		pkghash_it it = pkghash_iterator(pkg->users);
-
		while (pkghash_next(&it)) {
+
		tll_foreach(pkg->users, u) {
			if (count > 1)
				iterate_item(buf, pkg, p->sep_fmt->buf,
-
					     it.key, count, PP_U);
+
					     u->item, count, PP_U);

			iterate_item(buf, pkg, p->item_fmt->buf,
-
				     it.key, count, PP_U);
+
				     u->item, count, PP_U);
			count++;
		}
	}
@@ -1523,15 +1519,14 @@ format_int_checksum(xstring *buf, const void *data, struct percent_esc *p)
/*
 * %Y -- Required pattern.  List of pattern required by
 * binaries in the pkg.  Optionally accepts per-field format in %{ %|
-
 * %}.  Default %{%Yn\n%|%}
-
 */
+
 * %}.  Default %{%Yn\nr->item*/
xstring *
format_required(xstring *buf, const void *data, struct percent_esc *p)
{
	const struct pkg	*pkg = data;

	if (p->flags & (PP_ALTERNATE_FORM1|PP_ALTERNATE_FORM2))
-
		return (list_count(buf, pkg_list_count(pkg, PKG_REQUIRES), p));
+
		return (list_count(buf, tll_length(pkg->requires), p));
	else {
		int	 count;

@@ -1540,14 +1535,13 @@ format_required(xstring *buf, const void *data, struct percent_esc *p)
		count = 1;
		fflush(p->sep_fmt->fp);
		fflush(p->item_fmt->fp);
-
		pkghash_it it = pkghash_iterator(pkg->requires);
-
		while (pkghash_next(&it)) {
+
		tll_foreach(pkg->requires, r) {
			if (count > 1)
				iterate_item(buf, pkg, p->sep_fmt->buf,
-
					     it.key, count, PP_Y);
+
					     r->item, count, PP_Y);

			iterate_item(buf, pkg, p->item_fmt->buf,
-
				     it.key, count, PP_Y);
+
				     r->item, count, PP_Y);
			count++;
		}
	}
@@ -1589,9 +1583,8 @@ format_shlibs_provided(xstring *buf, const void *data, struct percent_esc *p)
	const struct pkg	*pkg = data;

	if (p->flags & (PP_ALTERNATE_FORM1|PP_ALTERNATE_FORM2))
-
		return (list_count(buf, pkg_list_count(pkg, PKG_SHLIBS_PROVIDED), p));
+
		return (list_count(buf, tll_length(pkg->shlibs_provided), p));
	else {
-
		pkghash_it it;
		int	 count;

		set_list_defaults(p, "%bn\n", "");
@@ -1599,14 +1592,13 @@ format_shlibs_provided(xstring *buf, const void *data, struct percent_esc *p)
		count = 1;
		fflush(p->sep_fmt->fp);
		fflush(p->item_fmt->fp);
-
		it = pkghash_iterator(pkg->shlibs_provided);
-
		while (pkghash_next(&it)) {
+
		tll_foreach(pkg->shlibs_provided, r) {
			if (count > 1)
				iterate_item(buf, pkg, p->sep_fmt->buf,
-
					     it.key, count, PP_b);
+
					     r->item, count, PP_b);

			iterate_item(buf, pkg, p->item_fmt->buf,
-
				     it.key, count, PP_b);
+
				     r->item, count, PP_b);
			count++;
		}
	}
@@ -1932,9 +1924,8 @@ format_provided(xstring *buf, const void *data, struct percent_esc *p)
	const struct pkg	*pkg = data;

	if (p->flags & (PP_ALTERNATE_FORM1|PP_ALTERNATE_FORM2))
-
		return (list_count(buf, pkg_list_count(pkg, PKG_PROVIDES), p));
+
		return (list_count(buf, tll_length(pkg->provides), p));
	else {
-
		pkghash_it it;
		int	 count;

		set_list_defaults(p, "%yn\n", "");
@@ -1942,14 +1933,13 @@ format_provided(xstring *buf, const void *data, struct percent_esc *p)
		count = 1;
		fflush(p->sep_fmt->fp);
		fflush(p->item_fmt->fp);
-
		it = pkghash_iterator(pkg->provides);
-
		while (pkghash_next(&it)) {
+
		tll_foreach(pkg->provides, r) {
			if (count > 1)
				iterate_item(buf, pkg, p->sep_fmt->buf,
-
					     it.key, count, PP_y);
+
					     r->item, count, PP_y);

			iterate_item(buf, pkg, p->item_fmt->buf,
-
				     it.key, count, PP_y);
+
				     r->item, count, PP_y);
			count++;
		}
	}
modified libpkg/pkg_solve.c
@@ -294,7 +294,7 @@ pkg_solve_handle_provide (struct pkg_solve_problem *problem,
		pkg = curvar->unit->pkg;

		if (pr->is_shlib) {
-
			libfound = (pkghash_get(pkg->shlibs_provided, pr->provide) != NULL);
+
			libfound = stringlist_contains(&pkg->shlibs_provided, pr->provide);
			/* Skip incompatible ABI as well */
			if (libfound && strcmp(pkg->arch, orig->arch) != 0) {
				pkg_debug(2, "solver: require %s: package %s-%s(%c) provides wrong ABI %s, "
@@ -304,7 +304,7 @@ pkg_solve_handle_provide (struct pkg_solve_problem *problem,
			}
		}
		else {
-
			providefound = (pkghash_get(pkg->provides, pr->provide) != NULL);
+
			providefound = stringlist_contains(&pkg->provides, pr->provide);
		}

		if (!providefound && !libfound) {
@@ -630,7 +630,6 @@ pkg_solve_process_universe_variable(struct pkg_solve_problem *problem,
	struct pkg_solve_variable *cur_var;
	struct pkg_jobs *j = problem->j;
	struct pkg_job_request *jreq = NULL;
-
	pkghash_it it;
	bool chain_added = false;

	LL_FOREACH(var, cur_var) {
@@ -666,22 +665,19 @@ pkg_solve_process_universe_variable(struct pkg_solve_problem *problem,
		}

		/* Shlibs */
-
		it = pkghash_iterator(pkg->shlibs_required);
-
		while (pkghash_next(&it)) {
+
		tll_foreach(pkg->shlibs_required, s) {
			if (pkg_solve_add_require_rule(problem, cur_var,
-
			    it.key, cur_var->assumed_reponame) != EPKG_OK) {
+
			    s->item, cur_var->assumed_reponame) != EPKG_OK) {
				continue;
			}
		}
-
		it = pkghash_iterator(pkg->requires);
-
		while (pkghash_next(&it)) {
+
		tll_foreach(pkg->requires, r) {
			if (pkg_solve_add_require_rule(problem, cur_var,
-
			    it.key, cur_var->assumed_reponame) != EPKG_OK) {
+
			    r->item, cur_var->assumed_reponame) != EPKG_OK) {
				continue;
			}
		}

-

		/*
		 * If this var chain contains mutually conflicting vars
		 * we need to register conflicts with all following
modified libpkg/pkgdb.c
@@ -1762,7 +1762,6 @@ pkgdb_register_pkg(struct pkgdb *db, struct pkg *pkg, int forced,
	int64_t			 package_id;

	const char		*arch;
-
	pkghash_it		hit;

	assert(db != NULL);

@@ -1956,12 +1955,11 @@ pkgdb_register_pkg(struct pkgdb *db, struct pkg *pkg, int forced,
	 * Insert users
	 */

-
	hit = pkghash_iterator(pkg->users);
-
	while (pkghash_next(&hit)) {
-
		if (run_prstmt(USERS1, hit.key)
+
	tll_foreach(pkg->users, u) {
+
		if (run_prstmt(USERS1, u->item)
		    != SQLITE_DONE
		    ||
-
		    run_prstmt(USERS2, package_id, hit.key)
+
		    run_prstmt(USERS2, package_id, u->item)
		    != SQLITE_DONE) {
			ERROR_STMT_SQLITE(s, STMT(USERS2));
			goto cleanup;
@@ -1972,12 +1970,11 @@ pkgdb_register_pkg(struct pkgdb *db, struct pkg *pkg, int forced,
	 * Insert groups
	 */

-
	hit = pkghash_iterator(pkg->groups);
-
	while (pkghash_next(&hit)) {
-
		if (run_prstmt(GROUPS1, hit.key)
+
	tll_foreach(pkg->groups, g) {
+
		if (run_prstmt(GROUPS1, g->item)
		    != SQLITE_DONE
		    ||
-
		    run_prstmt(GROUPS2, package_id, hit.key)
+
		    run_prstmt(GROUPS2, package_id, g->item)
		    != SQLITE_DONE) {
			ERROR_STMT_SQLITE(s, STMT(GROUPS2));
			goto cleanup;
@@ -2100,13 +2097,11 @@ pkgdb_insert_lua_scripts(struct pkg *pkg, int64_t package_id, sqlite3 *s)
int
pkgdb_update_shlibs_required(struct pkg *pkg, int64_t package_id, sqlite3 *s)
{
-
	pkghash_it it = pkghash_iterator(pkg->shlibs_required);
-

-
	while (pkghash_next(&it)) {
-
		if (run_prstmt(SHLIBS1, it.key)
+
	tll_foreach(pkg->shlibs_required, r) {
+
		if (run_prstmt(SHLIBS1, r->item)
		    != SQLITE_DONE
		    ||
-
		    run_prstmt(SHLIBS_REQD, package_id, it.key)
+
		    run_prstmt(SHLIBS_REQD, package_id, r->item)
		    != SQLITE_DONE) {
			ERROR_STMT_SQLITE(s, STMT(SHLIBS_REQD));
			return (EPKG_FATAL);
@@ -2135,13 +2130,11 @@ pkgdb_update_config_file_content(struct pkg *p, sqlite3 *s)
int
pkgdb_update_shlibs_provided(struct pkg *pkg, int64_t package_id, sqlite3 *s)
{
-
	pkghash_it it = pkghash_iterator(pkg->shlibs_provided);
-

-
	while (pkghash_next(&it)) {
-
		if (run_prstmt(SHLIBS1, it.key)
+
	tll_foreach(pkg->shlibs_provided, r) {
+
		if (run_prstmt(SHLIBS1, r->item)
		    != SQLITE_DONE
		    ||
-
		    run_prstmt(SHLIBS_PROV, package_id, it.key)
+
		    run_prstmt(SHLIBS_PROV, package_id, r->item)
		    != SQLITE_DONE) {
			ERROR_STMT_SQLITE(s, STMT(SHLIBS_PROV));
			return (EPKG_FATAL);
@@ -2154,13 +2147,11 @@ pkgdb_update_shlibs_provided(struct pkg *pkg, int64_t package_id, sqlite3 *s)
int
pkgdb_update_requires(struct pkg *pkg, int64_t package_id, sqlite3 *s)
{
-
	pkghash_it it = pkghash_iterator(pkg->requires);
-

-
	while (pkghash_next(&it)) {
-
		if (run_prstmt(REQUIRE, it.key)
+
	tll_foreach(pkg->requires, r) {
+
		if (run_prstmt(REQUIRE, r->item)
		    != SQLITE_DONE
		    ||
-
		    run_prstmt(PKG_REQUIRE, package_id, it.key)
+
		    run_prstmt(PKG_REQUIRE, package_id, r->item)
		    != SQLITE_DONE) {
			ERROR_STMT_SQLITE(s, STMT(PKG_REQUIRE));
			return (EPKG_FATAL);
@@ -2173,13 +2164,11 @@ pkgdb_update_requires(struct pkg *pkg, int64_t package_id, sqlite3 *s)
int
pkgdb_update_provides(struct pkg *pkg, int64_t package_id, sqlite3 *s)
{
-
	pkghash_it it = pkghash_iterator(pkg->provides);
-

-
	while (pkghash_next(&it)) {
-
		if (run_prstmt(PROVIDE, it.key)
+
	tll_foreach(pkg->provides, p) {
+
		if (run_prstmt(PROVIDE, p->item)
		    != SQLITE_DONE
		    ||
-
		    run_prstmt(PKG_PROVIDE, package_id, it.key)
+
		    run_prstmt(PKG_PROVIDE, package_id, p->item)
		    != SQLITE_DONE) {
			ERROR_STMT_SQLITE(s, STMT(PKG_PROVIDE));
			return (EPKG_FATAL);
modified libpkg/private/pkg.h
@@ -224,14 +224,14 @@ struct pkg {
	struct pkg_dir		*dirs;
	pkghash			*optionshash;
	struct pkg_option	*options;
-
	pkghash			*users;
-
	pkghash			*groups;
-
	pkghash			*shlibs_required;
-
	pkghash			*shlibs_provided;
+
	stringlist_t		 users;
+
	stringlist_t		 groups;
+
	stringlist_t		 shlibs_required;
+
	stringlist_t		 shlibs_provided;
	pkghash			*conflictshash;
	struct pkg_conflict	*conflicts;
-
	pkghash			*provides;
-
	pkghash			*requires;
+
	stringlist_t		 provides;
+
	stringlist_t		 requires;
	pkghash			*config_files_hash;
	struct pkg_config_file	*config_files;
	kvlist_t		 annotations;
@@ -828,5 +828,6 @@ int set_attrsat(int fd, const char *path, mode_t perm, uid_t uid, gid_t gid, con
struct trigger *triggers_load(bool cleanup_only);
int triggers_execute(struct trigger *cleanup_triggers);
void append_touched_file(const char *path);
+
bool stringlist_contains(stringlist_t *l, const char *name);

#endif
modified libpkg/repo/binary/update.c
@@ -212,48 +212,44 @@ try_again:
		}
	}

-
	it = pkghash_iterator(pkg->shlibs_required);
-
	while (pkghash_next(&it)) {
-
		ret = pkg_repo_binary_run_prstatement(SHLIB1, it.key);
+
	tll_foreach(pkg->shlibs_required, s) {
+
		ret = pkg_repo_binary_run_prstatement(SHLIB1, s->item);
		if (ret == SQLITE_DONE)
			ret = pkg_repo_binary_run_prstatement(SHLIB_REQD, package_id,
-
			    it.key);
+
			    s->item);
		if (ret != SQLITE_DONE) {
			ERROR_SQLITE(sqlite, pkg_repo_binary_sql_prstatement(SHLIB_REQD));
			return (EPKG_FATAL);
		}
	}

-
	it = pkghash_iterator(pkg->shlibs_provided);
-
	while (pkghash_next(&it)) {
-
		ret = pkg_repo_binary_run_prstatement(SHLIB1, it.key);
+
	tll_foreach(pkg->shlibs_provided, s) {
+
		ret = pkg_repo_binary_run_prstatement(SHLIB1, s->item);
		if (ret == SQLITE_DONE)
			ret = pkg_repo_binary_run_prstatement(SHLIB_PROV, package_id,
-
			    it.key);
+
			    s->item);
		if (ret != SQLITE_DONE) {
			ERROR_SQLITE(sqlite, pkg_repo_binary_sql_prstatement(SHLIB_PROV));
			return (EPKG_FATAL);
		}
	}

-
	it = pkghash_iterator(pkg->provides);
-
	while (pkghash_next(&it)) {
-
		ret = pkg_repo_binary_run_prstatement(PROVIDE, it.key);
+
	tll_foreach(pkg->provides, p) {
+
		ret = pkg_repo_binary_run_prstatement(PROVIDE, p->item);
		if (ret == SQLITE_DONE)
			ret = pkg_repo_binary_run_prstatement(PROVIDES, package_id,
-
			    it.key);
+
			    p->item);
		if (ret != SQLITE_DONE) {
			ERROR_SQLITE(sqlite, pkg_repo_binary_sql_prstatement(PROVIDES));
			return (EPKG_FATAL);
		}
	}

-
	it = pkghash_iterator(pkg->requires);
-
	while (pkghash_next(&it)) {
-
		ret = pkg_repo_binary_run_prstatement(REQUIRE, it.key);
+
	tll_foreach(pkg->requires, r) {
+
		ret = pkg_repo_binary_run_prstatement(REQUIRE, r->item);
		if (ret == SQLITE_DONE)
			ret = pkg_repo_binary_run_prstatement(REQUIRES, package_id,
-
			    it.key);
+
			    r->item);
		if (ret != SQLITE_DONE) {
			ERROR_SQLITE(sqlite, pkg_repo_binary_sql_prstatement(REQUIRES));
			return (EPKG_FATAL);
modified src/check.c
@@ -58,8 +58,10 @@ check_deps(struct pkgdb *db, struct pkg *p, deps_entries *dh, bool noinstall, xs
{
	struct pkg_dep *dep = NULL;
	struct pkgdb_it *it;
-
	char *buf = NULL;
+
	const char *buf;
	int nbpkgs = 0;
+
	struct pkg_stringlist	*sl;
+
	struct pkg_stringlist_iterator	*slit;

	assert(db != NULL);
	assert(p != NULL);
@@ -78,8 +80,9 @@ check_deps(struct pkgdb *db, struct pkg *p, deps_entries *dh, bool noinstall, xs
	}

	/* checking libraries required */
-
	buf = NULL;
-
	while (pkg_shlibs_required(p, &buf) == EPKG_OK) {
+
	pkg_get_stringlist(p, PKG_SHLIBS_REQUIRED, sl);
+
	slit = pkg_stringlist_iterator(sl);
+
	while ((buf = pkg_stringlist_next(slit))) {
		it = pkgdb_query_shlib_provide(db, buf);
		if (it != NULL && pkgdb_it_count(it) > 0) {
			pkgdb_it_free(it);
@@ -92,10 +95,14 @@ check_deps(struct pkgdb *db, struct pkg *p, deps_entries *dh, bool noinstall, xs
			pkg_fprintf(out->fp, "%n is missing a required shared library: %S\n",
			    p, buf);
	}
+
	free(slit);
+
	free(sl);

	/* checking requires */
	buf = NULL;
-
	while (pkg_requires(p, &buf) == EPKG_OK) {
+
	pkg_get_stringlist(p, PKG_REQUIRES, sl);
+
	slit = pkg_stringlist_iterator(sl);
+
	while ((buf = pkg_stringlist_next(slit))) {
		it = pkgdb_query_provide(db, buf);
		if (it != NULL && pkgdb_it_count(it) > 0) {
			pkgdb_it_free(it);
@@ -108,6 +115,8 @@ check_deps(struct pkgdb *db, struct pkg *p, deps_entries *dh, bool noinstall, xs
			pkg_fprintf(out->fp, "%n has a missing requirement: %S\n",
			    p, buf);
	}
+
	free(slit);
+
	free(sl);

	return (nbpkgs);
}
modified src/query.c
@@ -346,7 +346,6 @@ print_query(struct pkg *pkg, char *qstr, char multiline)
	struct pkg_option	*option = NULL;
	struct pkg_file		*file   = NULL;
	struct pkg_dir		*dir    = NULL;
-
	char			*buf;
	const char		*str;
	struct pkg_kv		*kv;
	struct pkg_stringlist	*sl;
@@ -370,7 +369,6 @@ print_query(struct pkg *pkg, char *qstr, char multiline)
		}
		break;
	case 'C':
-
		buf = NULL;
		pkg_get_stringlist(pkg, PKG_CATEGORIES, sl);
		slit = pkg_stringlist_iterator(sl);
		while ((str = pkg_stringlist_next(slit))) {
@@ -399,7 +397,6 @@ print_query(struct pkg *pkg, char *qstr, char multiline)
		}
		break;
	case 'L':
-
		buf = NULL;
		pkg_get_stringlist(pkg, PKG_LICENSES, sl);
		slit = pkg_stringlist_iterator(sl);
		while ((str = pkg_stringlist_next(slit))) {
@@ -410,30 +407,34 @@ print_query(struct pkg *pkg, char *qstr, char multiline)
		free(sl);
		break;
	case 'U':
-
		buf = NULL;
-
		while (pkg_users(pkg, &buf) == EPKG_OK) {
-
			format_str(pkg, output, qstr, buf);
+
		pkg_get_stringlist(pkg, PKG_USERS, sl);
+
		slit = pkg_stringlist_iterator(sl);
+
		while ((str = pkg_stringlist_next(slit))) {
+
			format_str(pkg, output, qstr, str);
			printf("%s\n", output->buf);
		}
		break;
	case 'G':
-
		buf = NULL;
-
		while (pkg_groups(pkg, &buf) == EPKG_OK) {
-
			format_str(pkg, output, qstr, buf);
+
		pkg_get_stringlist(pkg, PKG_GROUPS, sl);
+
		slit = pkg_stringlist_iterator(sl);
+
		while ((str = pkg_stringlist_next(slit))) {
+
			format_str(pkg, output, qstr, str);
			printf("%s\n", output->buf);
		}
		break;
	case 'B':
-
		buf = NULL;
-
		while (pkg_shlibs_required(pkg, &buf) == EPKG_OK) {
-
			format_str(pkg, output, qstr, buf);
+
		pkg_get_stringlist(pkg, PKG_SHLIBS_REQUIRED, sl);
+
		slit = pkg_stringlist_iterator(sl);
+
		while ((str = pkg_stringlist_next(slit))) {
+
			format_str(pkg, output, qstr, str);
			printf("%s\n", output->buf);
		}
		break;
	case 'b':
-
		buf = NULL;
-
		while (pkg_shlibs_provided(pkg, &buf) == EPKG_OK) {
-
			format_str(pkg, output, qstr, buf);
+
		pkg_get_stringlist(pkg, PKG_SHLIBS_PROVIDED, sl);
+
		slit = pkg_stringlist_iterator(sl);
+
		while ((str = pkg_stringlist_next(slit))) {
+
			format_str(pkg, output, qstr, str);
			printf("%s\n", output->buf);
		}
		break;