Radish alpha
H
rad:z3QDZAW2FAfuLvihrhiyDC9fAD8G9
HardenedBSD Package Manager
Radicle
Git
Propagate usage of ucl
Baptiste Daroussin committed 12 years ago
commit 99f9cd1a2c9273d5995b47ffecbc240b236fe9b0
parent 1e038a8
43 files changed +522 -1180
modified libpkg/fetch.c
@@ -279,7 +279,7 @@ start_ssh(struct pkg_repo *repo, struct url *u, off_t *sz)
	int sshout[2];
	const char *argv[4];

-
	pkg_config_string(PKG_CONFIG_SSH_ARGS, &ssh_args);
+
	ssh_args = pkg_object_string(pkg_config_get("PKG_SSH_ARGS"));

	if (repo->ssh == NULL) {
		/* Use socket pair because pipe have blocking issues */
@@ -406,11 +406,8 @@ pkg_fetch_file_to_fd(struct pkg_repo *repo, const char *url, int dest, time_t *t
	off_t		 sz = 0;
	bool		 pkg_url_scheme = false;

-
	if (pkg_config_int64(PKG_CONFIG_FETCH_RETRY, &max_retry) == EPKG_FATAL)
-
		max_retry = 3;
-

-
	if (pkg_config_int64(PKG_CONFIG_FETCH_TIMEOUT, &fetch_timeout) == EPKG_FATAL)
-
		fetch_timeout = 30;
+
	max_retry = pkg_object_int(pkg_config_get("FETCH_RETRY"));
+
	fetch_timeout = pkg_object_int(pkg_config_get("FETCH_TIMEOUT"));

	fetchTimeout = (int) fetch_timeout;

modified libpkg/packing.c
@@ -212,7 +212,7 @@ packing_append_file_attr(struct packing *pack, const char *filepath,
	if (perm != 0)
		archive_entry_set_perm(entry, perm);

-
	pkg_config_bool(PKG_CONFIG_UNSET_TIMESTAMP, &unset_timestamp);
+
	unset_timestamp = pkg_object_bool(pkg_config_get("UNSET_TIMESTAMP"));

	if (unset_timestamp) {
		archive_entry_unset_atime(entry);
modified libpkg/pkg.c
@@ -1400,12 +1400,12 @@ pkg_copy_tree(struct pkg *pkg, const char *src, const char *dest)
	struct pkg_dir *dir = NULL;
	char spath[MAXPATHLEN];
	char dpath[MAXPATHLEN];
-
	bool disable_mtree;
	const char *prefix;
	char *mtree;
+
	pkg_object *o;

-
	pkg_config_bool(PKG_CONFIG_DISABLE_MTREE, &disable_mtree);
-
	if (!disable_mtree) {
+
	o = pkg_config_get("DISABLE_MTREE");
+
	if (o && !pkg_object_bool(o)) {
		pkg_get(pkg, PKG_PREFIX, &prefix, PKG_MTREE, &mtree);
		do_extract_mtree(mtree, prefix);
	}
modified libpkg/pkg.h.in
@@ -78,15 +78,14 @@ struct pkg_solve_problem;

struct pkg_repo;

-
struct pkg_config;
-
struct pkg_config_kv;
-
struct pkg_config_value;
-

struct pkg_plugin;

struct pkg_manifest_key;
struct pkg_manifest_parser;

+
typedef struct ucl_object_s pkg_object;
+
typedef void * pkg_iter;
+

/**
 * The system-wide pkg(8) status: ie. is it a) installed or otherwise
 * available on the sysem, b) database (local.sqlite) initialised and
@@ -375,11 +374,6 @@ typedef enum _pkg_config_key {
	PKG_CONFIG_SAT_SOLVER,
} pkg_config_key;

-
typedef enum {
-
	PKG_CONFIG_KV_KEY,
-
	PKG_CONFIG_KV_VALUE
-
} pkg_config_kv_t;
-

typedef enum _pkg_stats_t {
	PKG_STATS_LOCAL_COUNT = 0,
	PKG_STATS_LOCAL_SIZE,
@@ -390,12 +384,13 @@ typedef enum _pkg_stats_t {
} pkg_stats_t;

typedef enum {
-
	PKG_CONFIG_STRING=0,
-
	PKG_CONFIG_BOOL,
-
	PKG_CONFIG_KVLIST,
-
	PKG_CONFIG_INTEGER,
-
	PKG_CONFIG_LIST
-
} pkg_config_t;
+
	PKG_STRING = 0,
+
	PKG_BOOL,
+
	PKG_INT,
+
	PKG_ARRAY,
+
	PKG_OBJECT,
+
	PKG_NULL
+
} pkg_object_t;

/**
 * Keys for accessing pkg plugin data
@@ -1316,18 +1311,12 @@ int pkg_plugin_set(struct pkg_plugin *p, pkg_plugin_key key, const char *str);
const char *pkg_plugin_get(struct pkg_plugin *p, pkg_plugin_key key);
void *pkg_plugin_func(struct pkg_plugin *p, const char *func);

-
int pkg_plugin_conf_add_string(struct pkg_plugin *p, int id, const char *key, const char *def);
-
int pkg_plugin_conf_add_bool(struct pkg_plugin *p, int id, const char *key, bool val);
-
int pkg_plugin_conf_add_integer(struct pkg_plugin *p, int id, const char *key, int64_t integer);
-
int pkg_plugin_conf_add_kvlist(struct pkg_plugin *p, int id, const char *key);
-
int pkg_plugin_conf_add_list(struct pkg_plugin *p, int id, const char *key);
-

-
int pkg_plugin_conf_string(struct pkg_plugin *p, int key, const char **value);
-
int pkg_plugin_conf_bool(struct pkg_plugin *p, int key, bool *value);
-
int pkg_plugin_conf_kvlist(struct pkg_plugin *p, int key, struct pkg_config_kv **kv);
-
int pkg_plugin_conf_list(struct pkg_plugin *p, int key, struct pkg_config_value **v);
-
int pkg_plugin_conf_integer(struct pkg_plugin *p, int key, int64_t *value);
-
int pkg_plugin_confs(struct pkg_plugin *p, struct pkg_config **conf);
+
int pkg_plugin_conf_add_string(struct pkg_plugin *p, const char *key, const char *def);
+
int pkg_plugin_conf_add_bool(struct pkg_plugin *p, const char *key, bool val);
+
int pkg_plugin_conf_add_integer(struct pkg_plugin *p, const char *key, int64_t integer);
+
int pkg_plugin_conf_add_kvlist(struct pkg_plugin *p, const char *key);
+
int pkg_plugin_conf_add_list(struct pkg_plugin *p, const char *key);
+
pkg_object *pkg_plugin_conf(struct pkg_plugin *p);

int pkg_plugin_parse(struct pkg_plugin *p);
void pkg_plugin_errno(struct pkg_plugin *p, const char *func, const char *arg);
@@ -1344,19 +1333,18 @@ int pkg_plugin_hook_register(struct pkg_plugin *p, pkg_plugin_hook_t hook, pkg_p
/**
 * Get the value of a configuration key
 */
-
int pkg_config_desc(pkg_config_key key, const char **value);
-
int pkg_config_string(pkg_config_key key, const char **value);
-
int pkg_config_bool(pkg_config_key key, bool *value);
-
int pkg_config_kvlist(pkg_config_key key, struct pkg_config_kv **kv);
-
int pkg_config_list(pkg_config_key key, struct pkg_config_value **v);
-
const char *pkg_config_kv_get(struct pkg_config_kv *kv, pkg_config_kv_t type);
-
const char *pkg_config_value(struct pkg_config_value *v);
-
int pkg_config_int64(pkg_config_key key, int64_t *value);
-
int pkg_configs(struct pkg_config **c);
-
int pkg_config_id(struct pkg_config *c);
-
int pkg_config_type(struct pkg_config *c);
-
const char *pkg_config_name(struct pkg_config *c);
-
struct pkg_config *pkg_config_lookup(const char *name);
+

+
pkg_object *pkg_conf(void);
+
pkg_object *pkg_config_get(const char *);
+
pkg_object_t pkg_object_type(pkg_object *);
+
int64_t pkg_object_int(pkg_object *o);
+
bool pkg_object_bool(pkg_object *o);
+
const char *pkg_object_string(pkg_object *o);
+
void pkg_object_free(pkg_object *o);
+
const char *pkg_object_key(pkg_object *);
+
pkg_object *pkg_object_iterate(pkg_object *, pkg_iter *);
+
const char *pkg_object_dump(pkg_object *o);
+
const char *pkg_config_dump(void);

/**
 * @todo Document
modified libpkg/pkg_add.c
@@ -298,7 +298,7 @@ pkg_add(struct pkgdb *db, const char *path, unsigned flags, struct pkg_manifest_
	 * experimantal purposes and to develop MTREE-free versions of
	 * packages. */

-
	pkg_config_bool(PKG_CONFIG_DISABLE_MTREE, &disable_mtree);
+
	disable_mtree = pkg_object_bool(pkg_config_get("DISABLE_MTREE"));
	if (!disable_mtree) {
		pkg_get(pkg, PKG_PREFIX, &prefix, PKG_MTREE, &mtree);
		if ((retcode = do_extract_mtree(mtree, prefix)) != EPKG_OK)
@@ -339,7 +339,7 @@ pkg_add(struct pkgdb *db, const char *path, unsigned flags, struct pkg_manifest_
	 * and that the service is running
	 */

-
	pkg_config_bool(PKG_CONFIG_HANDLE_RC_SCRIPTS, &handle_rc);
+
	handle_rc = pkg_object_bool(pkg_config_get("HANDLE_RC_SCRIPTS"));
	if (handle_rc)
		pkg_start_stop_rc_scripts(pkg, PKG_RC_START);

modified libpkg/pkg_config.c
@@ -58,12 +58,11 @@ struct config_entry {

static char myabi[BUFSIZ];
static struct pkg_repo *repos = NULL;
-
static struct pkg_config *config = NULL;
-
static struct pkg_config *config_by_key = NULL;
+
ucl_object_t *config = NULL;

static struct config_entry c[] = {
	[PKG_CONFIG_REPO] = {
-
		PKG_CONFIG_STRING,
+
		PKG_STRING,
		"PACKAGESITE",
#ifdef DEFAULT_PACKAGESITE
		DEFAULT_PACKAGESITE,
@@ -73,19 +72,19 @@ static struct config_entry c[] = {
		"Repository URL",
	},
	[PKG_CONFIG_DBDIR] = {
-
		PKG_CONFIG_STRING,
+
		PKG_STRING,
		"PKG_DBDIR",
		"/var/db/pkg",
		"Where the package databases are stored",
	},
	[PKG_CONFIG_CACHEDIR] = {
-
		PKG_CONFIG_STRING,
+
		PKG_STRING,
		"PKG_CACHEDIR",
		"/var/cache/pkg",
		"Directory containing cache of downloaded packages",
	},
	[PKG_CONFIG_PORTSDIR] = {
-
		PKG_CONFIG_STRING,
+
		PKG_STRING,
		"PORTSDIR",
#ifdef PORTSDIR
		PORTSDIR,
@@ -95,61 +94,61 @@ static struct config_entry c[] = {
		"Location of the ports collection",
	},
	[PKG_CONFIG_REPOKEY] = {
-
		PKG_CONFIG_STRING,
+
		PKG_STRING,
		"PUBKEY",
		NULL,
		"Public key for authenticating packages from the chosen repository",
	},
	[PKG_CONFIG_HANDLE_RC_SCRIPTS] = {
-
		PKG_CONFIG_BOOL,
+
		PKG_BOOL,
		"HANDLE_RC_SCRIPTS",
-
		NULL,
+
		"NO",
		"Automatically handle restarting services",
	},
	[PKG_CONFIG_ASSUME_ALWAYS_YES] = {
-
		PKG_CONFIG_BOOL,
+
		PKG_BOOL,
		"ASSUME_ALWAYS_YES",
-
		NULL,
+
		"NO",
		"Answer 'yes' to all pkg(8) questions",
	},
	[PKG_CONFIG_REPOS_DIR] = {
-
		PKG_CONFIG_LIST,
+
		PKG_ARRAY,
		"REPOS_DIR",
		"/etc/pkg/,"PREFIX"/etc/pkg/repos/",
		"Location of the repository configuration files"
	},
	[PKG_CONFIG_PLIST_KEYWORDS_DIR] = {
-
		PKG_CONFIG_STRING,
+
		PKG_STRING,
		"PLIST_KEYWORDS_DIR",
		NULL,
		"Directory containing definitions of plist keywords",
	},
	[PKG_CONFIG_SYSLOG] = {
-
		PKG_CONFIG_BOOL,
+
		PKG_BOOL,
		"SYSLOG",
		"YES",
		"Log pkg(8) operations via syslog(3)",
	},
	[PKG_CONFIG_AUTODEPS] = {
-
		PKG_CONFIG_BOOL,
+
		PKG_BOOL,
		"AUTODEPS",
		"YES",
		"Automatically append dependencies to fulfil dynamic linking requrements of binaries",
	},
	[PKG_CONFIG_ABI] = {
-
		PKG_CONFIG_STRING,
+
		PKG_STRING,
		"ABI",
		myabi,
		"Override the automatically detected ABI",
	},
	[PKG_CONFIG_DEVELOPER_MODE] = {
-
		PKG_CONFIG_BOOL,
+
		PKG_BOOL,
		"DEVELOPER_MODE",
		"NO",
		"Add extra strict, pedantic warnings as an aid to package maintainers",
	},
	[PKG_CONFIG_PORTAUDIT_SITE] = {
-
		PKG_CONFIG_STRING,
+
		PKG_STRING,
		"PORTAUDIT_SITE",
#ifdef DEFAULT_AUDIT_URL
		DEFAULT_AUDIT_URL,
@@ -159,7 +158,7 @@ static struct config_entry c[] = {
		"URL giving location of the audit database",
	},
	[PKG_CONFIG_VULNXML_SITE] = {
-
		PKG_CONFIG_STRING,
+
		PKG_STRING,
		"VULNXML_SITE",
#ifdef DEFAULT_VULNXML_URL
		DEFAULT_VULNXML_URL,
@@ -169,7 +168,7 @@ static struct config_entry c[] = {
		"URL giving location of the vulnxml database",
	},
	[PKG_CONFIG_MIRRORS] = {
-
		PKG_CONFIG_STRING,
+
		PKG_STRING,
		"MIRROR_TYPE",
#if DEFAULT_MIRROR_TYPE == 1
		"SRV",
@@ -181,121 +180,121 @@ static struct config_entry c[] = {
		"How to locate alternate mirror sites of a repository (one of: 'SRV', 'HTTP')",
	},
	[PKG_CONFIG_FETCH_RETRY] = {
-
		PKG_CONFIG_INTEGER,
+
		PKG_INT,
		"FETCH_RETRY",
		"3",
		"How many times to retry fetching files",
	},
	[PKG_CONFIG_PLUGINS_DIR] = {
-
		PKG_CONFIG_STRING,
+
		PKG_STRING,
		"PKG_PLUGINS_DIR",
		PREFIX"/lib/pkg/",
		"Directory which pkg(8) will load plugins from",
	},
	[PKG_CONFIG_ENABLE_PLUGINS] = {
-
		PKG_CONFIG_BOOL,
+
		PKG_BOOL,
		"PKG_ENABLE_PLUGINS",
		"YES",
		"Activate plugin support",
	},
	[PKG_CONFIG_PLUGINS] = {
-
		PKG_CONFIG_LIST,
+
		PKG_ARRAY,
		"PLUGINS",
		NULL,
		"List of plugins that pkg(8) should load",
	},
	[PKG_CONFIG_DEBUG_SCRIPTS] = {
-
		PKG_CONFIG_BOOL,
+
		PKG_BOOL,
		"DEBUG_SCRIPTS",
		"NO",
		"Run shell scripts in verbose mode to facilitate debugging",
	},
	[PKG_CONFIG_PLUGINS_CONF_DIR] = {
-
		PKG_CONFIG_STRING,
+
		PKG_STRING,
		"PLUGINS_CONF_DIR",
		PREFIX"/etc/pkg/",
		"Directory containing plugin configuration data",
	},
	[PKG_CONFIG_PERMISSIVE] = {
-
		PKG_CONFIG_BOOL,
+
		PKG_BOOL,
		"PERMISSIVE",
		"NO",
		"Permit package installation despite presence of conflicting packages",
	},
	[PKG_CONFIG_REPO_AUTOUPDATE] = {
-
		PKG_CONFIG_BOOL,
+
		PKG_BOOL,
		"REPO_AUTOUPDATE",
		"YES",
		"Automatically update repository catalogues prior to package updates",
	},
	[PKG_CONFIG_NAMESERVER] = {
-
		PKG_CONFIG_STRING,
+
		PKG_STRING,
		"NAMESERVER",
		NULL,
		"Use this nameserver when looking up addresses",
	},
	[PKG_CONFIG_EVENT_PIPE] = {
-
		PKG_CONFIG_STRING,
+
		PKG_STRING,
		"EVENT_PIPE",
		NULL,
		"Send all events to the specified fifo or Unix socket",
	},
	[PKG_CONFIG_FETCH_TIMEOUT] = {
-
		PKG_CONFIG_INTEGER,
+
		PKG_INT,
		"FETCH_TIMEOUT",
		"30",
		NULL,
	},
	[PKG_CONFIG_UNSET_TIMESTAMP] = {
-
		PKG_CONFIG_BOOL,
+
		PKG_BOOL,
		"UNSET_TIMESTAMP",
		"NO",
		NULL,
	},
	[PKG_CONFIG_SSH_RESTRICT_DIR] = {
-
		PKG_CONFIG_STRING,
+
		PKG_STRING,
		"SSH_RESTRICT_DIR",
		NULL,
		"Directory the ssh subsystem will be restricted to",
	},
	[PKG_CONFIG_ENV] = {
-
		PKG_CONFIG_KVLIST,
+
		PKG_OBJECT,
		"PKG_ENV",
		NULL,
		"Environment variables pkg will use",
	},
	[PKG_CONFIG_DISABLE_MTREE] = {
-
		PKG_CONFIG_BOOL,
+
		PKG_BOOL,
		"DISABLE_MTREE",
		"NO",
		"Experimental: disable MTREE processing on pkg installation",
	},
	[PKG_CONFIG_SSH_ARGS] = {
-
		PKG_CONFIG_STRING,
+
		PKG_STRING,
		"PKG_SSH_ARGS",
		NULL,
		"Extras arguments to pass to ssh(1)",
	},
	[PKG_CONFIG_DEBUG_LEVEL] = {
-
		PKG_CONFIG_INTEGER,
+
		PKG_INT,
		"DEBUG_LEVEL",
		"0",
		"Level for debug messages",
	},
	[PKG_CONFIG_ALIAS] = {
-
		PKG_CONFIG_KVLIST,
+
		PKG_OBJECT,
		"ALIAS",
		NULL,
		"Command aliases",
	},
	[PKG_CONFIG_CUDF_SOLVER] = {
-
		PKG_CONFIG_STRING,
+
		PKG_STRING,
		"CUDF_SOLVER",
		NULL,
		"Experimental: tells pkg to use an external CUDF solver",
	},
	[PKG_CONFIG_SAT_SOLVER] = {
-
		PKG_CONFIG_STRING,
+
		PKG_STRING,
		"SAT_SOLVER",
		NULL,
		"Experimental: tells pkg to use an external SAT solver",
@@ -305,8 +304,6 @@ static struct config_entry c[] = {
static bool parsed = false;
static size_t c_size = NELEM(c);

-
static void		 pkg_config_kv_free(struct pkg_config_kv *);
-
static void		 pkg_config_value_free(struct pkg_config_value *);
static struct pkg_repo	*pkg_repo_new(const char *name, const char *url);

static void
@@ -341,7 +338,7 @@ connect_evpipe(const char *evpipe) {
		sock.sun_family = AF_UNIX;
		if (strlcpy(sock.sun_path, evpipe, sizeof(sock.sun_path)) >=
		    sizeof(sock.sun_path)) {
-
			pkg_emit_error("Socket path too long: %s", evpipe);
+
			pkg_emit_error("Sockey path too long: %s", evpipe);
			close(eventpipe);
			eventpipe = -1;
			return;
@@ -357,321 +354,44 @@ connect_evpipe(const char *evpipe) {

}

-
static void
-
obj_walk_array(ucl_object_t *obj, struct pkg_config *conf)
-
{
-
	struct pkg_config_value *v;
-
	ucl_object_t *cur;
-
	ucl_object_iter_t it = NULL;
-
	
-
	while ((cur = ucl_iterate_object(obj, &it, true))) {
-
		if (cur->type != UCL_STRING)
-
			continue;
-
		v = malloc(sizeof(struct pkg_config_value));
-
		v->value = strdup(ucl_object_tostring(cur));
-
		HASH_ADD_STR(conf->list, value, v);
-
	}
-
}
-

-
static void
-
obj_walk_object(ucl_object_t *obj, struct pkg_config *conf)
-
{
-
	struct pkg_config_kv *kv;
-
	ucl_object_t *cur;
-
	ucl_object_iter_t it = NULL;
-
	const char *key;
-

-
	while ((cur = ucl_iterate_object(obj, &it, true))) {
-
		if (cur->type != UCL_STRING)
-
			continue;
-
		kv = malloc(sizeof(struct pkg_config_kv));
-
		key = ucl_object_key(cur);
-
		if (key == NULL)
-
			continue;
-
		kv->key = strdup(key);
-
		kv->value = strdup(ucl_object_tostring(cur));
-
		HASH_ADD_STR(conf->kvlist, value, kv);
-
	}
-
}
-

-
void
-
pkg_object_walk(ucl_object_t *obj, struct pkg_config *conf_by_key)
-
{
-
	ucl_object_t *cur;
-
	ucl_object_iter_t it = NULL;
-
	struct sbuf *b = sbuf_new_auto();
-
	struct pkg_config *conf;
-
	const char *key;
-
	size_t i;
-

-
	while ((cur = ucl_iterate_object(obj, &it, true))) {
-
		sbuf_clear(b);
-
		key = ucl_object_key(cur);
-
		if (key == NULL)
-
			continue;
-
		for (i = 0; i < strlen(key); i++)
-
			sbuf_putc(b, toupper(key[i]));
-
		sbuf_finish(b);
-

-
		HASH_FIND(hhkey, conf_by_key, sbuf_data(b), (size_t)sbuf_len(b), conf);
-
		if (conf != NULL) {
-
			switch (conf->type) {
-
			case PKG_CONFIG_STRING:
-
				if (cur->type != UCL_STRING) {
-
					pkg_emit_error("Expecting a string for key %s,"
-
					    " ignoring...", key);
-
					continue;
-
				}
-
				if (!conf->fromenv) {
-
					free(conf->string);
-
					conf->string = strdup(ucl_object_tostring(cur));
-
				}
-
				break;
-
			case PKG_CONFIG_INTEGER:
-
				if (cur->type != UCL_INT) {
-
					pkg_emit_error("Expecting an integer for key %s,"
-
					    " ignoring...", key);
-
					continue;
-
				}
-
				if (!conf->fromenv)
-
					conf->integer = ucl_object_toint(cur);
-
				break;
-
			case PKG_CONFIG_BOOL:
-
				if (cur->type != UCL_BOOLEAN) {
-
					pkg_emit_error("Expecting a boolean for key %s,"
-
					    " ignoring...", key);
-
					continue;
-
				}
-

-
				if (!conf->fromenv)
-
					conf->boolean = ucl_object_toboolean(cur);
-
				break;
-
			case PKG_CONFIG_LIST:
-
				if (cur->type != UCL_ARRAY) {
-
					pkg_emit_error("Expecting a list for key %s,"
-
					    " ignoring...", key);
-
					continue;
-
				}
-
				if (!conf->fromenv) {
-
					HASH_FREE(conf->list, pkg_config_value, pkg_config_value_free);
-
					conf->list = NULL;
-
					obj_walk_array(cur, conf);
-
				}
-
				break;
-
			case PKG_CONFIG_KVLIST:
-
				if (cur->type != UCL_OBJECT) {
-
					pkg_emit_error("Expecting a mapping for key %s,"
-
					    " ignoring...", key);
-
					continue;
-
				}
-
				if (!conf->fromenv) {
-
					HASH_FREE(conf->kvlist, pkg_config_kv, pkg_config_kv_free);
-
					conf->kvlist = NULL;
-
					obj_walk_object(cur, conf);
-
				}
-
				break;
-
			}
-
		}
-
	}
-
	sbuf_delete(b);
-
}
-

-
static char *
-
subst_packagesite_str(const char *oldstr)
-
{
-
	const char *myarch;
-
	struct sbuf *newval;
-
	const char *variable_string;
-
	char *res;
-

-
	variable_string = strstr(oldstr, ABI_VAR_STRING);
-
	if (variable_string == NULL)
-
		return strdup(oldstr);
-

-
	newval = sbuf_new_auto();
-
	sbuf_bcat(newval, oldstr, variable_string - oldstr);
-
	pkg_config_string(PKG_CONFIG_ABI, &myarch);
-
	sbuf_cat(newval, myarch);
-
	sbuf_cat(newval, variable_string + strlen(ABI_VAR_STRING));
-
	sbuf_finish(newval);
-

-
	res = strdup(sbuf_data(newval));
-
	sbuf_free(newval);
-

-
	return res;
-
}
-

int
pkg_initialized(void)
{
	return (parsed);
}

-
int
-
pkg_config_desc(pkg_config_key key, const char **desc)
-
{
-
	struct pkg_config *conf;
-

-
	if (parsed != true) {
-
		pkg_emit_error("pkg_init() must be called before pkg_config_desc()");
-
		return (EPKG_FATAL);
-
	}
-

-
	HASH_FIND_INT(config, &key, conf);
-
	if (conf == NULL)
-
		*desc = NULL;
-
	else
-
		*desc = conf->desc;
-

-
	return (EPKG_OK);
-
}
-

-
int
-
pkg_config_string(pkg_config_key key, const char **val)
-
{
-
	struct pkg_config *conf;
-

-
	if (parsed != true) {
-
		pkg_emit_error("pkg_init() must be called before pkg_config_string()");
-
		return (EPKG_FATAL);
-
	}
-

-
	HASH_FIND_INT(config, &key, conf);
-
	if (conf == NULL)
-
		*val = NULL;
-
	else
-
		*val = conf->string;
-

-
	return (EPKG_OK);
-
}
-

-
int
-
pkg_config_int64(pkg_config_key key, int64_t *val)
-
{
-
	struct pkg_config *conf;
-

-
	if (parsed != true) {
-
		pkg_emit_error("pkg_init() must be called before pkg_config_int64()");
-
		return (EPKG_FATAL);
-
	}
-

-
	HASH_FIND_INT(config, &key, conf);
-
	if (conf == NULL)
-
		return (EPKG_FATAL);
-

-
	*val = conf->integer;
-

-
	return (EPKG_OK);
-
}
-

-
int
-
pkg_config_bool(pkg_config_key key, bool *val)
-
{
-
	struct pkg_config *conf;
-

-
	if (parsed != true) {
-
		pkg_emit_error("pkg_init() must be called before pkg_config_bool()");
-
		return (EPKG_FATAL);
-
	}
-

-
	HASH_FIND_INT(config, &key, conf);
-
	if (conf == NULL)
-
		return (EPKG_FATAL);
-

-
	*val = conf->boolean;
-

-
	return (EPKG_OK);
+
pkg_object *
+
pkg_config_get(const char *key) {
+
	return (ucl_object_find_key(config, key));
}

-
int
-
pkg_config_kvlist(pkg_config_key key, struct pkg_config_kv **kv)
-
{
-
	struct pkg_config *conf;
-

-
	if (parsed != true) {
-
		pkg_emit_error("pkg_init() must be called before pkg_config_kvlist()");
-
		return (EPKG_FATAL);
-
	}
-

-
	HASH_FIND_INT(config, &key, conf);
-
	if (conf == NULL)
-
		return (EPKG_FATAL);
-

-
	if (conf->type != PKG_CONFIG_KVLIST) {
-
		pkg_emit_error("this config entry is not a \"key: value\" list");
-
		return (EPKG_FATAL);
-
	}
-

-
	HASH_NEXT(conf->kvlist, (*kv));
-
}
-

-
int
-
pkg_config_list(pkg_config_key key, struct pkg_config_value **v)
+
const char *
+
pkg_config_dump(void)
{
-
	struct pkg_config *conf;
-

-
	if (parsed != true) {
-
		pkg_emit_error("pkg_init() must be called before pkg_config_list()");
-
		return (EPKG_FATAL);
-
	}
-

-
	HASH_FIND_INT(config, &key, conf);
-
	if (conf == NULL)
-
		return (EPKG_FATAL);
-

-
	if (conf->type != PKG_CONFIG_LIST) {
-
		pkg_emit_error("this config entry is not a list");
-
		return (EPKG_FATAL);
-
	}
-

-
	HASH_NEXT(conf->list, (*v));
+
	return (pkg_object_dump(config));
}

const char *
-
pkg_config_value(struct pkg_config_value *v)
+
pkg_object_dump(pkg_object *o)
{
-
	assert(v != NULL);
-

-
	return (v->value);
+
	return (ucl_object_emit(o, UCL_EMIT_CONFIG));
}

-

-
const char *
-
pkg_config_kv_get(struct pkg_config_kv *kv, pkg_config_kv_t type)
-
{
-
	assert(kv != NULL);
-

-
	switch (type) {
-
	case PKG_CONFIG_KV_KEY:
-
		return (kv->key);
-
		break;
-
	case PKG_CONFIG_KV_VALUE:
-
		return (kv->value);
-
		break;
-
	}
-
	return (NULL);
+
pkg_object *
+
pkg_object_iter(pkg_object *o, pkg_iter *it) {
+
	return (ucl_iterate_object(o, it, true));
}

static void
disable_plugins_if_static(void)
{
	void *dlh;
-
	struct pkg_config *conf;
-
	pkg_config_key k = PKG_CONFIG_ENABLE_PLUGINS;
-

-
	HASH_FIND_INT(config, &k, conf);
-

-
	if (conf == NULL)
-
		return;
-

-
	if (!conf->boolean)
-
		return;

	dlh = dlopen(0, 0);

	/* if dlh is NULL then we are in static binary */
	if (dlh == NULL)
-
		conf->boolean = false;
+
		config = ucl_object_replace_key(config, ucl_object_frombool(false), "ENABLE_PLUGINS", 14, false);
	else
		dlclose(dlh);

@@ -805,8 +525,6 @@ walk_repo_obj(ucl_object_t *obj, const char *file)

	while ((cur = ucl_iterate_object(obj, &it, true))) {
		key = ucl_object_key(cur);
-
		if (key == NULL)
-
			continue;
		pkg_debug(1, "PkgConfig: parsing key '%s'", key);
		r = pkg_repo_find_ident(key);
		if (r != NULL)
@@ -825,11 +543,11 @@ load_repo_file(const char *repofile)
	struct ucl_parser *p;
	ucl_object_t *obj = NULL;
	bool fallback = false;
-
	const char *myarch;
+
	const char *myarch = NULL;

	p = ucl_parser_new(0);

-
	pkg_config_string(PKG_CONFIG_ABI, &myarch);
+
	myarch = pkg_object_string(pkg_config_get("ABI"));
	ucl_parser_register_variable (p, "ABI", myarch);

	pkg_debug(1, "PKgConfig: loading %s", repofile);
@@ -900,37 +618,17 @@ static void
load_repositories(const char *repodir)
{
	struct pkg_repo *r;
-
	struct pkg_config_value *v;
-
	const char *url, *pub, *mirror_type;
-

-
	pkg_config_string(PKG_CONFIG_REPO, &url);
-
	pkg_config_string(PKG_CONFIG_REPOKEY, &pub);
-
	pkg_config_string(PKG_CONFIG_MIRRORS, &mirror_type);
-

-
	if (url != NULL) {
-
		pkg_emit_error("PACKAGESITE in pkg.conf is deprecated. "
-
		    "Please create a repository configuration file");
-
		r = pkg_repo_new("packagesite", url);
-
		if (pub != NULL) {
-
			r->pubkey = strdup(pub);
-
			r->signature_type = SIG_PUBKEY;
-
		}
-
		if (mirror_type != NULL) {
-
			if (strcasecmp(mirror_type, "srv") == 0)
-
				r->mirror_type = SRV;
-
			else if (strcasecmp(mirror_type, "http") == 0)
-
				r->mirror_type = HTTP;
-
		}
-
	}
+
	pkg_object *reposlist, *cur;
+
	pkg_iter it = NULL;

	if (repodir != NULL) {
		load_repo_files(repodir);
		return;
	}

-
	v = NULL;
-
	while (pkg_config_list(PKG_CONFIG_REPOS_DIR, &v) == EPKG_OK)
-
		load_repo_files(pkg_config_value(v));
+
	reposlist = pkg_config_get( "REPOS_DIR");
+
	while ((cur = pkg_object_iter(reposlist, &it)))
+
		load_repo_files(pkg_object_string(cur));
}


@@ -940,7 +638,7 @@ pkg_init(const char *path, const char *reposdir)
	struct ucl_parser *p = NULL;
	size_t i;
	const char *val = NULL;
-
	const char *buf, *walk, *value, *key;
+
	const char *buf, *walk, *value, *key, *k;
	const char *errstr = NULL;
	const char *evkey = NULL;
	const char *nsname = NULL;
@@ -948,8 +646,9 @@ pkg_init(const char *path, const char *reposdir)
	struct pkg_config *conf;
	struct pkg_config_value *v;
	struct pkg_config_kv *kv;
-
	ucl_object_t *obj = NULL, *cur;
+
	ucl_object_t *obj = NULL, *cur, *o, *ncfg;
	ucl_object_iter_t it = NULL;
+
	struct sbuf *ukey = NULL;
	bool fallback = false;

	pkg_get_myarch(myabi, BUFSIZ);
@@ -959,64 +658,29 @@ pkg_init(const char *path, const char *reposdir)
	}

	for (i = 0; i < c_size; i++) {
-
		conf = malloc(sizeof(struct pkg_config));
-
		conf->id = i;
-
		conf->key = c[i].key;
-
		conf->type = c[i].type;
-
		conf->desc = c[i].desc;
-
		conf->fromenv = false;
-
		val = getenv(c[i].key);
-

		switch (c[i].type) {
-
		case PKG_CONFIG_STRING:
-
			if (val != NULL) {
-
				if (strcmp(c[i].key, "PACKAGESITE") == 0)
-
					conf->string = subst_packagesite_str(val);
-
				else
-
					conf->string = strdup(val);
-
				conf->fromenv = true;
-
			}
-
			else if (c[i].def != NULL)
-
				conf->string = strdup(c[i].def);
-
			else
-
				conf->string = NULL;
+
		case PKG_STRING:
+
			obj = ucl_object_fromstring_common(
+
			    c[i].def != NULL ? c[i].def : "", 0, UCL_STRING_TRIM);
+
			config = ucl_object_insert_key(config, obj,
+
			    c[i].key, strlen(c[i].key), false);
			break;
-
		case PKG_CONFIG_INTEGER:
-
			if (val == NULL)
-
				val = c[i].def;
-
			else
-
				conf->fromenv = true;
-
			conf->integer = strtonum(val, 0, INT64_MAX, &errstr);
-
			if (errstr != NULL) {
-
				pkg_emit_error("Unable to convert %s to int64: %s",
-
				    val, errstr);
-
				free(conf);
-
				return (EPKG_FATAL);
-
			}
+
		case PKG_INT:
+
			config = ucl_object_insert_key(config,
+
			    ucl_object_fromstring_common(c[i].def, 0, UCL_STRING_PARSE_INT),
+
			    c[i].key, strlen(c[i].key), false);
			break;
-
		case PKG_CONFIG_BOOL:
-
			if (val == NULL)
-
				val = c[i].def;
-
			else
-
				conf->fromenv = true;
-
			if (val != NULL && (
-
			    strcmp(val, "1") == 0 ||
-
			    strcasecmp(val, "yes") == 0 ||
-
			    strcasecmp(val, "true") == 0 ||
-
			    strcasecmp(val, "on") == 0)) {
-
				conf->boolean = true;
-
			} else {
-
				conf->boolean = false;
-
			}
+
		case PKG_BOOL:
+
			config = ucl_object_insert_key(config,
+
			    ucl_object_fromstring_common(c[i].def, 0, UCL_STRING_PARSE_BOOLEAN),
+
			    c[i].key, strlen(c[i].key), false);
			break;
-
		case PKG_CONFIG_KVLIST:
-
			conf->kvlist = NULL;
-
			if (val == NULL)
-
				val = c[i].def;
-
			else
-
				conf->fromenv = false;
-
			if (val != NULL) {
-
				walk = buf = val;
+
		case PKG_OBJECT:
+
			obj = NULL;
+
			if (c[i].def == NULL) {
+
				obj = ucl_object_typed_new(UCL_OBJECT);
+
			} else {
+
				walk = buf = c[i].def;
				while ((buf = strchr(buf, ',')) != NULL) {
					key = walk;
					value = walk;
@@ -1025,63 +689,45 @@ pkg_init(const char *path, const char *reposdir)
							break;
						value++;
					}
-
					if (value == buf || (value - key) == 0) {
-
						pkg_emit_error("Malformed Key/Value for %s", c[i].key);
-
						pkg_config_kv_free(conf->kvlist);
-
						conf->kvlist = NULL;
-
						break;
-
					}
-
					kv = malloc(sizeof(struct pkg_config_kv));
-
					kv->key = strndup(key, value - key);
-
					kv->value = strndup(value + 1, buf - value -1);
-
					HASH_ADD_STR(conf->kvlist, value, kv);
+
					obj = ucl_object_insert_key(obj,
+
					    ucl_object_fromstring_common(value + 1, buf - value - 1, UCL_STRING_TRIM),
+
					    key, value - key, false);
					buf++;
					walk = buf;
				}
				key = walk;
				value = walk;
-
				while (*value != '\0') {
+
				while (*value != ',') {
					if (*value == '=')
						break;
					value++;
				}
-
				if (*value == '\0' || (value - key) == 0) {
-
					pkg_emit_error("Malformed Key/Value for %s: %s", c[i].key, val);
-
					pkg_config_kv_free(conf->kvlist);
-
					conf->kvlist = NULL;
-
					break;
-
				}
-
				kv = malloc(sizeof(struct pkg_config_kv));
-
				kv->key = strndup(key, value - key);
-
				kv->value = strdup(value + 1);
-
				HASH_ADD_STR(conf->kvlist, value, kv);
+
				o = ucl_object_insert_key(o,
+
				    ucl_object_fromstring_common(value + 1, strlen(value + 1), UCL_STRING_TRIM),
+
			        k, value - k, false);
			}
+
			config = ucl_object_insert_key(config, obj,
+
			    c[i].key, strlen(c[i].key), false);
			break;
-
		case PKG_CONFIG_LIST:
-
			conf->list = NULL;
-
			if (val == NULL)
-
				val = c[i].def;
-
			else
-
				conf->fromenv = true;
-
			if (val != NULL) {
-
				walk = buf = val;
+
		case PKG_ARRAY:
+
			obj = NULL;
+
			if (c[i].def == NULL) {
+
				obj = ucl_object_typed_new(UCL_ARRAY);
+
			} else {
+
				walk = buf = c[i].def;
				while ((buf = strchr(buf, ',')) != NULL) {
-
					v = malloc(sizeof(struct pkg_config_value));
-
					v->value = strndup(walk, buf - walk);
-
					HASH_ADD_STR(conf->list, value, v);
+
					obj = ucl_array_append(obj,
+
					    ucl_object_fromstring_common(walk, buf - walk, UCL_STRING_TRIM));
					buf++;
					walk = buf;
				}
-
				v = malloc(sizeof(struct pkg_config_value));
-
				v->value = strdup(walk);
-
				HASH_ADD_STR(conf->list, value, v);
+
				obj = ucl_array_append(obj,
+
				    ucl_object_fromstring_common(walk, strlen(walk), UCL_STRING_TRIM));
			}
+
			config = ucl_object_insert_key(config, obj,
+
			    c[i].key, strlen(c[i].key), false);
			break;
		}
-

-
		HASH_ADD_INT(config, id, conf);
-
		HASH_ADD_KEYPTR(hhkey, config_by_key, conf->key,
-
		    strlen(conf->key), conf);
	}

	if (path == NULL)
@@ -1090,76 +736,152 @@ pkg_init(const char *path, const char *reposdir)
	p = ucl_parser_new(0);

	errno = 0;
+
	obj = NULL;
	if (!ucl_parser_add_file(p, path)) {
		if (errno == ENOENT)
			goto parsed;
-
		fallback = true;
+
		pkg_emit_error("%s", ucl_parser_get_error(p));
+
	} else {
+
		obj = ucl_parser_get_object(p);
+

	}

-
	if (!fallback) {
-
		/* Validate the first level of the configuration */
-
		obj = ucl_parser_get_object(p);
-
		if (obj->type == UCL_OBJECT) {
-
			while ((cur = ucl_iterate_object(obj, &it, true))) {
-
				key = ucl_object_key(cur);
-
				if (key == NULL)
-
					continue;
-
				if (strcasecmp(key, "REPOS_DIR") == 0 &&
-
				    cur->type != UCL_ARRAY)
-
					fallback = true;
-
				else if (strcasecmp(key, "PKG_ENV") == 0 &&
-
				    cur->type != UCL_OBJECT)
-
					fallback = true;
-
				else if (strcasecmp(key, "ALIAS") == 0 &&
-
				    cur->type != UCL_OBJECT)
-
					fallback = true;
-
				if (fallback)
-
					break;
-
			}
-
		} else {
-
			fallback = true;
+
	ncfg = NULL;
+
	while (obj != NULL && (cur = ucl_iterate_object(obj, &it, true))) {
+
		sbuf_init(&ukey);
+
		key = ucl_object_key(cur);
+
		for (i = 0; key[i] != '\0'; i++)
+
			sbuf_putc(ukey, toupper(key[i]));
+
		sbuf_done(ukey);
+
		o = ucl_object_find_keyl(config, sbuf_data(ukey), sbuf_len(ukey));
+
		/* ignore unknown keys */
+
		if (o == NULL)
+
			continue;
+

+
		if (o->type != cur->type) {
+
			pkg_emit_error("Malformed key %s, ignoring", key);
+
			continue;
		}
+

+
		ncfg = ucl_object_insert_key(ncfg, cur, key, strlen(key), false);
	}

-
	if (fallback) {
-
		if (obj != NULL)
-
			ucl_object_free(obj);
-
		obj = yaml_to_ucl(path, NULL, 0);
-
		if (obj == NULL)
-
			return (EPKG_FATAL);
+
	if (ncfg != NULL) {
+
		it = NULL;
+
		while (( cur = ucl_iterate_object(ncfg, &it, true))) {
+
			key = ucl_object_key(cur);
+
			config = ucl_object_replace_key(config, ucl_object_ref(cur), key, strlen(key), false);
+
		}
+
		ucl_object_unref(ncfg);
	}

-
	if (fallback) {
-
		pkg_emit_error("Your pkg.conf file is in deprecated format you "
-
		    "should convert it to the following format:\n"
-
		    "====== BEGIN pkg.conf ======\n"
-
		    "%s"
-
		    "\n====== END pkg.conf ======\n",
-
		    ucl_object_emit(obj, UCL_EMIT_YAML));
+
	ncfg = NULL;
+
	it = NULL;
+
	while ((cur = ucl_iterate_object(config, &it, true))) {
+
		o = NULL;
+
		key = ucl_object_key(cur);
+
		val = getenv(key);
+
		if (val == NULL)
+
			continue;
+
		switch (cur->type) {
+
		case UCL_STRING:
+
			o = ucl_object_fromstring_common(val, 0, UCL_STRING_TRIM);
+
			break;
+
		case UCL_INT:
+
			o = ucl_object_fromstring_common(val, 0, UCL_STRING_PARSE_INT);
+
			if (o->type != UCL_INT) {
+
				pkg_emit_error("Invalid type for environment "
+
				    "variable %s, got %s, while expecting an integer",
+
				    key, val);
+
				ucl_object_free(o);
+
				continue;
+
			}
+
			break;
+
		case UCL_BOOLEAN:
+
			o = ucl_object_fromstring_common(val, 0, UCL_STRING_PARSE_BOOLEAN);
+
			if (o->type != UCL_BOOLEAN) {
+
				pkg_emit_error("Invalid type for environment "
+
				    "variable %s, got %s, while expecting a boolean",
+
				    key, val);
+
				ucl_object_free(o);
+
				continue;
+
			}
+
			break;
+
		case UCL_OBJECT:
+
			walk = buf = val;
+
			while ((buf = strchr(buf, ',')) != NULL) {
+
				k = walk;
+
				value = walk;
+
				while (*value != ',') {
+
					if (*value == '=')
+
						break;
+
					value++;
+
				}
+
				o = ucl_object_insert_key(o,
+
				    ucl_object_fromstring_common(value + 1, buf - value - 1, UCL_STRING_TRIM),
+
				    k, value - k, false);
+
				buf++;
+
				walk = buf;
+
			}
+
			key = walk;
+
			value = walk;
+
			while (*value != '\0') {
+
				if (*value == '=')
+
					break;
+
				value++;
+
			}
+
			o = ucl_object_insert_key(o,
+
			    ucl_object_fromstring_common(value + 1, strlen(value + 1), UCL_STRING_TRIM),
+
			    k, value - k, false);
+
			break;
+
		case UCL_ARRAY:
+
			walk = buf = val;
+
			while ((buf = strchr(buf, ',')) != NULL) {
+
				o = ucl_array_append(o,
+
				    ucl_object_fromstring_common(walk, buf - walk, UCL_STRING_TRIM));
+
				buf++;
+
				walk = buf;
+
			}
+
			obj = ucl_array_append(obj,
+
			    ucl_object_fromstring_common(walk, strlen(walk), UCL_STRING_TRIM));
+
			break;
+
		default:
+
			/* ignore other types */
+
			break;
+
		}
+
		if (o != NULL)
+
			ncfg = ucl_object_insert_key(ncfg, o, key, strlen(key), true);
	}

-
	if (obj->type == UCL_OBJECT)
-
		pkg_object_walk(obj, config_by_key);
+
	if (ncfg != NULL) {
+
		it = NULL;
+
		while (( cur = ucl_iterate_object(ncfg, &it, true))) {
+
			key = ucl_object_key(cur);
+
			config = ucl_object_replace_key(config, ucl_object_ref(cur), key, strlen(key), false);
+
		}
+
		ucl_object_unref(ncfg);
+
	}

parsed:
	disable_plugins_if_static();

	parsed = true;
-
	ucl_object_free(obj);
+
//	ucl_object_unref(obj);
	ucl_parser_free(p);

	pkg_debug(1, "%s", "pkg initialized");

	/* Start the event pipe */
-
	pkg_config_string(PKG_CONFIG_EVENT_PIPE, &evpipe);
+
	evpipe = pkg_object_string(pkg_config_get("EVENT_PIPE"));
	if (evpipe != NULL)
		connect_evpipe(evpipe);

-
	kv = NULL;
-
	while (pkg_config_kvlist(PKG_CONFIG_ENV, &kv) == EPKG_OK) {
-
		evkey = pkg_config_kv_get(kv, PKG_CONFIG_KV_KEY);
+
	it = NULL;
+
	o = ucl_object_find_key(config, "PKG_ENV");
+
	while ((cur = ucl_iterate_object(o, &it, true))) {
+
		evkey = ucl_object_key(cur);
		if (evkey != NULL && evkey[0] != '\0')
-
			setenv(evkey, pkg_config_kv_get(kv, PKG_CONFIG_KV_VALUE), 1);
+
			setenv(evkey, ucl_object_tostring_forced(cur), 1);
	}

	/* load the repositories */
@@ -1168,85 +890,109 @@ parsed:
	setenv("HTTP_USER_AGENT", "pkg/"PKGVERSION, 1);

	/* bypass resolv.conf with specified NAMESERVER if any */
-
	pkg_config_string(PKG_CONFIG_NAMESERVER, &nsname);
+
	nsname = pkg_object_string(pkg_config_get("NAMESERVER"));
	if (nsname != NULL)
-
		set_nameserver(nsname);
+
		set_nameserver(ucl_object_tostring_forced(o));

	return (EPKG_OK);
}

-
struct pkg_config *
-
pkg_config_lookup(const char *name)
+
void
+
pkg_object_free(pkg_object *o)
{
-
	struct pkg_config *conf;
+
	ucl_object_unref(o);
+
}

-
	if (name == NULL)
-
		return (NULL);
+
const char *
+
pkg_object_key(pkg_object *o)
+
{
+
	return (ucl_object_key(o));
+
}

-
	HASH_FIND(hhkey, config_by_key, name, strlen(name), conf);
+
pkg_object *
+
pkg_object_iterate(pkg_object *o, pkg_iter *it)
+
{
+
	return (ucl_iterate_object(o, it, true));
+
}

-
	return (conf);
+
pkg_object *
+
pkg_conf(void)
+
{
+
	return (config);
}

-
static void
-
pkg_config_kv_free(struct pkg_config_kv *k)
+
pkg_object_t
+
pkg_object_type(pkg_object *o)
{
-
	if (k == NULL)
-
		return;
+
	switch (o->type) {
+
	case UCL_OBJECT:
+
		return (PKG_OBJECT);
+
	case UCL_BOOLEAN:
+
		return (PKG_BOOL);
+
	case UCL_STRING:
+
		return (PKG_STRING);
+
	case UCL_INT:
+
		return (PKG_INT);
+
	case UCL_ARRAY:
+
		return (PKG_ARRAY);
+
	default:
+
		return (PKG_NULL);
+
	};

-
	free(k->key);
-
	free(k->value);
-
	free(k);
}

-
static void
-
pkg_config_value_free(struct pkg_config_value *v)
+
bool
+
pkg_object_bool(pkg_object *o)
{
-
	if (v == NULL)
-
		return;
+
	assert(o->type == UCL_BOOLEAN);

-
	free(v->value);
-
	free(v);
+
	return (ucl_object_toboolean(o));
}

-
static void
-
pkg_config_free(struct pkg_config *conf)
+
const char *
+
pkg_object_string(pkg_object *o)
{
-
	if (conf == NULL)
-
		return;
+
	const char *ret;

-
	if (conf->type == PKG_CONFIG_STRING)
-
		free(conf->string);
-
	else if (conf->type == PKG_CONFIG_KVLIST)
-
		HASH_FREE(conf->kvlist, pkg_config_kv, pkg_config_kv_free);
-
	else if (conf->type == PKG_CONFIG_LIST)
-
		HASH_FREE(conf->list, pkg_config_value, pkg_config_value_free);
+
	ret = ucl_object_tostring_forced(o);

-
	free(conf);
+
	if (ret && *ret == '\0')
+
		return (NULL);
+
	return (ret);
}

-
int
-
pkg_config_id(struct pkg_config *conf)
+
int64_t
+
pkg_object_int(pkg_object *o)
{
-
	return (conf->id);
-
}
+
	assert(o->type == UCL_INT);

-
int
-
pkg_config_type(struct pkg_config *conf)
-
{
-
	return (conf->type);
+
	return (ucl_object_toint(o));
}

-
const char *
-
pkg_config_name(struct pkg_config *conf)
+
static char *
+
subst_packagesite_str(const char *oldstr)
{
-
	return (conf->key);
-
}
+
	const char *myarch;
+
	struct sbuf *newval;
+
	const char *variable_string;
+
	ucl_object_t *o;
+
	char *res;

-
int
-
pkg_configs(struct pkg_config **conf)
-
{
-
	HASH_NEXT(config, (*conf));
+
	variable_string = strstr(oldstr, ABI_VAR_STRING);
+
	if (variable_string == NULL)
+
		return strdup(oldstr);
+

+
	newval = sbuf_new_auto();
+
	sbuf_bcat(newval, oldstr, variable_string - oldstr);
+
	o = ucl_object_find_key(config, "ABI");
+
	sbuf_cat(newval, ucl_object_tostring_forced(o));
+
	sbuf_cat(newval, variable_string + strlen(ABI_VAR_STRING));
+
	sbuf_finish(newval);
+

+
	res = strdup(sbuf_data(newval));
+
	sbuf_free(newval);
+

+
	return res;
}

static struct pkg_repo *
@@ -1289,11 +1035,9 @@ pkg_shutdown(void)
		/* NOTREACHED */
	}

-
	HASH_FREE(config, pkg_config, pkg_config_free);
+
	ucl_object_unref(config);
	HASH_FREE(repos, pkg_repo, pkg_repo_free);

-
	config_by_key = NULL;
-

	parsed = false;

	return;
modified libpkg/pkg_create.c
@@ -137,7 +137,7 @@ pkg_create_from_dir(struct pkg *pkg, const char *root,

		ret = packing_append_file_attr(pkg_archive, fpath, pkg_path,
		    file->uname, file->gname, file->perm);
-
		pkg_config_bool(PKG_CONFIG_DEVELOPER_MODE, &developer);
+
		developer = pkg_object_bool(pkg_config_get("DEVELOPER_MODE"));
		if (developer && ret != EPKG_OK)
			return (ret);
	}
@@ -151,7 +151,7 @@ pkg_create_from_dir(struct pkg *pkg, const char *root,

		ret = packing_append_file_attr(pkg_archive, fpath, pkg_path,
		    dir->uname, dir->gname, dir->perm);
-
		pkg_config_bool(PKG_CONFIG_DEVELOPER_MODE, &developer);
+
		developer = pkg_object_bool(pkg_config_get("DEVELOPER_MODE"));
		if (developer && ret != EPKG_OK)
			return (ret);
	}
modified libpkg/pkg_delete.c
@@ -91,7 +91,7 @@ pkg_delete(struct pkg *pkg, struct pkgdb *db, unsigned flags)
	 * stop the different related services if the users do want that
	 * and that the service is running
	 */
-
	pkg_config_bool(PKG_CONFIG_HANDLE_RC_SCRIPTS, &handle_rc);
+
	handle_rc = pkg_object_bool(pkg_config_get("HANDLE_RC_SCRIPTS"));
	if (handle_rc)
		pkg_start_stop_rc_scripts(pkg, PKG_RC_STOP);

modified libpkg/pkg_elf.c
@@ -217,7 +217,7 @@ analyse_elf(struct pkg *pkg, const char *fpath,
	bool developer = false;
	bool is_shlib = false;

-
	pkg_config_bool(PKG_CONFIG_DEVELOPER_MODE, &developer);
+
	developer = pkg_object_bool(pkg_config_get("DEVELOPER_MODE"));

	int fd;

@@ -408,8 +408,8 @@ pkg_analyse_files(struct pkgdb *db, struct pkg *pkg, const char *stage)
	bool developer = false;
	int (*action)(void *, struct pkg *, const char *, const char *, bool);

-
	pkg_config_bool(PKG_CONFIG_AUTODEPS, &autodeps);
-
	pkg_config_bool(PKG_CONFIG_DEVELOPER_MODE, &developer);
+
	autodeps = pkg_object_bool(pkg_config_get("AUTODEPS"));
+
	developer = pkg_object_bool(pkg_config_get("DEVELOPER_MORE"));

	if (elf_version(EV_CURRENT) == EV_NONE)
		return (EPKG_FATAL);
modified libpkg/pkg_event.c
@@ -452,7 +452,7 @@ pkg_emit_install_finished(struct pkg *p)
	ev.type = PKG_EVENT_INSTALL_FINISHED;
	ev.e_install_finished.pkg = p;

-
	pkg_config_bool(PKG_CONFIG_SYSLOG, &syslog_enabled);
+
	syslog_enabled = pkg_object_bool(pkg_config_get("SYSLOG"));
	if (syslog_enabled) {
		pkg_get(p, PKG_NAME, &name, PKG_VERSION, &version);
		syslog(LOG_NOTICE, "%s-%s installed", name, version);
@@ -516,7 +516,7 @@ pkg_emit_deinstall_finished(struct pkg *p)
	ev.type = PKG_EVENT_DEINSTALL_FINISHED;
	ev.e_deinstall_finished.pkg = p;

-
	pkg_config_bool(PKG_CONFIG_SYSLOG, &syslog_enabled);
+
	syslog_enabled = pkg_object_bool(pkg_config_get("SYSLOG"));
	if (syslog_enabled) {
		pkg_get(p, PKG_NAME, &name, PKG_VERSION, &version);
		syslog(LOG_NOTICE, "%s-%s deinstalled", name, version);
@@ -548,7 +548,7 @@ pkg_emit_upgrade_finished(struct pkg *new, struct pkg *old)
	ev.e_upgrade_finished.new = new;
	ev.e_upgrade_finished.old = old;

-
	pkg_config_bool(PKG_CONFIG_SYSLOG, &syslog_enabled);
+
	syslog_enabled = pkg_object_bool(pkg_config_get("SYSLOG"));
	if (syslog_enabled) {
		const char *actions[] = {
			[PKG_DOWNGRADE] = "downgraded",
@@ -726,7 +726,7 @@ pkg_debug(int level, const char *fmt, ...)
	va_list ap;
	int64_t expectlevel;

-
	pkg_config_int64(PKG_CONFIG_DEBUG_LEVEL, &expectlevel);
+
	expectlevel = pkg_object_int(pkg_config_get("DEBUG_LEVEL"));

	if (expectlevel < level)
		return;
modified libpkg/pkg_jobs.c
@@ -1481,8 +1481,7 @@ pkg_jobs_solve(struct pkg_jobs *j)
	}

	if (ret == EPKG_OK) {
-
		if (pkg_config_string(PKG_CONFIG_CUDF_SOLVER, &solver) == EPKG_OK
-
				&& solver != NULL) {
+
		if ((solver = pkg_object_string(pkg_config_get("CUDF_SOLVER"))) != NULL) {
			pchild = process_spawn_pipe(spipe, solver);
			if (pchild == -1)
				return (EPKG_FATAL);
@@ -1499,8 +1498,7 @@ pkg_jobs_solve(struct pkg_jobs *j)
		else {
			problem = pkg_solve_jobs_to_sat(j);
			if (problem != NULL) {
-
				if (pkg_config_string(PKG_CONFIG_SAT_SOLVER, &solver) == EPKG_OK
-
						&& solver != NULL) {
+
				if ((solver = pkg_object_string(pkg_config_get("SAT_SOLVER"))) != NULL) {
					pchild = process_spawn_pipe(spipe, solver);
					if (pchild == -1)
						return (EPKG_FATAL);
@@ -1652,10 +1650,8 @@ pkg_jobs_execute(struct pkg_jobs *j)
	if (j->flags & PKG_FLAG_SKIP_INSTALL)
		return (EPKG_OK);

-
	if (pkg_config_string(PKG_CONFIG_CACHEDIR, &cachedir) != EPKG_OK)
-
		return (EPKG_FATAL);
-
	
-
	pkg_config_bool(PKG_CONFIG_HANDLE_RC_SCRIPTS, &handle_rc);
+
	cachedir = pkg_object_string(pkg_config_get("PKG_CACHEDIR"));
+
	handle_rc = pkg_object_bool(pkg_config_get("HANDLE_RC_SCRIPTS"));

	/* XXX: get rid of hardcoded values */
	retcode = pkgdb_upgrade_lock(j->db, PKGDB_LOCK_ADVISORY,
@@ -1851,8 +1847,7 @@ pkg_jobs_fetch(struct pkg_jobs *j)
	const char *repopath = NULL;
	char cachedpath[MAXPATHLEN];
	
-
	if (pkg_config_string(PKG_CONFIG_CACHEDIR, &cachedir) != EPKG_OK)
-
		return (EPKG_FATAL);
+
	cachedir = pkg_object_string(pkg_config_get("PKG_CACHEDIR"));

	/* check for available size to fetch */
	PKG_JOBS_FETCH_CALCULATE(j->jobs);
@@ -1903,8 +1898,7 @@ pkg_jobs_check_conflicts(struct pkg_jobs *j)
	char path[MAXPATHLEN];
	int ret = EPKG_OK, res, added = 0;

-
	if (pkg_config_string(PKG_CONFIG_CACHEDIR, &cachedir) != EPKG_OK)
-
		return (EPKG_FATAL);
+
	cachedir = pkg_object_string(pkg_config_get("PKG_CACHEDIR"));

	pkg_emit_integritycheck_begin();

modified libpkg/pkg_manifest.c
@@ -62,7 +62,7 @@
#define PKG_PROVIDES -19 /* Deprecated field: treat as an annotation for backwards compatibility */

static int pkg_string(struct pkg *, ucl_object_t *, int);
-
static int pkg_object(struct pkg *, ucl_object_t *, int);
+
static int pkg_obj(struct pkg *, ucl_object_t *, int);
static int pkg_array(struct pkg *, ucl_object_t *, int);
static int pkg_int(struct pkg *, ucl_object_t *, int);
static int pkg_set_deps_from_object(struct pkg *, ucl_object_t *);
@@ -78,18 +78,18 @@ static struct manifest_key {
	enum ucl_type valid_type;
	int (*parse_data)(struct pkg *, ucl_object_t *, int);
} manifest_keys[] = {
-
	{ "annotations",         PKG_ANNOTATIONS,         UCL_OBJECT, pkg_object},
+
	{ "annotations",         PKG_ANNOTATIONS,         UCL_OBJECT, pkg_obj},
	{ "arch",                PKG_ARCH,                UCL_STRING, pkg_string},
	{ "categories",          PKG_CATEGORIES,          UCL_ARRAY,  pkg_array},
	{ "comment",             PKG_COMMENT,             UCL_STRING, pkg_string},
	{ "conflicts",           PKG_CONFLICTS,           UCL_ARRAY,  pkg_array},
-
	{ "deps",                PKG_DEPS,                UCL_OBJECT, pkg_object},
+
	{ "deps",                PKG_DEPS,                UCL_OBJECT, pkg_obj},
	{ "desc",                PKG_DESC,                UCL_STRING, pkg_string},
-
	{ "directories",         PKG_DIRECTORIES,         UCL_OBJECT, pkg_object},
+
	{ "directories",         PKG_DIRECTORIES,         UCL_OBJECT, pkg_obj},
	{ "dirs",                PKG_DIRS,                UCL_ARRAY,  pkg_array},
-
	{ "files",               PKG_FILES,               UCL_OBJECT, pkg_object},
+
	{ "files",               PKG_FILES,               UCL_OBJECT, pkg_obj},
	{ "flatsize",            PKG_FLATSIZE,            UCL_INT,    pkg_int},
-
	{ "groups",              PKG_GROUPS,              UCL_OBJECT, pkg_object},
+
	{ "groups",              PKG_GROUPS,              UCL_OBJECT, pkg_obj},
	{ "groups",              PKG_GROUPS,              UCL_ARRAY,  pkg_array},
	{ "infos",               PKG_INFOS,               UCL_STRING, pkg_string}, /* Deprecated: treat as an annotation */
	{ "licenselogic",        PKG_LICENSE_LOGIC,       UCL_STRING, pkg_string},
@@ -98,20 +98,20 @@ static struct manifest_key {
	{ "message",             PKG_MESSAGE,             UCL_STRING, pkg_string},
	{ "name",                PKG_NAME,                UCL_STRING, pkg_string},
	{ "name",                PKG_NAME,                UCL_INT,    pkg_string},
-
	{ "options",             PKG_OPTIONS,             UCL_OBJECT, pkg_object},
-
	{ "option_defaults",     PKG_OPTION_DEFAULTS,     UCL_OBJECT, pkg_object},
-
	{ "option_descriptions", PKG_OPTION_DESCRIPTIONS, UCL_OBJECT, pkg_object},
+
	{ "options",             PKG_OPTIONS,             UCL_OBJECT, pkg_obj},
+
	{ "option_defaults",     PKG_OPTION_DEFAULTS,     UCL_OBJECT, pkg_obj},
+
	{ "option_descriptions", PKG_OPTION_DESCRIPTIONS, UCL_OBJECT, pkg_obj},
	{ "origin",              PKG_ORIGIN,              UCL_STRING, pkg_string},
	{ "path",                PKG_REPOPATH,            UCL_STRING, pkg_string},
	{ "pkgsize",             PKG_PKGSIZE,             UCL_INT,    pkg_int},
	{ "prefix",              PKG_PREFIX,              UCL_STRING, pkg_string},
	{ "provides",            PKG_PROVIDES,            UCL_ARRAY,  pkg_array},
-
	{ "scripts",             PKG_SCRIPTS,             UCL_OBJECT, pkg_object},
+
	{ "scripts",             PKG_SCRIPTS,             UCL_OBJECT, pkg_obj},
	{ "shlibs",              PKG_SHLIBS_REQUIRED,     UCL_ARRAY,  pkg_array}, /* Backwards compat with 1.0.x packages */
	{ "shlibs_provided",     PKG_SHLIBS_PROVIDED,     UCL_ARRAY,  pkg_array},
	{ "shlibs_required",     PKG_SHLIBS_REQUIRED,     UCL_ARRAY,  pkg_array},
	{ "sum",                 PKG_CKSUM,               UCL_STRING, pkg_string},
-
	{ "users",               PKG_USERS,               UCL_OBJECT, pkg_object},
+
	{ "users",               PKG_USERS,               UCL_OBJECT, pkg_obj},
	{ "users",               PKG_USERS,               UCL_ARRAY,  pkg_array},
	{ "version",             PKG_VERSION,             UCL_STRING, pkg_string},
	{ "version",             PKG_VERSION,             UCL_INT,    pkg_string},
@@ -331,7 +331,7 @@ pkg_array(struct pkg *pkg, ucl_object_t *obj, int attr)
			if (cur->type == UCL_STRING)
				pkg_adduser(pkg, ucl_object_tostring(cur));
			else if (cur->type == UCL_OBJECT)
-
				pkg_object(pkg, cur, attr);
+
				pkg_obj(pkg, cur, attr);
			else
				pkg_emit_error("Skipping malformed license");
			break;
@@ -339,7 +339,7 @@ pkg_array(struct pkg *pkg, ucl_object_t *obj, int attr)
			if (cur->type == UCL_STRING)
				pkg_addgroup(pkg, ucl_object_tostring(cur));
			else if (cur->type == UCL_OBJECT)
-
				pkg_object(pkg, cur, attr);
+
				pkg_obj(pkg, cur, attr);
			else
				pkg_emit_error("Skipping malformed license");
			break;
@@ -347,7 +347,7 @@ pkg_array(struct pkg *pkg, ucl_object_t *obj, int attr)
			if (cur->type == UCL_STRING)
				pkg_adddir(pkg, ucl_object_tostring(cur), 1, false);
			else if (cur->type == UCL_OBJECT)
-
				pkg_object(pkg, cur, attr);
+
				pkg_obj(pkg, cur, attr);
			else
				pkg_emit_error("Skipping malformed dirs");
			break;
@@ -382,7 +382,7 @@ pkg_array(struct pkg *pkg, ucl_object_t *obj, int attr)
}

static int
-
pkg_object(struct pkg *pkg, ucl_object_t *obj, int attr)
+
pkg_obj(struct pkg *pkg, ucl_object_t *obj, int attr)
{
	struct sbuf *tmp = NULL;
	ucl_object_t *cur;
modified libpkg/pkg_old.c
@@ -237,7 +237,7 @@ pkg_register_old(struct pkg *pkg)
	pkg_get(pkg, PKG_NAME, &name, PKG_VERSION, &version);
	pkg_old_emit_content(pkg, &content);

-
	pkg_config_string(PKG_CONFIG_DBDIR, &pkgdbdir);
+
	pkgdbdir = pkg_object_string(pkg_config_get("PKG_DBDIR"));
	snprintf(path, sizeof(path), "%s/%s-%s", pkgdbdir, name, version);
	mkdir(path, 0755);

modified libpkg/pkg_ports.c
@@ -244,7 +244,7 @@ meta_dirrm(struct plist *p, char *line, struct file_attr *a, bool try)
		pkg_emit_errno("lstat", testpath);
		if (p->stage != NULL)
			ret = EPKG_FATAL;
-
		pkg_config_bool(PKG_CONFIG_DEVELOPER_MODE, &developer);
+
		developer = pkg_object_bool(pkg_config_get("DEVELOPER_MODE"));
		if (developer) {
			pkg_emit_developer_mode("Plist error: @dirrm %s", line);
			ret = EPKG_FATAL;
@@ -312,7 +312,7 @@ file(struct plist *p, char *line, struct file_attr *a)
		pkg_emit_errno("lstat", testpath);
		if (p->stage != NULL)
			ret = EPKG_FATAL;
-
		pkg_config_bool(PKG_CONFIG_DEVELOPER_MODE, &developer);
+
		developer = pkg_object_bool(pkg_config_get("DEVELOPER_MODE"));
		if (developer) {
			pkg_emit_developer_mode("Plist error, missing file: %s", line);
			ret = EPKG_FATAL;
@@ -785,9 +785,9 @@ external_keyword(struct plist *plist, char *keyword, char *line, struct file_att
	int ret = EPKG_UNKNOWN;
	ucl_object_t *o;

-
	pkg_config_string(PKG_CONFIG_PLIST_KEYWORDS_DIR, &keyword_dir);
+
	keyword_dir = pkg_object_string(pkg_config_get("PLIST_KEYWORDS_DIR"));
	if (keyword_dir == NULL) {
-
		pkg_config_string(PKG_CONFIG_PORTSDIR, &keyword_dir);
+
		keyword_dir = pkg_object_string(pkg_config_get("PORTSDIR"));
		snprintf(keyfile_path, sizeof(keyfile_path),
		    "%s/Keywords/%s.yaml", keyword_dir, keyword);
	} else {
modified libpkg/pkg_repo.c
@@ -68,8 +68,7 @@ pkg_repo_fetch(struct pkg *pkg)

	assert((pkg->type & PKG_REMOTE) == PKG_REMOTE);

-
	if (pkg_config_string(PKG_CONFIG_CACHEDIR, &cachedir) != EPKG_OK)
-
		return (EPKG_FATAL);
+
	cachedir = pkg_object_string(pkg_config_get("PKG_CACHEDIR"));

	pkg_get(pkg, PKG_REPONAME, &reponame,
	    PKG_CKSUM, &sum, PKG_NAME, &name, PKG_VERSION, &version);
modified libpkg/pkg_status.c
@@ -43,8 +43,8 @@ static bool is_exec_at_localbase(const char *progname);
pkg_status_t
pkg_status(int *count)
{
+
	pkg_object	*o;
	const char	*progname;
-
	const char	*dbdir;
	char		 dbpath[MAXPATHLEN];
	int		 numpkgs = 0;
	sqlite3		*db = NULL;
@@ -69,10 +69,8 @@ pkg_status(int *count)
	/* Does the local.sqlite pkg database exist, and can we open
	   it for reading? */

-
	if (pkg_config_string(PKG_CONFIG_DBDIR, &dbdir) != EPKG_OK)
-
		return (PKG_STATUS_NODB);
-

-
	snprintf(dbpath, sizeof(dbpath), "%s/local.sqlite", dbdir);
+
	o = pkg_config_get("PKG_DBDIR");
+
	snprintf(dbpath, sizeof(dbpath), "%s/local.sqlite", pkg_object_string(o));

	if (eaccess(dbpath, R_OK) == -1)
		return (PKG_STATUS_NODB);
modified libpkg/pkgdb.c
@@ -983,6 +983,7 @@ database_access(unsigned mode, const char* dbdir, const char *dbname)
int
pkgdb_access(unsigned mode, unsigned database)
{
+
	pkg_object	*o;
	const char	*dbdir;
	int		 retval = EPKG_OK;

@@ -1006,9 +1007,8 @@ pkgdb_access(unsigned mode, unsigned database)
	 * EPKG_OK: We can go ahead
	 */

-
	if (pkg_config_string(PKG_CONFIG_DBDIR, &dbdir) != EPKG_OK)
-
		return (EPKG_FATAL); /* Config borked */
-

+
	o = pkg_config_get("ABI");
+
	dbdir = pkg_object_string(o);
	if ((mode & ~(PKGDB_MODE_READ|PKGDB_MODE_WRITE|PKGDB_MODE_CREATE))
	    != 0)
		return (EPKG_FATAL); /* EINVAL */
@@ -1059,7 +1059,7 @@ pkgdb_open(struct pkgdb **db_p, pkgdb_t type)
	struct statfs	 stfs;
	bool		 reopen = false;
	char		 localpath[MAXPATHLEN];
-
	const char	*dbdir = NULL;
+
	const char	*dbdir;
	bool		 create = false;
	bool		 createdir = false;
	int		 ret;
@@ -1072,9 +1072,7 @@ pkgdb_open(struct pkgdb **db_p, pkgdb_t type)
			return (EPKG_OK);
	}

-
	if (pkg_config_string(PKG_CONFIG_DBDIR, &dbdir) != EPKG_OK)
-
		return (EPKG_FATAL);
-

+
	dbdir = pkg_object_string(pkg_config_get("PKG_DBDIR"));
	if (!reopen && (db = calloc(1, sizeof(struct pkgdb))) == NULL) {
		pkg_emit_errno("malloc", "pkgdb");
		return EPKG_FATAL;
@@ -2739,9 +2737,9 @@ pkgdb_register_pkg(struct pkgdb *db, struct pkg *pkg, int complete, int forced)
		}
		pkg_get(pkg2, PKG_NAME, &name2, PKG_VERSION, &version2);
		if (!forced) {
-
			pkg_config_bool(PKG_CONFIG_DEVELOPER_MODE, &devmode);
+
			devmode = pkg_object_bool(pkg_config_get("DEVELOPER_MORE"));
			if (!devmode)
-
				pkg_config_bool(PKG_CONFIG_PERMISSIVE, &permissive);
+
				permissive = pkg_object_bool(pkg_config_get("PERMISSIVE"));
			pkg_emit_error("%s-%s conflicts with %s-%s"
					" (installs files into the same place). "
					" Problematic file: %s%s",
@@ -4169,8 +4167,7 @@ pkgshell_open(const char **reponame)

	sqlite3_auto_extension((void(*)(void))sqlcmd_init);

-
	if (pkg_config_string(PKG_CONFIG_DBDIR, &dbdir) != EPKG_OK)
-
		return;
+
	dbdir = pkg_object_string(pkg_config_get("PKG_DBDIR"));

	snprintf(localpath, sizeof(localpath), "%s/local.sqlite", dbdir);
	*reponame = strdup(localpath);
modified libpkg/plugins.c
@@ -57,8 +57,7 @@ struct pkg_plugin {
	void *lh;						/* library handle */
	bool parsed;
	struct plugin_hook *hooks;
-
	struct pkg_config *conf;
-
	struct pkg_config *conf_by_key;
+
	pkg_object *conf;
	struct pkg_plugin *next;
};

@@ -167,192 +166,51 @@ pkg_plugin_get(struct pkg_plugin *p, pkg_plugin_key key)
}

int
-
pkg_plugin_conf_add_string(struct pkg_plugin *p, int id, const char *key, const char *def)
+
pkg_plugin_conf_add_string(struct pkg_plugin *p, const char *key, const char *def)
{
-
	struct pkg_config *conf;
-
	char *val;
-

-
	HASH_FIND_INT(p->conf, &id, conf);
-
	if (conf != NULL) {
-
		pkg_emit_error("A configuration with the same id is already registred");
-
		return (EPKG_FATAL);
-
	}
-

-
	HASH_FIND(hhkey, p->conf_by_key, key, strlen(key), conf);
-
	if (conf != NULL) {
-
		pkg_emit_error("A configuration with the same key(%s) is already registred", key);
-
		return (EPKG_FATAL);
-
	}
-

-
	conf = malloc(sizeof(struct pkg_config));
-
	conf->id = id;
-
	conf->key = key;
-
	conf->type = PKG_CONFIG_STRING;
-
	conf->fromenv = false;
-
	val = getenv(key);
-
	if (val != NULL) {
-
		conf->string = strdup(val);
-
		conf->fromenv = true;
-
	} else if (def != NULL) {
-
		conf->string = strdup(def);
-
	} else {
-
		conf->string = NULL;
-
	}
-

-
	HASH_ADD_INT(p->conf, id, conf);
-
	HASH_ADD_KEYPTR(hhkey, p->conf_by_key, conf->key,
-
	    strlen(conf->key), conf);
+
	p->conf = ucl_object_insert_key(p->conf,
+
	    ucl_object_fromstring_common(def, 0, 0),
+
	    key, strlen(key), false);

	return (EPKG_OK);
}

int
-
pkg_plugin_conf_add_bool(struct pkg_plugin *p, int id, const char *key, bool boolean)
+
pkg_plugin_conf_add_bool(struct pkg_plugin *p, const char *key, bool boolean)
{
-
	struct pkg_config *conf;
-
	char *val;
-

-
	HASH_FIND_INT(p->conf, &id, conf);
-
	if (conf != NULL) {
-
		pkg_emit_error("A configuration with the same id is already registred");
-
		return (EPKG_FATAL);
-
	}
-

-
	HASH_FIND(hhkey, p->conf_by_key, key, strlen(key), conf);
-
	if (conf != NULL) {
-
		pkg_emit_error("A configuration with the same key(%s) is already registred", key);
-
		return (EPKG_FATAL);
-
	}
-

-
	conf = malloc(sizeof(struct pkg_config));
-
	conf->id = id;
-
	conf->key = key;
-
	conf->type = PKG_CONFIG_BOOL;
-
	conf->fromenv = false;
-
	val = getenv(key);
-
	if (val != NULL) {
-
		conf->fromenv = true;
-
		if (val != NULL && (
-
		    strcmp(val, "1") == 0 ||
-
		    strcasecmp(val, "yes") == 0 ||
-
		    strcasecmp(val, "true") == 0 ||
-
		    strcasecmp(val, "on") == 0)) {
-
			conf->boolean = true;
-
		} else {
-
			conf->boolean = false;
-
		}
-
	} else {
-
		conf->boolean = boolean;
-
	}
-

-
	HASH_ADD_INT(p->conf, id, conf);
-
	HASH_ADD_KEYPTR(hhkey, p->conf_by_key, conf->key,
-
	    strlen(conf->key), conf);
+
	p->conf = ucl_object_insert_key(p->conf,
+
	    ucl_object_frombool(boolean),
+
	    key, strlen(key), false);

	return (EPKG_OK);
}

int
-
pkg_plugin_conf_add_integer(struct pkg_plugin *p, int id, const char *key, int64_t integer)
+
pkg_plugin_conf_add_int(struct pkg_plugin *p, const char *key, int64_t integer)
{
-
	struct pkg_config *conf;
-
	const char *errstr;
-
	char *val;
-

-
	HASH_FIND_INT(p->conf, &id, conf);
-
	if (conf != NULL) {
-
		pkg_emit_error("A configuration with the same id is already registred");
-
		return (EPKG_FATAL);
-
	}
-

-
	HASH_FIND(hhkey, p->conf_by_key, key, strlen(key), conf);
-
	if (conf != NULL) {
-
		pkg_emit_error("A configuration with the same key(%s) is already registred", key);
-
		return (EPKG_FATAL);
-
	}
-

-
	conf = malloc(sizeof(struct pkg_config));
-
	conf->id = id;
-
	conf->key = key;
-
	conf->type = PKG_CONFIG_STRING;
-
	conf->fromenv = false;
-
	val = getenv(key);
-
	if (val != NULL) {
-
		conf->fromenv = true;
-
		conf->integer = strtonum(val, 0, INT64_MAX, &errstr);
-
		if (errstr != NULL) {
-
			pkg_emit_error("Unable to convert %s to int64: %s",
-
			    val, errstr);
-
			free(conf);
-
			return (EPKG_FATAL);
-
		}
-
	} else {
-
		conf->integer = integer;
-
	}
-

-
	HASH_ADD_INT(p->conf, id, conf);
-
	HASH_ADD_KEYPTR(hhkey, p->conf_by_key, conf->key,
-
	    strlen(conf->key), conf);
+
	p->conf = ucl_object_insert_key(p->conf,
+
	    ucl_object_fromint(integer),
+
	    key, strlen(key), false);

	return (EPKG_OK);
}

int
-
pkg_plugin_conf_add_kvlist(struct pkg_plugin *p, int id, const char *key)
+
pkg_plugin_conf_add_object(struct pkg_plugin *p, const char *key)
{
-
	struct pkg_config *conf;
-

-
	HASH_FIND_INT(p->conf, &id, conf);
-
	if (conf != NULL) {
-
		pkg_emit_error("A configuration with the same id is already registred");
-
		return (EPKG_FATAL);
-
	}
-

-
	HASH_FIND(hhkey, p->conf_by_key, key, strlen(key), conf);
-
	if (conf != NULL) {
-
		pkg_emit_error("A configuration with the same key(%s) is already registred", key);
-
		return (EPKG_FATAL);
-
	}
-

-
	conf = malloc(sizeof(struct pkg_config));
-
	conf->id = id;
-
	conf->key = key;
-
	conf->type = PKG_CONFIG_KVLIST;
-
	conf->kvlist = NULL;
-

-
	HASH_ADD_INT(p->conf, id, conf);
-
	HASH_ADD_KEYPTR(hhkey, p->conf_by_key, conf->key,
-
	    strlen(conf->key), conf);
+
	p->conf = ucl_object_insert_key(p->conf, 
+
	    ucl_object_typed_new(UCL_OBJECT),
+
	    key, strlen(key), false);

	return (EPKG_OK);
}

int
-
pkg_plugin_conf_add_list(struct pkg_plugin *p, int id, const char *key)
+
pkg_plugin_conf_add_array(struct pkg_plugin *p, const char *key)
{
-
	struct pkg_config *conf;
-

-
	HASH_FIND_INT(p->conf, &id, conf);
-
	if (conf != NULL) {
-
		pkg_emit_error("A configuration with the same id is already registred");
-
		return (EPKG_FATAL);
-
	}
-

-
	HASH_FIND(hhkey, p->conf_by_key, key, strlen(key), conf);
-
	if (conf != NULL) {
-
		pkg_emit_error("A configuration with the same key(%s) is already registred", key);
-
		return (EPKG_FATAL);
-
	}
-

-
	conf = malloc(sizeof(struct pkg_config));
-
	conf->id = id;
-
	conf->key = key;
-
	conf->type = PKG_CONFIG_LIST;
-
	conf->list = NULL;
-

-
	HASH_ADD_INT(p->conf, id, conf);
-
	HASH_ADD_KEYPTR(hhkey, p->conf_by_key, conf->key,
-
	    strlen(conf->key), conf);
+
	p->conf = ucl_object_insert_key(p->conf,
+
	    ucl_object_typed_new(UCL_ARRAY),
+
	    key, strlen(key), false);

	return (EPKG_OK);
}
@@ -377,36 +235,42 @@ pkg_plugins_init(void)
	struct pkg_plugin *p = NULL;
	struct pkg_config_value *v = NULL;
	char pluginfile[MAXPATHLEN];
+
	ucl_object_t *obj, *cur;
+
	ucl_object_iter_t it = NULL;
	const char *plugdir;
	bool plug_enabled = false;
	int (*init_func)(struct pkg_plugin *);

-
	pkg_config_bool(PKG_CONFIG_ENABLE_PLUGINS, &plug_enabled);
+
	plug_enabled = pkg_object_bool(pkg_config_get("PKG_ENABLE_PLUGINS"));
	if (!plug_enabled)
		return (EPKG_OK);
	/*
	 * Discover available plugins
	 */
-
	pkg_config_string(PKG_CONFIG_PLUGINS_DIR, &plugdir);
+
	plugdir = pkg_object_string(pkg_config_get("PKG_PLUGINS_DIR"));

-
	while (pkg_config_list(PKG_CONFIG_PLUGINS, &v) == EPKG_OK) {
+
	obj = pkg_config_get("PLUGINS");
+
	while ((cur = ucl_iterate_object(obj, &it, false))) {
		/*
		 * Load the plugin
		 */
+
		if (cur->type != UCL_STRING)
+
			continue;
+

		snprintf(pluginfile, sizeof(pluginfile), "%s/%s.so", plugdir,
-
		    pkg_config_value(v));
+
		    pkg_object_string(cur));
		p = calloc(1, sizeof(struct pkg_plugin));
		if ((p->lh = dlopen(pluginfile, RTLD_LAZY)) == NULL) {
			pkg_emit_error("Loading of plugin '%s' failed: %s",
-
			    pkg_config_value(v), dlerror());
+
			    pkg_object_string(cur), dlerror());
			free(p);
			return (EPKG_FATAL);
		}
		if ((init_func = dlsym(p->lh, "pkg_plugin_init")) == NULL) {
			pkg_emit_error("Cannot load init function for plugin '%s'",
-
			     pkg_config_value(v));
+
			     pkg_object_string(cur));
			pkg_emit_error("Plugin '%s' will not be loaded: %s",
-
			      pkg_config_value(v), dlerror());
+
			      pkg_object_string(cur), dlerror());
			dlclose(p->lh);
			free(p);
			return (EPKG_FATAL);
@@ -424,124 +288,19 @@ pkg_plugins_init(void)
}

int
-
pkg_plugin_conf_string(struct pkg_plugin *p, int key, const char **val)
-
{
-
	struct pkg_config *conf;
-

-
	if (p->parsed != true) {
-
		pkg_emit_error("configuration file not parsed");
-
		return (EPKG_FATAL);
-
	}
-

-
	HASH_FIND_INT(p->conf, &key, conf);
-
	if (conf == NULL)
-
		*val = NULL;
-
	else
-
		*val = conf->string;
-

-
	return (EPKG_OK);
-
}
-

-
int
-
pkg_plugin_conf_integer(struct pkg_plugin *p, int key, int64_t *val)
-
{
-
	struct pkg_config *conf;
-

-
	if (p->parsed != true) {
-
		pkg_emit_error("configuration file not parsed");
-
		return (EPKG_FATAL);
-
	}
-

-
	HASH_FIND_INT(p->conf, &key, conf);
-
	if (conf == NULL)
-
		return (EPKG_FATAL);
-

-
	*val = conf->integer;
-

-
	return (EPKG_OK);
-
}
-

-
int
-
pkg_plugin_conf_bool(struct pkg_plugin *p, int key, bool *val)
-
{
-
	struct pkg_config *conf;
-

-
	if (p->parsed != true) {
-
		pkg_emit_error("configuration file not parsed");
-
		return (EPKG_FATAL);
-
	}
-

-
	HASH_FIND_INT(p->conf, &key, conf);
-
	if (conf == NULL)
-
		return (EPKG_FATAL);
-

-
	*val = conf->boolean;
-

-
	return (EPKG_OK);
-
}
-

-
int
-
pkg_plugin_conf_kvlist(struct pkg_plugin *p, int key, struct pkg_config_kv **kv)
-
{
-
	struct pkg_config *conf;
-

-
	if (p->parsed != true) {
-
		pkg_emit_error("configuration file not parsed");
-
		return (EPKG_FATAL);
-
	}
-

-
	HASH_FIND_INT(p->conf, &key, conf);
-
	if (conf == NULL)
-
		return (EPKG_FATAL);
-

-
	if (conf->type != PKG_CONFIG_KVLIST) {
-
		pkg_emit_error("this config entry is not a \"key: value\" list");
-
		return (EPKG_FATAL);
-
	}
-

-
	HASH_NEXT(conf->kvlist, (*kv));
-
}
-

-
int
-
pkg_plugin_conf_list(struct pkg_plugin *p, int key, struct pkg_config_value **v)
-
{
-
	struct pkg_config *conf;
-

-
	if (p->parsed != true) {
-
		pkg_emit_error("configuration file not parsed");
-
		return (EPKG_FATAL);
-
	}
-

-
	HASH_FIND_INT(p->conf, &key, conf);
-
	if (conf == NULL)
-
		return (EPKG_FATAL);
-

-
	if (conf->type != PKG_CONFIG_LIST) {
-
		pkg_emit_error("this config entry is not a list");
-
		return (EPKG_FATAL);
-
	}
-

-
	HASH_NEXT(conf->list, (*v));
-
}
-

-
int
-
pkg_plugin_confs(struct pkg_plugin *p, struct pkg_config **conf)
-
{
-
	HASH_NEXT(p->conf, (*conf));
-
}
-

-
int
pkg_plugin_parse(struct pkg_plugin *p)
{
	char confpath[MAXPATHLEN];
	const char *path;
	const char *plugname;
	struct ucl_parser *pr;
-
	ucl_object_t *obj;
+
	ucl_object_t *obj, *cur, *o;
+
	ucl_object_iter_t it = NULL;
+
	const char *key;

	pr = ucl_parser_new(0);

-
	pkg_config_string(PKG_CONFIG_PLUGINS_CONF_DIR, &path);
+
	path = pkg_object_string(pkg_config_get("PLUGINS_CONF_DIR"));
	plugname = pkg_plugin_get(p, PKG_PLUGIN_NAME);

	snprintf(confpath, sizeof(confpath), "%s/%s.conf", path, plugname);
@@ -559,8 +318,21 @@ pkg_plugin_parse(struct pkg_plugin *p)
	}

	obj = ucl_parser_get_object(pr);
-
	if (obj->type == UCL_OBJECT)
-
		pkg_object_walk(obj, p->conf_by_key);
+

+
	while ((cur = ucl_iterate_object(obj, &it, true))) {
+
		key = ucl_object_key(cur);
+
		o = ucl_object_find_key(p->conf, key);
+
		if (o == NULL)
+
			continue;
+

+
		if (o->type != cur->type) {
+
			pkg_emit_error("Malformed key %s, ignoring", key);
+
			continue;
+
		}
+

+
		ucl_object_delete_key(p->conf, key);
+
		p->conf = ucl_object_insert_key(p->conf, cur, key, strlen(key), false);
+
	}

	p->parsed = true;
	ucl_object_free(obj);
@@ -592,3 +364,9 @@ pkg_plugins_shutdown(void)

	return;
}
+

+
pkg_object *
+
pkg_plugin_conf(struct pkg_plugin *p)
+
{
+
	return (p->conf);
+
}
modified libpkg/private/pkg.h
@@ -265,35 +265,6 @@ struct pkg_shlib {
	UT_hash_handle	hh;
};

-
struct pkg_config {
-
	int id;
-
	pkg_config_t type;
-
	const char *key;
-
	const void *def;
-
	const char *desc;
-
	bool fromenv;
-
	union {
-
		char *string;
-
		uint64_t integer;
-
		bool boolean;
-
		struct pkg_config_kv *kvlist;
-
		struct pkg_config_value *list;
-
	};
-
	UT_hash_handle hh;
-
	UT_hash_handle hhkey;
-
};
-

-
struct pkg_config_kv {
-
	char *key;
-
	char *value;
-
	UT_hash_handle hh;
-
};
-

-
struct pkg_config_value {
-
	char *value;
-
	UT_hash_handle hh;
-
};
-

struct pkg_note {
	struct sbuf	*tag;
	struct sbuf	*value;
@@ -480,8 +451,6 @@ int pkgdb_register_finale(struct pkgdb *db, int retcode);

int pkg_register_shlibs(struct pkg *pkg, const char *root);

-
void pkg_object_walk(ucl_object_t *o, struct pkg_config *conf_by_key);
-

int pkg_emit_manifest_sbuf(struct pkg*, struct sbuf *, short, char **);
int pkg_emit_filelist(struct pkg *, FILE *);

modified libpkg/scripts.c
@@ -90,7 +90,7 @@ pkg_script_run(struct pkg * const pkg, pkg_script type)
		if (j == map[i].a || j == map[i].b) {
			sbuf_reset(script_cmd);
			setenv("PKG_PREFIX", prefix, 1);
-
			pkg_config_bool(PKG_CONFIG_DEBUG_SCRIPTS, &debug);
+
			debug = pkg_object_bool(pkg_config_get("DEBUG_SCRIPTS"));
			if (debug)
				sbuf_printf(script_cmd, "set -x\n");
			pkg_sbuf_printf(script_cmd, "set -- %n-%v", pkg, pkg);
modified libpkg/ssh.c
@@ -59,7 +59,7 @@ pkg_sshserve(int fd)
	char fpath[MAXPATHLEN];
	const char *restricted = NULL;

-
	pkg_config_string(PKG_CONFIG_SSH_RESTRICT_DIR, &restricted);
+
	restricted = pkg_object_string(pkg_config_get("SSH_RESTRICT_DIR"));

	printf("ok: pkg "PKGVERSION"\n");
	for (;;) {
modified libpkg/update.c
@@ -827,11 +827,7 @@ repo_update_binary_pkgs(struct pkg_repo *repo, bool force)
	if (!pkg_repo_enabled(repo))
		return (EPKG_OK);

-
	if (pkg_config_string(PKG_CONFIG_DBDIR, &dbdir) != EPKG_OK) {
-
		pkg_emit_error("Cant get dbdir config entry");
-
		return (EPKG_FATAL);
-
	}
-

+
	dbdir = pkg_object_string(pkg_config_get("PKG_DBDIR"));
	pkg_debug(1, "PkgRepo: verifying update for %s", pkg_repo_name(repo));
	snprintf(repofile, sizeof(repofile), "%s/%s.sqlite", dbdir, pkg_repo_name(repo));

modified libpkg/utils.c
@@ -479,7 +479,7 @@ bool
is_valid_abi(const char *arch, bool emit_error) {
	const char *myarch;

-
	pkg_config_string(PKG_CONFIG_ABI, &myarch);
+
	myarch = pkg_object_string(pkg_config_get("ABI"));

	if (fnmatch(arch, myarch, FNM_CASEFOLD) == FNM_NOMATCH &&
	    strncmp(arch, myarch, strlen(myarch)) != 0) {
modified src/annotate.c
@@ -198,7 +198,7 @@ exec_annotate(int argc, char **argv)
	int		 retcode;
	int		 exitcode = EX_OK;

-
	pkg_config_bool(PKG_CONFIG_ASSUME_ALWAYS_YES, &yes);
+
	yes = pkg_object_bool(pkg_config_get("ASSUME_ALWAYS_YES"));

	while ((ch = getopt(argc, argv, "aADgiMqxy")) != -1) {
		switch (ch) {
modified src/audit.c
@@ -726,10 +726,7 @@ exec_audit(int argc, char **argv)
	int ret = EX_OK, res;
	const char *portaudit_site = NULL;

-
	if (pkg_config_string(PKG_CONFIG_DBDIR, &db_dir) != EPKG_OK) {
-
		warnx("PKG_DBIR is missing");
-
		return (EX_CONFIG);
-
	}
+
	db_dir = pkg_object_string(pkg_config_get("PKG_DBDIR"));

	while ((ch = getopt(argc, argv, "qF")) != -1) {
		switch (ch) {
@@ -750,10 +747,7 @@ exec_audit(int argc, char **argv)
	snprintf(audit_file, sizeof(audit_file), "%s/vuln.xml", db_dir);

	if (fetch == true) {
-
		if (pkg_config_string(PKG_CONFIG_VULNXML_SITE, &portaudit_site) != EPKG_OK) {
-
			warnx("VULNXML_SITE is missing");
-
			return (EX_CONFIG);
-
		}
+
		portaudit_site = pkg_object_string(pkg_config_get("VULNXML_SITE"));
		if (fetch_and_extract(portaudit_site, audit_file) != EPKG_OK) {
			return (EX_IOERR);
		}
modified src/autoremove.c
@@ -54,7 +54,7 @@ exec_autoremove(__unused int argc, __unused char **argv)
	nbactions = nbdone = 0;
	pkg_flags f = PKG_FLAG_FORCE;

-
	pkg_config_bool(PKG_CONFIG_ASSUME_ALWAYS_YES, &yes);
+
	yes = pkg_object_bool(pkg_config_get("ASSUME_ALWAYS_YES"));

	while ((ch = getopt(argc, argv, "ynq")) != -1) {
		switch (ch) {
modified src/check.c
@@ -265,7 +265,7 @@ exec_check(int argc, char **argv)
	int i;
	int verbose = 0;

-
	pkg_config_bool(PKG_CONFIG_ASSUME_ALWAYS_YES, &yes);
+
	yes = pkg_object_bool(pkg_config_get("ASSUME_ALWAYS_YES"));

	struct deps_head dh = STAILQ_HEAD_INITIALIZER(dh);

modified src/clean.c
@@ -233,7 +233,7 @@ exec_clean(int argc, char **argv)
	int		 ch;
	struct pkg_manifest_key *keys = NULL;

-
	pkg_config_bool(PKG_CONFIG_ASSUME_ALWAYS_YES, &yes);
+
	yes = pkg_object_bool(pkg_config_get("ASSUME_ALWAYS_YES"));

	while ((ch = getopt(argc, argv, "anqy")) != -1) {
		switch (ch) {
@@ -257,10 +257,7 @@ exec_clean(int argc, char **argv)
	argc -= optind;
	argv += optind;

-
	if (pkg_config_string(PKG_CONFIG_CACHEDIR, &cachedir) != EPKG_OK) {
-
		warnx("Cannot get cachedir config entry");
-
		return 1;
-
	}
+
	cachedir = pkg_object_string(pkg_config_get("PKG_CACHEDIR"));

	paths[0] = __DECONST(char*, cachedir);
	paths[1] = NULL;
modified src/config.c
@@ -45,9 +45,8 @@ usage_config(void)
int
exec_config(int argc, char **argv)
{
-
	struct pkg_config *conf;
-
	struct pkg_config_value *list;
-
	struct pkg_config_kv *kv;
+
	pkg_object *conf, *o;
+
	pkg_iter it = NULL;
	const char *buf;
	char *key;
	int64_t integer;
@@ -63,38 +62,37 @@ exec_config(int argc, char **argv)
	for (i = 0; key[i] != '\0'; i++)
		key[i] = toupper(key[i]);

-
	conf = pkg_config_lookup(key);
+
	conf = pkg_config_get(key);
	if (conf == NULL) {
		warnx("No such configuration options: %s", key);
		return (EX_SOFTWARE);
	}

-
	switch (pkg_config_type(conf)) {
-
	case PKG_CONFIG_STRING:
-
		pkg_config_string(pkg_config_id(conf), &buf);
+
	switch (pkg_object_type(conf)) {
+
	case PKG_STRING:
+
		buf = pkg_object_string(conf);
		printf("%s\n", buf == NULL ? "" : buf);
		break;
-
	case PKG_CONFIG_BOOL:
-
		pkg_config_bool(pkg_config_id(conf), &b);
+
	case PKG_BOOL:
+
		b = pkg_object_bool(conf);
		printf("%s\n", b ? "yes" : "no");
		break;
-
	case PKG_CONFIG_INTEGER:
-
		pkg_config_int64(pkg_config_id(conf), &integer);
+
	case PKG_INT:
+
		integer = pkg_object_int(conf);
		printf("%"PRId64"\n", integer);
		break;
-
	case PKG_CONFIG_KVLIST:
-
		kv = NULL;
-
		while (pkg_config_kvlist(pkg_config_id(conf), &kv) == EPKG_OK) {
-
			printf("%s: %s\n", pkg_config_kv_get(kv, PKG_CONFIG_KV_KEY),
-
			    pkg_config_kv_get(kv, PKG_CONFIG_KV_VALUE));
+
	case PKG_OBJECT:
+
		while ((o = pkg_object_iterate(conf, it))) {
+
			printf("%s: %s\n", pkg_object_key(o), pkg_object_string(o));
		}
		break;
-
	case PKG_CONFIG_LIST:
-
		list = NULL;
-
		while (pkg_config_list(pkg_config_id(conf), &list) == EPKG_OK) {
-
			printf("%s\n", pkg_config_value(list));
+
	case PKG_ARRAY:
+
		while ((o = pkg_object_iterate(conf, it))) {
+
			printf("%s\n", pkg_object_string(o));
		}
		break;
+
	default:
+
		break;
	}

	return (EX_OK);
modified src/delete.c
@@ -60,7 +60,7 @@ exec_delete(int argc, char **argv)
	pkg_flags f = PKG_FLAG_NONE;
	int i;

-
	pkg_config_bool(PKG_CONFIG_ASSUME_ALWAYS_YES, &yes);
+
	yes = pkg_object_bool(pkg_config_get("ASSUME_ALWAYS_YES"));

	while ((ch = getopt(argc, argv, "aDfginqRxy")) != -1) {
		switch (ch) {
modified src/fetch.c
@@ -64,8 +64,8 @@ exec_fetch(int argc, char **argv)
	match_t		 match = MATCH_EXACT;
	pkg_flags	 f = PKG_FLAG_NONE;

-
	pkg_config_bool(PKG_CONFIG_REPO_AUTOUPDATE, &auto_update);
-
	pkg_config_bool(PKG_CONFIG_ASSUME_ALWAYS_YES, &yes);
+
	auto_update = pkg_object_bool(pkg_config_get("REPO_AUTOUPDATE"));
+
	yes = pkg_object_bool(pkg_config_get("ASSUME_ALWAYS_YES"));

	while ((ch = getopt(argc, argv, "adgiqr:Uuxy")) != -1) {
		switch (ch) {
modified src/install.c
@@ -67,8 +67,8 @@ exec_install(int argc, char **argv)
	nbactions = nbdone = 0;
	pkg_flags f = PKG_FLAG_NONE | PKG_FLAG_PKG_VERSION_TEST;

-
	pkg_config_bool(PKG_CONFIG_ASSUME_ALWAYS_YES, &yes_arg);
-
	pkg_config_bool(PKG_CONFIG_REPO_AUTOUPDATE, &auto_update);
+
	yes_arg = pkg_object_bool(pkg_config_get("ASSUME_ALWAYS_YES"));
+
	auto_update = pkg_object_bool(pkg_config_get("REPO_AUTOUPDATE"));
	yes = yes_arg;

	while ((ch = getopt(argc, argv, "AfgIiFnqRr:Uxy")) != -1) {
modified src/lock.c
@@ -118,7 +118,7 @@ exec_lock_unlock(int argc, char **argv, enum action action)
	int exitcode = EX_OK;
	int ch;

-
	pkg_config_bool(PKG_CONFIG_ASSUME_ALWAYS_YES, &yes);
+
	yes = pkg_object_bool(pkg_config_get("ASSUME_ALWAYS_YES"));

	while ((ch = getopt(argc, argv, "agiqxy")) != -1) {
		switch (ch) {
modified src/main.c
@@ -180,7 +180,7 @@ usage(const char *conffile, const char *reposdir, FILE *out, enum pkg_usage_reas
		if (!pkg_initialized() && pkg_init(conffile, reposdir) != EPKG_OK)
			errx(EX_SOFTWARE, "Cannot parse configuration file!");

-
		pkg_config_bool(PKG_CONFIG_ENABLE_PLUGINS, &plugins_enabled);
+
		plugins_enabled = pkg_object_bool(pkg_config_get("PKG_ENABLE_PLUGINS"));

		if (plugins_enabled) {
			if (pkg_plugins_init() != EPKG_OK)
@@ -232,7 +232,7 @@ exec_help(int argc, char **argv)
		}
	}

-
	pkg_config_bool(PKG_CONFIG_ENABLE_PLUGINS, &plugins_enabled);
+
	plugins_enabled = pkg_object_bool(pkg_config_get("PKG_ENABLE_PLUGINS"));

	if (plugins_enabled) {
		STAILQ_FOREACH(c, &plugins, next) {
@@ -265,170 +265,62 @@ exec_help(int argc, char **argv)
}

static void
-
show_config_info(int version)
-
{
-
	struct pkg_config	*conf = NULL;
-
	struct pkg_config_value	*list = NULL;
-
	struct pkg_config_kv	*kv = NULL;
-
	const char		*configname;
-
	const char		*buf = NULL;
-
	int			 cout;
-
	int64_t			 integer;
-
	bool			 b;
-

-
	assert(version > 1);
-

-
	while (pkg_configs(&conf) == EPKG_OK) {
-
		configname = pkg_config_name(conf);
-

-
		switch (pkg_config_type(conf)) {
-
		case PKG_CONFIG_STRING:
-
			pkg_config_string(pkg_config_id(conf), &buf);
-
			cout = printf("%-24s: %s", configname,
-
			    buf == NULL ? "" : buf);
-

-
			if (version > 2) {
-
				pkg_config_desc(pkg_config_id(conf), &buf);
-
				if (buf != NULL) {
-
					cout = (cout >= 48 ? 1 : 48 - cout);
-
					printf("%*s/* %s */", cout, "", buf);
-
				}
-
			}
-
			printf("\n");
-
			break;
-
		case PKG_CONFIG_BOOL:
-
			pkg_config_bool(pkg_config_id(conf), &b);
-
			cout = printf("%-24s: %s", configname, b ? "yes": "no");
-

-
			if (version > 2) {
-
				pkg_config_desc(pkg_config_id(conf), &buf);
-
				if (buf != NULL) {
-
					cout = (cout >= 48 ? 1 : 48 - cout);
-
					printf("%*s/* %s */", cout, "", buf);
-
				}
-
			}
-
			printf("\n");
-
			break;
-
		case PKG_CONFIG_INTEGER:
-
			pkg_config_int64(pkg_config_id(conf), &integer);
-
			cout = printf("%-24s: %"PRId64, configname, integer);
-

-
			if (version > 2) {
-
				pkg_config_desc(pkg_config_id(conf), &buf);
-
				if (buf != NULL) {
-
					cout = (cout >= 48 ? 1 : 48 - cout);
-
					printf("%*s/* %s */", cout, "", buf);
-
				}
-
			}
-
			printf("\n");
-
			break;
-
		case PKG_CONFIG_KVLIST:
-
			cout = printf("%-24s: {", configname);
-

-
			if (version > 2) {
-
				pkg_config_desc(pkg_config_id(conf), &buf);
-
				if (buf != NULL) {
-
					cout = (cout >= 48 ? 1 : 48 - cout);
-
					printf("%*s/* %s */", cout, "", buf);
-
				}
-
			}
-
			printf("\n");
-

-
			kv = NULL;
-
			while (pkg_config_kvlist(pkg_config_id(conf), &kv)
-
			       == EPKG_OK) {
-
				printf("  %s: %s,\n",
-
				    pkg_config_kv_get(kv, PKG_CONFIG_KV_KEY),
-
				    pkg_config_kv_get(kv, PKG_CONFIG_KV_VALUE));
-
			}
-
			printf("}\n");
-
			break;
-
		case PKG_CONFIG_LIST:
-
			cout = printf("%-24s: [", configname);
-

-
			if (version > 2) {
-
				pkg_config_desc(pkg_config_id(conf), &buf);
-
				if (buf != NULL) {
-
					cout = (cout >= 48 ? 1 : 48 - cout);
-
					printf("%*s/* %s */", cout, "", buf);
-
				}
-
			}
-
			printf("\n");
-

-
			list = NULL;
-
			while (pkg_config_list(pkg_config_id(conf), &list)
-
			       == EPKG_OK) {
-
				printf("  %-s,\n", pkg_config_value(list));
-
			}
-
			printf("]\n");
-
			break;
-
		}
-
	}
-
}
-

-
static void
show_plugin_info(void)
{
+
	pkg_object		*conf, *cur, *obj;
+
	pkg_iter		it, it2;
	struct pkg_plugin	*p = NULL;
-
	struct pkg_config	*conf = NULL;
-
	struct pkg_config_value	*list = NULL;
-
	struct pkg_config_kv	*kv = NULL;
	const char		*configname;
	const char		*buf;
	int64_t			 integer;
	bool			 b;

	while (pkg_plugins(&p) == EPKG_OK) {
-
		conf = NULL;
+
		conf = pkg_plugin_conf(p);
		printf("Configuration for plugin: %s\n",
		    pkg_plugin_get(p, PKG_PLUGIN_NAME));

-
		while (pkg_plugin_confs(p, &conf) == EPKG_OK) {
-
			configname = pkg_config_name(conf);
+
		it = NULL;
+
		while ((cur = pkg_object_iterate(conf, &it))) {
+
			configname = pkg_object_key(cur);

-
			switch (pkg_config_type(conf)) {
-
			case PKG_CONFIG_STRING:
-
				pkg_plugin_conf_string(p, pkg_config_id(conf),
-
				    &buf);
+
			switch (pkg_object_type(cur)) {
+
			case PKG_STRING:
+
				buf = pkg_object_string(cur);
				if (buf == NULL)
					printf("\t%16s:\n", configname);
				else
					printf("\t%16s: %s\n", configname, buf);
				break;
-
			case PKG_CONFIG_BOOL:
-
				pkg_plugin_conf_bool(p, pkg_config_id(conf),
-
				    &b);
+
			case PKG_BOOL:
+
				b = pkg_object_bool(cur);
				printf("\t%16s: %s\n", configname,
			            b ? "yes": "no");
				break;
-
			case PKG_CONFIG_INTEGER:
-
				pkg_plugin_conf_integer(p, pkg_config_id(conf),
-
				    &integer);
+
			case PKG_INT:
+
				integer = pkg_object_int(cur);
				printf("\t%16s: %"PRId64"\n", configname,
                                    integer);
				break;
-
			case PKG_CONFIG_KVLIST:
+
			case PKG_OBJECT:
				printf("\t%16s:\n", configname);
-
				kv = NULL;
-
				while (pkg_plugin_conf_kvlist(p,
-
                                    pkg_config_id(conf), &kv) == EPKG_OK) {
+
				it2 = NULL;
+
				while ((obj = pkg_object_iterate(cur, &it2))) {
					printf("\t\t- %8s: %s\n",
-
					    pkg_config_kv_get(kv,
-
					        PKG_CONFIG_KV_KEY),
-
					    pkg_config_kv_get(kv,
-
						PKG_CONFIG_KV_VALUE));
+
					    pkg_object_key(obj),
+
					    pkg_object_string(obj));
				}
				break;
-
			case PKG_CONFIG_LIST:
+
			case PKG_ARRAY:
				printf("\t%16s:\n", configname);
-

-
				list = NULL;
-
				while (pkg_plugin_conf_list(p,
-
			            pkg_config_id(conf), &list) == EPKG_OK) {
+
				it2 = NULL;
+
				while ((obj = pkg_object_iterate(cur, &it2))) {
					printf("\t\t- %8s\n",
-
					    pkg_config_value(list));
+
					    pkg_object_string(obj));
				}
				break;
+
			case PKG_NULL:
+
				break;
			}
		}
	}
@@ -502,7 +394,7 @@ show_version_info(int version)
	if (version == 1)
		exit(EX_OK);

-
	show_config_info(version);
+
	printf("%s\n", pkg_config_dump());
	show_plugin_info();
	show_repository_info();
	
@@ -587,7 +479,8 @@ main(int argc, char **argv)
	struct plugcmd *c;
	const char *conffile = NULL;
	const char *reposdir = NULL;
-
	struct pkg_config_kv *alias = NULL;
+
	pkg_object *alias, *cur;
+
	pkg_iter it = NULL;
	const char *alias_value;
	char **newargv, *arg, *args;
	int newargc, newargvl;
@@ -693,7 +586,7 @@ main(int argc, char **argv)
	if (atexit(&pkg_shutdown) != 0)
		errx(EX_SOFTWARE, "register pkg_shutdown() to run at exit");

-
	pkg_config_bool(PKG_CONFIG_ENABLE_PLUGINS, &plugins_enabled);
+
	plugins_enabled = pkg_object_bool(pkg_config_get("PKG_ENABLE_PLUGINS"));

	if (plugins_enabled) {
		struct pkg_plugin	*p = NULL;
@@ -755,10 +648,10 @@ main(int argc, char **argv)

	newargv = argv;
	newargc = argc;
-
	alias = NULL;
-
	while (pkg_config_kvlist(PKG_CONFIG_ALIAS, &alias) == EPKG_OK) {
-
		if (strcmp(argv[0], pkg_config_kv_get(alias, PKG_CONFIG_KV_KEY)) == 0) {
-
			if ((alias_value = pkg_config_kv_get(alias, PKG_CONFIG_KV_VALUE)) == NULL)
+
	alias = pkg_config_get("ALIAS");
+
	while ((cur = pkg_object_iterate(alias, &it))) {
+
		if (strcmp(argv[0], pkg_object_key(cur)) == 0) {
+
			if ((alias_value = pkg_object_string(cur)) == NULL)
				continue;
			argv++;
			argc--;
modified src/register.c
@@ -109,7 +109,7 @@ exec_register(int argc, char **argv)
	int		 ret     = EPKG_OK;
	int		 retcode = EX_OK;

-
	pkg_config_bool(PKG_CONFIG_DEVELOPER_MODE, &developer);
+
	developer = pkg_object_bool(pkg_config_get("DEVELOPER_MODE"));

	if (pkg_new(&pkg, PKG_INSTALLED) != EPKG_OK)
		err(EX_OSERR, "malloc");
modified src/rquery.c
@@ -116,7 +116,7 @@ exec_rquery(int argc, char **argv)
	bool old_quiet;
	bool index_output = false;

-
	pkg_config_bool(PKG_CONFIG_REPO_AUTOUPDATE, &auto_update);
+
	auto_update = pkg_object_bool(pkg_config_get("REPO_AUTOUPDATE"));

	while ((ch = getopt(argc, argv, "agiIxe:r:U")) != -1) {
		switch (ch) {
modified src/search.c
@@ -255,7 +255,7 @@ exec_search(int argc, char **argv)
	bool auto_update;
	bool old_quiet;

-
	pkg_config_bool(PKG_CONFIG_REPO_AUTOUPDATE, &auto_update);
+
	auto_update = pkg_object_bool(pkg_config_get("REPO_AUTOUPDATE"));

	while ((ch = getopt(argc, argv, "cDdefgiL:opqQ:r:RS:sUx")) != -1) {
		switch (ch) {
modified src/set.c
@@ -64,7 +64,7 @@ exec_set(int argc, char **argv)
	unsigned int sets = 0;
	int retcode;

-
	pkg_config_bool(PKG_CONFIG_ASSUME_ALWAYS_YES, &yes);
+
	yes = pkg_object_bool(pkg_config_get("ASSUME_ALWAYS_YES"));

	while ((ch = getopt(argc, argv, "A:agio:xy")) != -1) {
		switch (ch) {
modified src/ssh.c
@@ -64,7 +64,7 @@ exec_ssh(int argc, char **argv __unused)
		return (EX_USAGE);
	}

-
	pkg_config_string(PKG_CONFIG_SSH_RESTRICT_DIR, &restricted);
+
	restricted = pkg_object_string(pkg_config_get("SSH_RESTRICT_DIR"));
	if (restricted == NULL)
		restricted = "/";

modified src/updating.c
@@ -114,8 +114,8 @@ exec_updating(int argc, char **argv)
	}

	if (updatingfile == NULL) {
-
		const char *portsdir;
-
		if (pkg_config_string(PKG_CONFIG_PORTSDIR, &portsdir) != EPKG_OK) {
+
		const char *portsdir = pkg_object_string(pkg_config_get("PORTSDIR"));
+
		if (portsdir == NULL) {
			retcode = EX_CONFIG;
			goto cleanup;
		}
modified src/upgrade.c
@@ -59,9 +59,8 @@ exec_upgrade(int argc, char **argv)
	nbactions = nbdone = 0;
	pkg_flags f = PKG_FLAG_NONE | PKG_FLAG_PKG_VERSION_TEST;

-
	pkg_config_bool(PKG_CONFIG_ASSUME_ALWAYS_YES, &yes_arg);
-
	pkg_config_bool(PKG_CONFIG_REPO_AUTOUPDATE, &auto_update);
-

+
	yes_arg = pkg_object_bool(pkg_config_get("ASSUME_ALWAYS_YES"));
+
	auto_update = pkg_object_bool(pkg_config_get("REPO_AUTOUPDATE"));

	while ((ch = getopt(argc, argv, "fInqFr:Uy")) != -1) {
		switch (ch) {
modified src/utils.c
@@ -541,7 +541,7 @@ print_jobs_summary_pkg(struct pkg *new_pkg, struct pkg *old_pkg,
	flatsize = oldflatsize = pkgsize = 0;
	oldversion = NULL;

-
	pkg_config_string(PKG_CONFIG_CACHEDIR, &cachedir);
+
	cachedir = pkg_object_string(pkg_config_get("PKG_CACHEDIR"));
	pkg_get(new_pkg, PKG_FLATSIZE, &flatsize, PKG_PKGSIZE, &pkgsize, PKG_REASON, &why);
	if (old_pkg != NULL)
		pkg_get(old_pkg, PKG_VERSION, &oldversion, PKG_FLATSIZE, &oldflatsize);
modified src/version.c
@@ -174,7 +174,7 @@ exec_version(int argc, char **argv)
	char portsdirmakefile[MAXPATHLEN];
	int retcode = EXIT_SUCCESS;

-
	pkg_config_bool(PKG_CONFIG_REPO_AUTOUPDATE, &auto_update);
+
	auto_update = pkg_object_bool(pkg_config_get("REPO_AUTOUPDATE"));

	while ((ch = getopt(argc, argv, "hIPRUoqvl:L:ix:g:e:O:r:tT")) != -1) {
		switch (ch) {
@@ -302,7 +302,8 @@ exec_version(int argc, char **argv)
		return (retval);
		
	} else {
-
		if (pkg_config_string(PKG_CONFIG_PORTSDIR, &portsdir) != EPKG_OK)
+
		portsdir = pkg_object_string(pkg_config_get("PORTSDIR"));
+
		if (portsdir == NULL)
			err(1, "Cannot get portsdir config entry!");

		snprintf(portsdirmakefile, sizeof(portsdirmakefile),