Radish alpha
H
rad:z3QDZAW2FAfuLvihrhiyDC9fAD8G9
HardenedBSD Package Manager
Radicle
Git
API: replace generic pkg_get with typesafe version
Baptiste Daroussin committed 4 years ago
commit 7bb8d7ea08ef61e5b2c46c025e45c535a98d06b6
parent 2fd3368
13 files changed +237 -49
modified libpkg/libpkg.ver
@@ -1,5 +1,9 @@
LIBPKG_1.4 {
global:
+
	pkg_kvlist_iterator;
+
	pkg_kvlist_next;
+
	pkg_stringlist_iterator;
+
	pkg_stringlist_next;
	pkg_absolutepath;
	pkg_add;
	pkg_add_from_remote;
modified libpkg/pkg.h.in
@@ -539,6 +539,62 @@ typedef enum {
	PKG_SOLVED_UPGRADE_INSTALL
} pkg_solved_t;

+
struct pkg_kvlist;
+
struct pkg_stringlist;
+

+
typedef enum {
+
	PKG_KVLIST = 1U,
+
	PKG_STRINGLIST,
+
	PKG_STR,
+
	PKG_INTEGER,
+
	PKG_BOOLEAN,
+
} pkg_el_t;
+

+
#define pkg_get_string(p, t, v) do { \
+
	struct pkg_el *e = pkg_get_element(p, t); \
+
	if (e->type != PKG_STR) abort(); \
+
	v = e->string; \
+
	free(e); \
+
} while (0);
+

+
#define pkg_get_bool(p, t, v) do { \
+
	struct pkg_el *e = pkg_get_element(p, t); \
+
	if (e->type != PKG_BOOLEAN) abort(); \
+
	v = e->boolean; \
+
	free(e); \
+
} while (0);
+

+
#define pkg_get_int(p, t, v) do { \
+
	struct pkg_el *e = pkg_get_element(p, t); \
+
	if (e->type != PKG_INTEGER) abort(); \
+
	v = e->integer; \
+
	free(e); \
+
} while (0);
+

+
#define pkg_get_kv(p, t, v) do { \
+
	struct pkg_el *e = pkg_get_element(p, t); \
+
	if (e->type != PKG_KVLIST) abort(); \
+
	v = e->kvlist; \
+
	free(e); \
+
} while (0);
+

+
#define pkg_get_stringlist(p, t, v) do { \
+
	struct pkg_el *e = pkg_get_element(p, t); \
+
	if (e->type != PKG_STRINGLIST) abort(); \
+
	v = e->kvlist; \
+
} while (0);
+

+
struct pkg_el {
+
	union {
+
		struct pkg_kvlist *kvlist;
+
		struct pkg_stringlist *stringlist;
+
		const char *string;
+
		int64_t integer;
+
		bool boolean;
+
	};
+
	pkg_el_t type;
+
};
+

#define PKG_OPEN_MANIFEST_ONLY 0x1
#define PKG_OPEN_MANIFEST_COMPACT (0x1 << 1)
#define PKG_OPEN_TRY (0x1 << 2)
@@ -1664,6 +1720,12 @@ int pkgdb_register_ports(struct pkgdb *db, struct pkg *pkg) __attribute__((depre
int pkg_execute_deferred_triggers(void);
int pkg_add_triggers(void);

+
struct pkg_kvlist_iterator *pkg_kvlist_iterator(struct pkg_kvlist *l);
+
struct pkg_kv *pkg_kvlist_next(struct pkg_kvlist_iterator *it);
+
struct pkg_stringlist_iterator *pkg_stringlist_iterator(struct pkg_stringlist *l);
+
const char *pkg_stringlist_next(struct pkg_stringlist_iterator *it);
+
struct pkg_el *pkg_get_element(struct pkg *p, pkg_attr a);
+

#ifdef __cplusplus
}
#endif
modified libpkg/pkg_attributes.c
@@ -172,3 +172,113 @@ pkg_kv_free(struct pkg_kv *c)
	free(c->value);
	free(c);
}
+

+
struct pkg_kvlist_iterator *
+
pkg_kvlist_iterator(struct pkg_kvlist *l)
+
{
+
	struct pkg_kvlist_iterator *it = xcalloc(1, sizeof(struct pkg_kvlist_iterator));
+
	it->list = l->list;
+
	return (it);
+
};
+

+
struct pkg_kv *
+
pkg_kvlist_next(struct pkg_kvlist_iterator *it)
+
{
+
	if (it->cur == NULL)
+
		it->cur = it->list->head;
+
	else
+
		it->cur = ((__typeof__(it->list->head))it->cur)->next;
+
	if (it->cur == NULL)
+
		return (NULL);
+
	return (((__typeof__(it->list->head))it->cur)->item);
+
}
+

+
struct pkg_stringlist_iterator *
+
pkg_stringlist_iterator(struct pkg_stringlist *l)
+
{
+
	struct pkg_stringlist_iterator *it = xcalloc(1, sizeof(struct pkg_stringlist_iterator));
+
	it->list = l->list;
+
	return (it);
+
};
+

+
const char *
+
pkg_stringlist_next(struct pkg_stringlist_iterator *it)
+
{
+
	if (it->cur == NULL)
+
		it->cur = it->list->head;
+
	else
+
		it->cur = ((__typeof__(it->list->head))it->cur)->next;
+
	if (it->cur == NULL)
+
		return (NULL);
+
	return (((__typeof__(it->list->head))it->cur)->item);
+
}
+

+
struct pkg_el *
+
pkg_get_element(struct pkg *p, pkg_attr a)
+
{
+
	struct pkg_el *e = xcalloc(1, sizeof(*e));
+

+
	switch (a) {
+
	case PKG_NAME:
+
		e->string = p->name;
+
		e->type = PKG_STR;
+
		break;
+
	case PKG_VERSION:
+
		e->string = p->version;
+
		e->type = PKG_STR;
+
		break;
+
	case PKG_ORIGIN:
+
		e->string = p->origin;
+
		e->type = PKG_STR;
+
		break;
+
	case PKG_UNIQUEID:
+
		e->string = p->uid;
+
		e->type = PKG_STR;
+
		break;
+
	case PKG_CKSUM:
+
		e->string = p->sum;
+
		e->type = PKG_STR;
+
		break;
+
	case PKG_REPONAME:
+
		e->string = p->reponame;
+
		e->type = PKG_STR;
+
		break;
+
	case PKG_REPOPATH:
+
		e->string = p->repopath;
+
		e->type = PKG_STR;
+
		break;
+
	case PKG_REPOURL:
+
		e->string = p->repourl;
+
		e->type = PKG_STR;
+
		break;
+
	case PKG_REASON:
+
		e->string = p->reason;
+
		e->type = PKG_STR;
+
		break;
+
	case PKG_AUTOMATIC:
+
		e->boolean = p->automatic;
+
		e->type = PKG_BOOLEAN;
+
		break;
+
	case PKG_LOCKED:
+
		e->boolean = p->locked;
+
		e->type = PKG_BOOLEAN;
+
		break;
+
	case PKG_VITAL:
+
		e->boolean = p->vital;
+
		e->type = PKG_BOOLEAN;
+
		break;
+
	case PKG_FLATSIZE:
+
		e->integer = p->flatsize;
+
		e->type = PKG_INTEGER;
+
		break;
+
	case PKG_OLD_FLATSIZE:
+
		e->integer = p->old_flatsize;
+
		e->type = PKG_INTEGER;
+
		break;
+
	case PKG_PKGSIZE:
+
		e->integer = p->pkgsize;
+
		e->type = PKG_INTEGER;
+
		break;
+
	}
+
	return (e);
+
}
modified libpkg/private/pkg.h
@@ -127,6 +127,27 @@
} while (0)
#define DL_FREE(head, free_func) DL_FREE2(head, free_func, prev, next)

+
typedef tll(struct pkg_kv *) kvlist_t;
+
typedef tll(char *) stringlist_t;
+

+
struct pkg_kvlist {
+
	kvlist_t *list;
+
};
+

+
struct pkg_stringlist {
+
	stringlist_t *list;
+
};
+

+
struct pkg_kvlist_iterator {
+
	kvlist_t *list;
+
	void *cur;
+
};
+

+
struct pkg_stringlist_iterator {
+
	stringlist_t *list;
+
	void *cur;
+
};
+

struct pkg_ctx {
	int eventpipe;
	int64_t debug_level;
@@ -157,9 +178,6 @@ struct pkg_repo;
struct pkg_message;
struct pkg_lua_script;

-
typedef tll(struct pkg_kv *) kvlist_t;
-
typedef tll(char *) stringlist_t;
-

struct pkg {
	bool		 direct;
	bool		 locked;
@@ -693,7 +711,6 @@ int pkgdb_set_pkg_digest(struct pkgdb *db, struct pkg *pkg);
int pkgdb_is_dir_used(struct pkgdb *db, struct pkg *p, const char *dir, int64_t *res);
int pkgdb_file_set_cksum(struct pkgdb *db, struct pkg_file *file, const char *sha256);

-

int pkg_emit_manifest_buf(struct pkg*, xstring *, short, char **);
int pkg_emit_filelist(struct pkg *, FILE *);

@@ -712,7 +729,7 @@ int pkg_checksum_generate(struct pkg *pkg, char *dest, size_t destlen,
 * Caller must free resulting hash after usage
 */
unsigned char * pkg_checksum_data(const unsigned char *in, size_t inlen,
-
	pkg_checksum_type_t type);
+
    pkg_checksum_type_t type);
unsigned char *pkg_checksum_fd(int fd, pkg_checksum_type_t type);
unsigned char *pkg_checksum_file(const char *path, pkg_checksum_type_t type);
unsigned char *pkg_checksum_fileat(int fd, const char *path,
modified src/audit.c
@@ -80,7 +80,7 @@ add_to_check(pkghash *check, struct pkg *pkg)
{
	const char *uid;

-
	pkg_get(pkg, PKG_UNIQUEID, &uid);
+
	pkg_get_string(pkg, PKG_UNIQUEID, uid);
	pkghash_safe_add(check, uid, pkg, NULL);
}

@@ -123,7 +123,7 @@ print_issue(struct pkg *p, struct pkg_audit_issue *issue)
	const struct pkg_audit_entry *e;
	struct pkg_audit_cve *cve;

-
	pkg_get(p, PKG_VERSION, &version);
+
	pkg_get_string(p, PKG_VERSION, version);

	e = issue->audit;
	if (version == NULL) {
@@ -152,16 +152,14 @@ print_issue(struct pkg *p, struct pkg_audit_issue *issue)
}

static void
-
format_issue(struct pkg *p, struct pkg_audit_issue *issue, ucl_object_t *array)
+
format_issue(struct pkg_audit_issue *issue, ucl_object_t *array)
{
-
	const char *version;
	struct pkg_audit_versions_range *vers;
	const struct pkg_audit_entry *e;
	struct pkg_audit_cve *cve;
	ucl_object_t *o = ucl_object_typed_new(UCL_OBJECT);
	ucl_object_t *affected_versions = ucl_object_typed_new(UCL_ARRAY);

-
	pkg_get(p, PKG_VERSION, &version);
	ucl_array_append(array, o);

	e = issue->audit;
@@ -400,7 +398,7 @@ exec_audit(int argc, char **argv)

				if (top == NULL) {
					affected += issues->count;
-
					pkg_get(pkg, PKG_VERSION, &version);
+
					pkg_get_string(pkg, PKG_VERSION, version);
					if (quiet) {
						if (version != NULL)
							pkg_printf("%n-%v\n", pkg, pkg);
@@ -419,7 +417,8 @@ exec_audit(int argc, char **argv)
					if (vuln_objs == NULL)
						vuln_objs = ucl_object_typed_new(UCL_OBJECT);
					obj = ucl_object_typed_new(UCL_OBJECT);
-
					pkg_get(pkg, PKG_NAME, &name, PKG_VERSION, &version);
+
					pkg_get_string(pkg, PKG_NAME, name);
+
					pkg_get_string(pkg, PKG_VERSION, version);
					if (version != NULL)
						ucl_object_insert_key(obj, ucl_object_fromstring(version), "version", 7 , false);
					ucl_object_insert_key(obj, ucl_object_fromint(issues->count), "issue_count", 11, false);
@@ -431,7 +430,7 @@ exec_audit(int argc, char **argv)
					if (top == NULL)
						print_issue(pkg, issue);
					else
-
						format_issue(pkg, issue, array);
+
						format_issue(issue, array);
				}
				if (top != NULL)
					ucl_object_insert_key(obj, array, "issues", 6, false);
@@ -441,7 +440,7 @@ exec_audit(int argc, char **argv)
					pkghash *seen = pkghash_new();

					if (name == NULL)
-
						pkg_get(pkg, PKG_NAME, &name);
+
						pkg_get_string(pkg, PKG_NAME, name);
					if (top == NULL) {
						printf("  Packages that depend on %s: ", name);
					} else {
modified src/clean.c
@@ -154,7 +154,7 @@ populate_sums(struct pkgdb *db)
	suml = pkghash_new();
	it = pkgdb_repo_search(db, "*", MATCH_GLOB, FIELD_NAME, FIELD_NONE, NULL);
	while (pkgdb_it_next(it, &p, PKG_LOAD_BASIC) == EPKG_OK) {
-
		pkg_get(p, PKG_CKSUM, &sum);
+
		pkg_get_string(p, PKG_CKSUM, sum);
		slen = MIN(strlen(sum), PKG_FILE_CKSUM_CHARS);
		cksum = strndup(sum, slen);
		pkghash_safe_add(suml, cksum, NULL, NULL);
modified src/event.c
@@ -876,14 +876,14 @@ event_callback(void *data, struct pkg_event *ev)
		pkg_fprintf(conflicts->fp, "  - %n-%v",
		    ev->e_conflicts.p1, ev->e_conflicts.p1);
		if (pkg_repos_total_count() > 1) {
-
			pkg_get(ev->e_conflicts.p1, PKG_REPONAME, &reponame);
+
			pkg_get_string(ev->e_conflicts.p1, PKG_REPONAME, reponame);
			fprintf(conflicts->fp, " [%s]",
			    reponame == NULL ? "installed" : reponame);
		}
		pkg_fprintf(conflicts->fp, " conflicts with %n-%v",
		    ev->e_conflicts.p2, ev->e_conflicts.p2);
		if (pkg_repos_total_count() > 1) {
-
			pkg_get(ev->e_conflicts.p2, PKG_REPONAME, &reponame);
+
			pkg_get_string(ev->e_conflicts.p2, PKG_REPONAME, reponame);
			fprintf(conflicts->fp, " [%s]",
			    reponame == NULL ? "installed" : reponame);
		}
modified src/info.c
@@ -451,7 +451,7 @@ exec_info(int argc, char **argv)
			gotone = true;
			const char *version;

-
			pkg_get(pkg, PKG_VERSION, &version);
+
			pkg_get_string(pkg, PKG_VERSION, version);
			if (pkgversion != NULL) {
				switch (pkg_version_cmp(version, pkgversion)) {
				case -1:
modified src/query.c
@@ -115,11 +115,11 @@ format_str(struct pkg *pkg, xstring *dest, const char *qstr, const void *data)
				pkg_fprintf(dest->fp, "%w", pkg);
				break;
			case 'a':
-
				pkg_get(pkg, PKG_AUTOMATIC, &automatic);
+
				pkg_get_bool(pkg, PKG_AUTOMATIC, automatic);
				fprintf(dest->fp, "%d", automatic);
				break;
			case 'k':
-
				pkg_get(pkg, PKG_LOCKED, &locked);
+
				pkg_get_bool(pkg, PKG_LOCKED, locked);
				fprintf(dest->fp, "%d", locked);
				break;
			case 't':
@@ -129,7 +129,7 @@ format_str(struct pkg *pkg, xstring *dest, const char *qstr, const void *data)
				qstr++;
				if (qstr[0] == 'h')
					pkg_fprintf(dest->fp, "%#sB", pkg);
-
			        else if (qstr[0] == 'b')
+
				else if (qstr[0] == 'b')
					pkg_fprintf(dest->fp, "%s", pkg);
				break;
			case 'e':
@@ -295,7 +295,7 @@ format_str(struct pkg *pkg, xstring *dest, const char *qstr, const void *data)
					pkg_fprintf(dest->fp, "%M", pkg);
				break;
			case 'V':
-
				pkg_get(pkg, PKG_VITAL, &vital);
+
				pkg_get_bool(pkg, PKG_VITAL, vital);
				fprintf(dest->fp, "%d", vital);
				break;
			case 'X':
modified src/set.c
@@ -294,7 +294,7 @@ exec_set(int argc, char **argv)
		while (pkgdb_it_next(it, &pkg, loads) == EPKG_OK) {
			gotone = true;
			if ((sets & AUTOMATIC) == AUTOMATIC) {
-
				pkg_get(pkg, PKG_AUTOMATIC, &automatic);
+
				pkg_get_bool(pkg, PKG_AUTOMATIC, automatic);
				if (automatic == newautomatic)
					continue;
				if (!rc) {
@@ -312,7 +312,7 @@ exec_set(int argc, char **argv)
				rc = saved_rc;
			}
			if ((sets & VITAL) == VITAL) {
-
				pkg_get(pkg, PKG_VITAL, &vital);
+
				pkg_get_bool(pkg, PKG_VITAL, vital);
				if (vital == newvital)
					continue;
				if (!rc) {
modified src/upgrade.c
@@ -66,7 +66,7 @@ add_to_check(pkghash *check, struct pkg *pkg)
{
	const char *uid;

-
	pkg_get(pkg, PKG_UNIQUEID, &uid);
+
	pkg_get_string(pkg, PKG_UNIQUEID, uid);
	pkghash_safe_add(check, uid, pkg, NULL);
}

@@ -141,7 +141,7 @@ check_vulnerable(struct pkg_audit *audit, struct pkgdb *db, int sock)
				issues = NULL;
				pkg = (struct pkg *)hit.value;
				if (pkg_audit_is_vulnerable(audit, pkg, &issues, true)) {
-
					pkg_get(pkg, PKG_UNIQUEID, &uid);
+
					pkg_get_string(pkg, PKG_UNIQUEID, uid);
					fprintf(out, "%s\n", uid);
					fflush(out);
				}
modified src/utils.c
@@ -331,18 +331,13 @@ print_info(struct pkg * const pkg, uint64_t options)
{
	bool print_tag = false;
	bool show_locks = false;
-
	const char *repourl;
+
	const char *repourl = NULL;
	unsigned opt;
-
	int64_t flatsize, oldflatsize, pkgsize;
	int cout = 0;		/* Number of characters output */
	int info_num;		/* Number of different data items to print */
	int outflags = PKG_MANIFEST_EMIT_LOCAL_METADATA;

-
	pkg_get(pkg,
-
		PKG_REPOURL,       &repourl,
-
		PKG_FLATSIZE,      &flatsize,
-
		PKG_OLD_FLATSIZE,  &oldflatsize,
-
		PKG_PKGSIZE,       &pkgsize);
+
	pkg_get_string(pkg, PKG_REPOURL, repourl);

	if (options & INFO_RAW) {
		switch (options & (INFO_RAW_YAML|INFO_RAW_JSON|INFO_RAW_JSON_COMPACT|INFO_RAW_UCL)) {
@@ -697,7 +692,7 @@ set_jobs_summary_pkg(struct pkg_jobs *jobs, struct pkg *new_pkg,
    int64_t *newsize, int64_t *dlsize, pkg_solved_display_t *disp,
    struct jobs_sum_number *sum)
{
-
	const char *oldversion, *repopath, *destdir;
+
	const char *repopath, *destdir;
	char path[MAXPATHLEN];
	int ret;
	struct stat st;
@@ -705,12 +700,12 @@ set_jobs_summary_pkg(struct pkg_jobs *jobs, struct pkg *new_pkg,
	struct pkg_solved_display *it;

	flatsize = oldflatsize = pkgsize = 0;
-
	oldversion = NULL;

-
	pkg_get(new_pkg, PKG_FLATSIZE, &flatsize, PKG_PKGSIZE, &pkgsize,
-
		PKG_REPOPATH, &repopath);
+
	pkg_get_int(new_pkg, PKG_FLATSIZE, flatsize);
+
	pkg_get_int(new_pkg, PKG_PKGSIZE, pkgsize);
+
	pkg_get_string(new_pkg, PKG_REPOPATH, repopath);
	if (old_pkg != NULL)
-
		pkg_get(old_pkg, PKG_VERSION, &oldversion, PKG_FLATSIZE, &oldflatsize);
+
		pkg_get_int(old_pkg, PKG_FLATSIZE, oldflatsize);

	it = malloc(sizeof (*it));
	if (it == NULL) {
@@ -821,7 +816,7 @@ display_summary_item(struct pkg_solved_display *it, int64_t dlsize)
	char size[8], tlsize[8];
	const char *type;

-
	pkg_get(it->new, PKG_PKGSIZE, &pkgsize);
+
	pkg_get_int(it->new, PKG_PKGSIZE, pkgsize);

	switch (it->display_type) {
	case PKG_DISPLAY_LOCKED:
@@ -860,7 +855,7 @@ display_summary_item(struct pkg_solved_display *it, int64_t dlsize)
		}
		break;
	case PKG_DISPLAY_DELETE:
-
		pkg_get(it->new, PKG_REASON, &why);
+
		pkg_get_string(it->new, PKG_REASON, why);
		pkg_printf("\t%n: %v", it->new, it->new);
		if (why != NULL)
			printf(" (%s)", why);
@@ -885,7 +880,7 @@ display_summary_item(struct pkg_solved_display *it, int64_t dlsize)
		printf("\n");
		break;
	case PKG_DISPLAY_REINSTALL:
-
		pkg_get(it->new, PKG_REASON, &why);
+
		pkg_get_string(it->new, PKG_REASON, why);
		pkg_printf("\t%n-%v", it->new, it->new);
		if (pkg_repos_total_count() > 1)
			pkg_printf(" [%N]", it->new);
@@ -1055,11 +1050,9 @@ drop_privileges(void)
int
print_pkg(struct pkg *p, void *ctx)
{
-
	const char *name;
	int *counter = ctx;

-
	pkg_get(p, PKG_NAME, &name);
-
	printf("\t%s\n", name);
+
	pkg_printf("\t%n\n", p);
	(*counter)++;

	return 0;
modified src/version.c
@@ -84,7 +84,7 @@ print_version(struct pkg *pkg, const char *source, const char *ver,
	const char	*version;
	int		 cout;

-
	pkg_get(pkg, PKG_VERSION, &version);
+
	pkg_get_string(pkg, PKG_VERSION, version);
	if (ver == NULL) {
		if (source == NULL)
			key = "!";
@@ -424,7 +424,8 @@ do_source_index(unsigned int opt, char limchar, char *pattern, match_t match,
		goto cleanup;

	while (pkgdb_it_next(it, &pkg, PKG_LOAD_BASIC) == EPKG_OK) {
-
		pkg_get(pkg, PKG_NAME, &name, PKG_ORIGIN, &origin);
+
		pkg_get_string(pkg, PKG_NAME, name);
+
		pkg_get_string(pkg, PKG_ORIGIN, origin);

		/* If -O was specified, check if this origin matches */
		if ((opt & VERSION_WITHORIGIN) &&
@@ -499,7 +500,8 @@ do_source_remote(unsigned int opt, char limchar, char *pattern, match_t match,
	}

	while (pkgdb_it_next(it, &pkg, PKG_LOAD_BASIC) == EPKG_OK) {
-
		pkg_get(pkg, PKG_NAME, &name, PKG_ORIGIN, &origin);
+
		pkg_get_string(pkg, PKG_NAME, name);
+
		pkg_get_string(pkg, PKG_ORIGIN, origin);

		/* If -O was specified, check if this origin matches */
		if ((opt & VERSION_WITHORIGIN) &&
@@ -523,7 +525,7 @@ do_source_remote(unsigned int opt, char limchar, char *pattern, match_t match,

		if (pkgdb_it_next(it_remote, &pkg_remote, PKG_LOAD_BASIC)
		    == EPKG_OK) {
-
			pkg_get(pkg_remote, PKG_VERSION, &version_remote);
+
			pkg_get_string(pkg_remote, PKG_VERSION, version_remote);
			print_version(pkg, "remote", version_remote, limchar,
			    opt);
		} else {
@@ -746,7 +748,8 @@ do_source_ports(unsigned int opt, char limchar, char *pattern, match_t match,
	cmd = xstring_new();

	while (pkgdb_it_next(it, &pkg, PKG_LOAD_BASIC) == EPKG_OK) {
-
		pkg_get(pkg, PKG_NAME, &name, PKG_ORIGIN, &origin);
+
		pkg_get_string(pkg, PKG_NAME, name);
+
		pkg_get_string(pkg, PKG_ORIGIN, origin);

		/* If -O was specified, check if this origin matches */
		if ((opt & VERSION_WITHORIGIN) &&