Radish alpha
H
rad:z3QDZAW2FAfuLvihrhiyDC9fAD8G9
HardenedBSD Package Manager
Radicle
Git
Introduce new pkg_config API.
jlaffaye committed 14 years ago
commit 3871973e98698dcb74b68cdc63c01b1849c8ca3b
parent fc63b44
17 files changed +316 -153
modified libpkg/pkg.h
@@ -27,6 +27,8 @@ struct pkg_jobs;
struct pkg_repos;
struct pkg_repos_entry;

+
struct pkg_config_kv;
+

typedef enum {
	/**
	 * The license logic is OR (dual in the ports)
@@ -169,6 +171,17 @@ typedef enum _pkg_jobs_t {
	PKG_JOBS_UPGRADE
} pkg_jobs_t;

+
typedef enum _pkg_config_key {
+
	PKG_CONFIG_REPO = 0,
+
	PKG_CONFIG_DBDIR = 1,
+
	PKG_CONFIG_CACHEDIR = 2,
+
	PKG_CONFIG_PORTSDIR = 3,
+
	PKG_CONFIG_REPOKEY = 4,
+
	PKG_CONFIG_MULTIREPOS = 5,
+
	PKG_CONFIG_HANDLE_RC_SCRIPTS = 6,
+
	PKG_CONFIG_ASSUME_ALWAYS_YES = 7,
+
} pkg_config_key;
+

/**
 * Error type used everywhere by libpkg.
 */
@@ -744,7 +757,9 @@ int pkg_repo_verify(const char *path, unsigned char *sig, unsigned int sig_len);
/**
 * Get the value of a configuration key
 */
-
const char * pkg_config(const char *key);
+
int pkg_config_string(pkg_config_key key, const char **value);
+
int pkg_config_bool(pkg_config_key key, bool *value);
+
int pkg_config_list(pkg_config_key key, struct pkg_config_kv **kv);

/**
 * @todo Document
modified libpkg/pkg_config.c
@@ -1,50 +1,101 @@
#include <sys/types.h>
+
#include <sys/queue.h>

-
#include <assert.h>
#include <err.h>
#include <stdlib.h>
#include <string.h>
+

#include <yaml.h>

#include "pkg.h"
#include "pkg_event.h"

-
static struct _config {
+
#define STRING 0
+
#define BOOL 1
+
#define LIST 2
+

+
struct pkg_config_kv {
+
	char *key;
+
	char *value;
+
	SLIST_ENTRY(pkg_config_kv) next;
+
};
+

+
struct config_entry {
+
	uint8_t type;
	const char *key;
	const char *def;
-
	const char *val;
-
} c[] = {
-
	{ "PACKAGESITE", NULL, NULL},
-
	{ "PKG_DBDIR", "/var/db/pkg", NULL},
-
	{ "PKG_CACHEDIR", "/var/cache/pkg", NULL},
-
	{ "PORTSDIR", "/usr/ports", NULL },
-
	{ "PUBKEY", "/etc/ssl/pkg.pub", NULL },
-
	{ "PKG_MULTIREPOS", NULL, NULL },
-
	{ "HANDLE_RC_SCRIPTS", NULL, NULL },
-
	{ "ASSUME_ALWAYS_YES", NULL, NULL }, 
-
	{ NULL, NULL, NULL}
+
	union {
+
		char *val;
+
		SLIST_HEAD(, pkg_config_kv) list;
+
	};
};

-
struct _pkg_config {
-
	yaml_parser_t parser;
-
	yaml_document_t doc;
-
	struct _config *c;
+
static struct config_entry c[] = {
+
	[PKG_CONFIG_REPO] = {
+
		STRING,
+
		"PACKAGESITE",
+
		NULL,
+
		{ NULL }
+
	},
+
	[PKG_CONFIG_DBDIR] = {
+
		STRING,
+
		"PKG_DBDIR",
+
		"/var/db/pkg",
+
		{ NULL }
+
	},
+
	[PKG_CONFIG_CACHEDIR] = {
+
		STRING,
+
		"PKG_CACHEDIR",
+
		"/var/cache/pkg",
+
		{ NULL }
+
	},
+
	[PKG_CONFIG_PORTSDIR] = {
+
		STRING,
+
		"PORTSDIR",
+
		"/usr/ports",
+
		{ NULL }
+
	},
+
	[PKG_CONFIG_REPOKEY] = {
+
		STRING,
+
		"PUBKEY",
+
		"/etc/ssl/pkg.pub",
+
		{ NULL }
+
	},
+
	[PKG_CONFIG_MULTIREPOS] = {
+
		BOOL,
+
		"PKG_MULTIREPOS",
+
		NULL,
+
		{ NULL }
+
	},
+
	[PKG_CONFIG_HANDLE_RC_SCRIPTS] = {
+
		BOOL,
+
		"HANDLE_RC_SCRIPTS",
+
		NULL,
+
		{ NULL }
+
	},
+
	[PKG_CONFIG_ASSUME_ALWAYS_YES] = {
+
		BOOL,
+
		"ASSUME_ALWAYS_YES",
+
		NULL,
+
		{ NULL }
+
	}, 
};

-
static struct _pkg_config *conf = NULL;
+
static bool parsed = false;
+
static size_t c_size = sizeof(c) / sizeof(struct config_entry);

static void
-
parse_configuration(yaml_node_t *node)
+
parse_configuration(yaml_document_t *doc, yaml_node_t *node)
{
-
	int i;
+
	size_t i;
	yaml_node_pair_t *pair;
	yaml_node_t *key;
	yaml_node_t *val;

	pair = node->data.mapping.pairs.start;
	while (pair < node->data.mapping.pairs.top) {
-
		key = yaml_document_get_node(&conf->doc, pair->key);
-
		val = yaml_document_get_node(&conf->doc, pair->value);
+
		key = yaml_document_get_node(doc, pair->key);
+
		val = yaml_document_get_node(doc, pair->value);

		if (key->data.scalar.length <= 0) {
			/* ignoring silently */
@@ -57,14 +108,14 @@ parse_configuration(yaml_node_t *node)
			++pair;
			continue;
		}
-
		for (i = 0; conf->c[i].key != NULL; i++) {
-
			if (!strcasecmp(key->data.scalar.value, conf->c[i].key)) {
-
				if (conf->c[i].val != NULL) {
+
		for (i = 0; i < c_size; i++) {
+
			if (!strcasecmp(key->data.scalar.value, c[i].key)) {
+
				if (c[i].val != NULL) {
					/* skip env var already set */
					++pair;
					continue;
				}
-
				conf->c[i].val = val->data.scalar.value;
+
				c[i].val = strdup(val->data.scalar.value);
				break;
			}
		}
@@ -73,77 +124,150 @@ parse_configuration(yaml_node_t *node)
	}
}

-
const char *
-
pkg_config(const char *key)
+
int
+
pkg_config_string(pkg_config_key key, const char **val)
{
-
	int i;
+
	*val = NULL;
+

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

-
	assert(conf != NULL);
+
	if (c[key].type != STRING) {
+
		pkg_emit_error("this config entry is not a string");
+
		return (EPKG_FATAL);
+
	}

-
	for (i = 0; conf->c[i].key != NULL; i++) {
-
		if (strcmp(conf->c[i].key, key) == 0) {
-
			if (conf->c[i].val != NULL)
-
				return (conf->c[i].val);
-
			else
-
				return (conf->c[i].def);
-
		}
+
	*val = c[key].val;
+

+
	if (*val == NULL)
+
		*val = c[key].def;
+

+
	return (EPKG_OK);
+
}
+

+
int
+
pkg_config_bool(pkg_config_key key, bool *val)
+
{
+
	const char *str;
+

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

+
	if (c[key].type != BOOL) {
+
		pkg_emit_error("this config entry is not a bool");
+
		return (EPKG_FATAL);
+
	}
+

+
	str = c[key].val;
+
	if (str != NULL && strcasecmp(str, "yes"))
+
		*val = true;
+
	else
+
		*val = false;
+

+
	return (EPKG_OK);
+
}
+

+
int
+
pkg_config_list(pkg_config_key key, struct pkg_config_kv **kv)
+
{
+
	if (parsed != true) {
+
		pkg_emit_error("pkg_init() must be called before pkg_config_list()");
+
		return (EPKG_FATAL);
+
	}
+

+
	if (c[key].type != LIST) {
+
		pkg_emit_error("this config entry is not a list");
+
		return (EPKG_FATAL);
	}

-
	return (NULL);
+
	if (kv == NULL)
+
	{
+
		*kv = SLIST_FIRST(&(c[key].list));
+
	} else {
+
		*kv = SLIST_NEXT(*kv, next);
+
	}
+

+
	if (*kv == NULL)
+
		return (EPKG_END);
+
	else
+
		return (EPKG_OK);
}

int
pkg_init(const char *path)
{
-
	FILE *conffile;
+
	FILE *fp;
+
	yaml_parser_t parser;
+
	yaml_document_t doc;
	yaml_node_t *node;
	int i;

-
	assert(conf == NULL);
-

-
	conf = malloc(sizeof(struct _pkg_config));
-
	conf->c = c;
+
	if (parsed != false) {
+
		pkg_emit_error("pkg_init() must only be called once");
+
		return (EPKG_FATAL);
+
	}

	/* first fill with environment variables */

-
	for (i = 0; conf->c[i].key != NULL; i++)
-
		conf->c[i].val = getenv(conf->c[i].key);
+
	for (i = 0; c[i].key != NULL; i++)
+
		c[i].val = getenv(c[i].key);

	if (path == NULL)
		path = "/etc/pkg.conf";

-
	conffile = fopen(path, "r");
-

-
	if (conffile == NULL)
-
		return (EPKG_OK);
+
	if ((fp = fopen(path, "r")) == NULL) {
+
		pkg_emit_errno("fopen", path);
+
		return (EPKG_FATAL);
+
	}

-
	yaml_parser_initialize(&conf->parser);
-
	yaml_parser_set_input_file(&conf->parser, conffile);
-
	yaml_parser_load(&conf->parser, &conf->doc);
+
	yaml_parser_initialize(&parser);
+
	yaml_parser_set_input_file(&parser, fp);
+
	yaml_parser_load(&parser, &doc);

-
	node = yaml_document_get_root_node(&conf->doc);
+
	node = yaml_document_get_root_node(&doc);
	if (node != NULL) {
		if (node->type != YAML_MAPPING_NODE) {
			pkg_emit_error("Invalid configuration format, ignoring the configuration file");
		} else {
-
			parse_configuration(node);
+
			parse_configuration(&doc, node);
		}
	} else {
		pkg_emit_error("Invalid configuration format, ignoring the configuration file");
	}

+
	yaml_document_delete(&doc);
+
	yaml_parser_delete(&parser);
+

+
	parsed = true;
	return (EPKG_OK);
}

int
pkg_shutdown(void)
{
-
	assert(conf != NULL);
-

-
	yaml_document_delete(&conf->doc);
-
	yaml_parser_delete(&conf->parser);
+
	size_t i;

-
	free(conf);
+
	if (parsed == true) {
+
		for (i = 0; i < c_size; i++) {
+
			switch (c[i].type) {
+
			case STRING:
+
			case BOOL:
+
				free(c[i].val);
+
				break;
+
			case LIST:
+
				break;
+
			default:
+
				err(1, "unknown config entry type");
+
			}
+
		}
+
	} else {
+
		pkg_emit_error("pkg_shutdown() must be called after pkg_init()");
+
		return (EPKG_FATAL);
+
	}

	return (EPKG_OK);
}
modified libpkg/pkg_delete.c
@@ -17,7 +17,7 @@ pkg_delete(struct pkg *pkg, struct pkgdb *db, int flags)
{
	struct pkg_dep *rdep = NULL;
	int ret;
-
	const char *handle_rc = NULL;
+
	bool handle_rc = false;

	assert(pkg != NULL);
	assert(db != NULL);
@@ -58,8 +58,8 @@ pkg_delete(struct pkg *pkg, struct pkgdb *db, int flags)
	 * stop the different related services if the users do want that
	 * and that the service is running
	 */
-
	handle_rc = pkg_config("HANDLE_RC_SCRIPTS");
-
	if (handle_rc && (strcasecmp(handle_rc, "yes") == 0))
+
	pkg_config_bool(PKG_CONFIG_HANDLE_RC_SCRIPTS, &handle_rc);
+
	if (handle_rc)
		pkg_stop_rc_scripts(pkg);

	if (flags & PKG_DELETE_UPGRADE) {
modified libpkg/pkg_jobs.c
@@ -141,7 +141,8 @@ pkg_jobs_install(struct pkg_jobs *j)
	while (pkg_jobs(j, &p) == EPKG_OK)
		dlsize += pkg_new_pkgsize(p);

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

	while (statfs(cachedir, &fs) == -1) {
		if (errno == ENOENT) {
@@ -156,7 +157,7 @@ pkg_jobs_install(struct pkg_jobs *j)
	if (dlsize > ((int64_t)fs.f_bsize * (int64_t)fs.f_bfree)) {
		humanize_number(dlsz, sizeof(dlsz), dlsize, "B", HN_AUTOSCALE, 0);
		humanize_number(fsz, sizeof(fsz), (int64_t)fs.f_bsize * (int64_t)fs.f_bfree, "B", HN_AUTOSCALE, 0);
-
		pkg_emit_error("Not enough space in %s, needed %s available %s", pkg_config("PKG_CACHEDIR"), dlsz, fsz);
+
		pkg_emit_error("Not enough space in %s, needed %s available %s", cachedir, dlsz, fsz);
		return (EPKG_FATAL);
	}
		
modified libpkg/pkg_repo.c
@@ -73,12 +73,16 @@ pkg_repo_fetch(struct pkg *pkg)
	char cksum[SHA256_DIGEST_LENGTH * 2 +1];
	char *path = NULL;
	const char *packagesite = NULL;
+
	const char *cachedir = NULL;
+
	bool multirepos_enabled = false;
	int retcode = EPKG_OK;
-
	const char *multirepos_enabled = NULL;

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

-
	snprintf(dest, sizeof(dest), "%s/%s", pkg_config("PKG_CACHEDIR"),
+
	if (pkg_config_string(PKG_CONFIG_CACHEDIR, &cachedir) != EPKG_OK)
+
		return (EPKG_FATAL);
+

+
	snprintf(dest, sizeof(dest), "%s/%s", cachedir,
			 pkg_get(pkg, PKG_REPOPATH));

	/* If it is already in the local cachedir, dont bother to download it */
@@ -100,12 +104,12 @@ pkg_repo_fetch(struct pkg *pkg)
	 * For a single attached database the repository URL should be
	 * defined by PACKAGESITE.
	 */
-
	multirepos_enabled = pkg_config("PKG_MULTIREPOS");
+
	pkg_config_bool(PKG_CONFIG_MULTIREPOS, &multirepos_enabled);

-
	if (multirepos_enabled && (strcasecmp(multirepos_enabled, "yes") == 0)) {
+
	if (multirepos_enabled) {
		packagesite = pkg_get(pkg, PKG_REPOURL);
	} else {
-
		packagesite = pkg_config("PACKAGESITE");
+
		pkg_config_string(PKG_CONFIG_REPO, &packagesite);
	}

	if (packagesite == NULL) {
@@ -405,6 +409,7 @@ pkg_repo_verify(const char *path, unsigned char *sig, unsigned int sig_len)
{
	char sha256[SHA256_DIGEST_LENGTH *2 +1];
	char errbuf[1024];
+
	const char *repokey = NULL;
	RSA *rsa = NULL;

	sha256_file(path, sha256);
@@ -413,12 +418,15 @@ pkg_repo_verify(const char *path, unsigned char *sig, unsigned int sig_len)
	OpenSSL_add_all_algorithms();
	OpenSSL_add_all_ciphers();

-
	rsa = load_rsa_public_key(pkg_config("PUBKEY"));
+
	if (pkg_config_string(PKG_CONFIG_REPOKEY, &repokey) != EPKG_OK)
+
		return (EPKG_FATAL);
+

+
	rsa = load_rsa_public_key(repokey);
	if (rsa == NULL)
		return(EPKG_FATAL);

	if (RSA_verify(NID_sha1, sha256, sizeof(sha256), sig, sig_len, rsa) == 0) {
-
		pkg_emit_error("%s: %s", pkg_config("PUBKEY"),
+
		pkg_emit_error("%s: %s", repokey,
					   ERR_error_string(ERR_get_error(), errbuf));
		return (EPKG_FATAL);
	}
modified libpkg/pkgdb.c
@@ -494,7 +494,7 @@ pkgdb_open(struct pkgdb **db_p, pkgdb_t type)
	char remotepath[MAXPATHLEN + 1];
	const char *dbdir = NULL;
	const char *repo_name = NULL;
-
	const char *multirepos_enabled = NULL;
+
	bool multirepos_enabled = false;
	struct sbuf *sql = sbuf_new_auto();
	bool create = false;

@@ -504,7 +504,8 @@ pkgdb_open(struct pkgdb **db_p, pkgdb_t type)
	 */
	*db_p = NULL;

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

	if ((db = calloc(1, sizeof(struct pkgdb))) == NULL) {
		pkg_emit_errno("malloc", "pkgdb");
@@ -571,9 +572,9 @@ pkgdb_open(struct pkgdb **db_p, pkgdb_t type)
	}

	if (type == PKGDB_REMOTE) {
-
		multirepos_enabled = pkg_config("PKG_MULTIREPOS");
+
		pkg_config_bool(PKG_CONFIG_MULTIREPOS, &multirepos_enabled);

-
		if (multirepos_enabled && (strcasecmp(multirepos_enabled, "yes") == 0)) {
+
		if (multirepos_enabled) {
			fprintf(stderr, "\t/!\\		   WARNING WARNING WARNING		/!\\\n");
			fprintf(stderr, "\t/!\\	     WORKING ON MULTIPLE REPOSITORIES		/!\\\n");
			fprintf(stderr, "\t/!\\  THIS FEATURE IS STILL CONSIDERED EXPERIMENTAL	/!\\\n");
@@ -666,16 +667,16 @@ pkgdb_close(struct pkgdb *db)
	struct pkg_repos *repos = NULL;
	struct pkg_repos_entry *re = NULL;
	struct sbuf *sql = NULL;
-
	const char *multirepos_enabled = NULL;
+
	bool multirepos_enabled = false;

	if (db == NULL)
		return;

	if (db->sqlite != NULL) {
		if (db->type == PKGDB_REMOTE) {
-
			multirepos_enabled = pkg_config("PKG_MULTIREPOS");
+
			pkg_config_bool(PKG_CONFIG_MULTIREPOS, &multirepos_enabled);

-
			if (multirepos_enabled && (strcasecmp(multirepos_enabled, "yes") == 0)) {
+
			if (multirepos_enabled) {
				/*
				 * Working on multiple remote repositories.
				 * Detach the remote repositories from the main database
@@ -1376,7 +1377,7 @@ pkgdb_register_pkg(struct pkgdb *db, struct pkg *pkg, int complete)
	int retcode = EPKG_FATAL;
	int64_t package_id;

-
	const char *handle_rc = NULL;
+
	bool handle_rc = false;

	const char sql_begin[] = "BEGIN;";
	const char sql_mtree[] = "INSERT OR IGNORE INTO mtree(content) VALUES(?1);";
@@ -1812,8 +1813,8 @@ pkgdb_register_pkg(struct pkgdb *db, struct pkg *pkg, int complete)
	 * start the different related services if the users do want that
	 * and that the service is running
	 */
-
	handle_rc = pkg_config("HANDLE_RC_SCRIPTS");
-
	if (handle_rc && (strcasecmp(handle_rc, "yes") == 0))
+
	pkg_config_bool(PKG_CONFIG_HANDLE_RC_SCRIPTS, &handle_rc);
+
	if (handle_rc)
		pkg_start_rc_scripts(pkg);

	return (retcode);
@@ -2006,7 +2007,7 @@ pkgdb_query_installs(struct pkgdb *db, match_t match, int nbpkgs, char **pkgs, c
	struct sbuf *sql = sbuf_new_auto();
	const char *how = NULL;
	const char *reponame = NULL;
-
	const char *multirepos_enabled = NULL;
+
	bool multirepos_enabled = false;

	const char finalsql[] = "SELECT pkgid AS id, origin, name, version, "
		"comment, desc, message, arch, osversion, maintainer, "
@@ -2039,9 +2040,9 @@ pkgdb_query_installs(struct pkgdb *db, match_t match, int nbpkgs, char **pkgs, c
	}

	/* Working on multiple repositories */
-
	multirepos_enabled = pkg_config("PKG_MULTIREPOS");
+
	pkg_config_bool(PKG_CONFIG_MULTIREPOS, &multirepos_enabled);

-
	if (multirepos_enabled && (strcasecmp(multirepos_enabled, "yes") == 0)) {
+
	if (multirepos_enabled) {
		if (repo != NULL) {
			if (pkgdb_repos_new(db, &repos) != EPKG_OK) {
				pkg_emit_error("cannot get the attached databases");
@@ -2148,7 +2149,7 @@ pkgdb_query_upgrades(struct pkgdb *db, const char *repo)
	sqlite3_stmt *stmt = NULL;
	struct sbuf *sql = sbuf_new_auto();
	const char *reponame = NULL;
-
	const char *multirepos_enabled = NULL;
+
	bool multirepos_enabled = false;

	assert(db != NULL);

@@ -2190,9 +2191,9 @@ pkgdb_query_upgrades(struct pkgdb *db, const char *repo)
			"AND (PKGLT(l.version, r.version) OR (l.name != r.name))";

	/* Working on multiple repositories */
-
	multirepos_enabled = pkg_config("PKG_MULTIREPOS");
+
	pkg_config_bool(PKG_CONFIG_MULTIREPOS, &multirepos_enabled);

-
	if (multirepos_enabled && (strcasecmp(multirepos_enabled, "yes") == 0)) {
+
	if (multirepos_enabled) {
		if (repo != NULL) {
			if (pkgdb_repos_new(db, &repos) != EPKG_OK) {
				pkg_emit_error("cannot get the attached databases");
@@ -2257,7 +2258,7 @@ pkgdb_query_downgrades(struct pkgdb *db, const char *repo)
	struct sbuf *sql = sbuf_new_auto();
	const char *reponame = NULL;
	sqlite3_stmt *stmt = NULL;
-
	const char *multirepos_enabled = NULL;
+
	bool multirepos_enabled = false;

	assert(db != NULL);

@@ -2277,9 +2278,9 @@ pkgdb_query_downgrades(struct pkgdb *db, const char *repo)
		"AND PKGGT(l.version, r.version)";

	/* Working on multiple repositories */
-
	multirepos_enabled = pkg_config("PKG_MULTIREPOS");
+
	pkg_config_bool(PKG_CONFIG_MULTIREPOS, &multirepos_enabled);

-
	if (multirepos_enabled && (strcasecmp(multirepos_enabled, "yes") == 0)) {
+
	if (multirepos_enabled) {
		if (repo != NULL) {
			if (pkgdb_repos_new(db, &repos) != EPKG_OK) {
				pkg_emit_error("cannot get the attached databases");
@@ -2495,7 +2496,7 @@ pkgdb_rquery(struct pkgdb *db, const char *pattern, match_t match, unsigned int
	struct sbuf *sql = NULL;
	struct pkg_repos *repos = NULL;
	struct pkg_repos_entry *re = NULL;
-
	const char *multirepos_enabled = NULL;
+
	bool multirepos_enabled = false;
	const char *basesql = ""
				"SELECT id, origin, name, version, comment, "
					"prefix, desc, arch, osversion, maintainer, www, "
@@ -2518,9 +2519,9 @@ pkgdb_rquery(struct pkgdb *db, const char *pattern, match_t match, unsigned int
	sql = sbuf_new_auto();
	sbuf_cat(sql, basesql);

-
	multirepos_enabled = pkg_config("PKG_MULTIREPOS");
+
	pkg_config_bool(PKG_CONFIG_MULTIREPOS, &multirepos_enabled);
	    
-
	if (multirepos_enabled && (strcasecmp(multirepos_enabled, "yes") == 0)) {
+
	if (multirepos_enabled) {
		/*
		 * Working on multiple remote repositories
		 */
modified pkg/audit.c
@@ -123,8 +123,7 @@ exec_audit(int argc, char **argv)
	struct pkg *p = NULL;
#endif

-
	db_dir = pkg_config("PKG_DBDIR");
-
	if (db_dir == NULL) {
+
	if (pkg_config_string(PKG_CONFIG_DBDIR, &db_dir) != EPKG_OK) {
		warnx("PKG_DBIR is missing");
		return (1);
	}
modified pkg/autoremove.c
@@ -32,13 +32,13 @@ exec_autoremove(int argc, char **argv)
	int retcode = EPKG_OK;
	int64_t oldsize = 0, newsize = 0;
	char size[7];
-
	int ch, yes = 0;
-
	const char *assume_yes = NULL;
+
	int ch;
+
	bool yes = false;

	while ((ch = getopt(argc, argv, "y")) != -1) {
		switch (ch) {
			case 'y':
-
				yes = 1;
+
				yes = true;
				break;
			default:
				break;
@@ -102,14 +102,12 @@ exec_autoremove(int argc, char **argv)
	else
		printf("\nThe autoremove will require %s more space\n", size);

-
	assume_yes = pkg_config("ASSUME_ALWAYS_YES");
-
	if (assume_yes && (strcasecmp(assume_yes, "yes") == 0))
-
	    yes = 1;
-

-
	if (yes == 0)
+
	if (yes == false)
+
		pkg_config_bool(PKG_CONFIG_ASSUME_ALWAYS_YES, &yes);
+
	if (yes == false)
		yes = query_yesno("\nProceed with autoremove of packages [y/N]: ");

-
	if (yes == 1) {
+
	if (yes == true) {
		if ((retcode = pkg_jobs_apply(jobs, 1)) != EPKG_OK)
			goto cleanup;
	}
modified pkg/clean.c
@@ -25,7 +25,8 @@ exec_clean(int argc, char **argv)
	struct pkg *p = NULL;
	FTS *fts = NULL;
	FTSENT *ent = NULL;
-
	char *cachedir[2];
+
	const char *cachedir;
+
	char *paths[2];
	char *repopath;
	bool to_delete;
	int retcode = 1;
@@ -34,15 +35,20 @@ exec_clean(int argc, char **argv)
	(void)argc;
	(void)argv;

-
	cachedir[0] = __DECONST(char*, pkg_config("PKG_CACHEDIR"));
-
	cachedir[1] = NULL;
+
	if (pkg_config_string(PKG_CONFIG_CACHEDIR, &cachedir) != EPKG_OK) {
+
		warnx("Cant get cachedir config entry");
+
		return 1;
+
	}
+

+
	paths[0] = __DECONST(char*, cachedir);
+
	paths[1] = NULL;

	if (pkgdb_open(&db, PKGDB_REMOTE) != EPKG_OK) {
		goto cleanup;
	}

-
	if ((fts = fts_open(cachedir, FTS_PHYSICAL, NULL)) == NULL) {
-
		warn("fts_open(%s)", cachedir[0]);
+
	if ((fts = fts_open(paths, FTS_PHYSICAL, NULL)) == NULL) {
+
		warn("fts_open(%s)", cachedir);
		goto cleanup;
	}

@@ -50,7 +56,7 @@ exec_clean(int argc, char **argv)
		if (ent->fts_info != FTS_F)
			continue;

-
		repopath = ent->fts_path + strlen(cachedir[0]);
+
		repopath = ent->fts_path + strlen(cachedir);
		if (repopath[0] == '/')
			repopath++;

modified pkg/delete.c
@@ -31,12 +31,11 @@ exec_delete(int argc, char **argv)
	int ch;
	int flags = PKG_LOAD_BASIC;
	int force = 0;
-
	int yes = 0;
+
	bool yes = false;
	int retcode = 1;
	int recursive = 0;
	int64_t oldsize = 0, newsize = 0;
	char size[7];
-
	const char *assume_yes = NULL;

	while ((ch = getopt(argc, argv, "agxXfyr")) != -1) {
		switch (ch) {
@@ -56,7 +55,7 @@ exec_delete(int argc, char **argv)
				force = 1;
				break;
			case 'y':
-
				yes = 1;
+
				yes = true;
				break;
			case 'r':
				recursive = 1;
@@ -123,14 +122,12 @@ exec_delete(int argc, char **argv)
	else
		printf("\nThe deinstallation will require %s more space\n", size);

-
	assume_yes = pkg_config("ASSUME_ALWAYS_YES");
-
	if (assume_yes && (strcasecmp(assume_yes, "yes") == 0))
-
	    yes = 1;
-

-
	if (yes == 0)
+
	if (yes == false)
+
		pkg_config_bool(PKG_CONFIG_ASSUME_ALWAYS_YES, &yes);
+
	if (yes == false)
		yes = query_yesno("\nProceed with deinstalling packages [y/N]: ");

-
	if (yes == 1) {
+
	if (yes == true) {
		if ((retcode = pkg_jobs_apply(jobs, force)) != EPKG_OK)
			goto cleanup;
	} else
modified pkg/install.c
@@ -30,17 +30,17 @@ exec_install(int argc, char **argv)
	struct pkg_jobs *jobs = NULL;
	const char *reponame = NULL;
	int retcode = 1;
-
	int ch, yes = 0;
+
	int ch;
+
	bool yes = false;
	int64_t dlsize = 0;
	int64_t oldsize = 0, newsize = 0;
	char size[7];
	match_t match = MATCH_EXACT;
-
	const char *assume_yes = NULL;

	while ((ch = getopt(argc, argv, "ygxXr:")) != -1) {
		switch (ch) {
			case 'y':
-
				yes = 1;
+
				yes = true;
				break;
			case 'g':
				match = MATCH_GLOB;
@@ -120,15 +120,13 @@ exec_install(int argc, char **argv)
	}
	humanize_number(size, sizeof(size), dlsize, "B", HN_AUTOSCALE, 0);
	printf("%s to be downloaded\n", size);
-
 
-
	assume_yes = pkg_config("ASSUME_ALWAYS_YES");
-
	if (assume_yes && (strcasecmp(assume_yes, "yes") == 0))
-
		yes = 1;

-
	if (yes == 0)
+
	if (yes == false) 
+
		pkg_config_bool(PKG_CONFIG_ASSUME_ALWAYS_YES, &yes);
+
	if (yes == false)
		yes = query_yesno("\nProceed with installing packages [y/N]: ");

-
	if (yes == 1)
+
	if (yes == true)
		if (pkg_jobs_apply(jobs, 0) != EPKG_OK)
			goto cleanup;

modified pkg/update.c
@@ -36,7 +36,11 @@ update_from_remote_repo(const char *name, const char *url)
	int siglen = 0;

	tmp   = mktemp(strdup("/tmp/repo.txz.XXXXXX"));
-
	dbdir = pkg_config("PKG_DBDIR");
+

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

	if (pkg_fetch_file(url, tmp) != EPKG_OK) {
		unlink(tmp);
@@ -99,6 +103,7 @@ exec_update(int argc, char **argv)
	int retcode = EPKG_OK;
	struct pkg_repos *repos = NULL;
	struct pkg_repos_entry *re = NULL;
+
	bool multi_repos = false;

	(void)argv;
	if (argc != 1) {
@@ -115,13 +120,15 @@ exec_update(int argc, char **argv)
	 * Fetch remote databases.
	 */

+
	pkg_config_bool(PKG_CONFIG_MULTIREPOS, &multi_repos);
+

	/* single repository */
-
	if (pkg_config("PKG_MULTIREPOS") == NULL) {
+
	if (multi_repos) {
		/*
		 * Single remote database
		 */

-
		if ((packagesite = pkg_config("PACKAGESITE")) == NULL) {
+
		if (pkg_config_string(PKG_CONFIG_REPO, &packagesite) != EPKG_OK) {
			warnx("PACKAGESITE is not defined.");
			return (1);
		}
modified pkg/updating.c
@@ -81,8 +81,14 @@ exec_updating(int argc, char **argv)
	/* TODO missing per port */
	}

-
	if (updatingfile == NULL)
-
		asprintf(&updatingfile, "%s/UPDATING", pkg_config("PORTSDIR"));
+
	if (updatingfile == NULL) {
+
		const char *portsdir;
+
		if (pkg_config_string(PKG_CONFIG_PORTSDIR, &portsdir) != EPKG_OK) {
+
			warnx("Cant get portsdir config entry");
+
			return (1);
+
		}
+
		asprintf(&updatingfile, "%s/UPDATING", portsdir);
+
	}

	fd = fopen(updatingfile, "r");
	if (fd == NULL)
modified pkg/upgrade.c
@@ -34,8 +34,8 @@ exec_upgrade(int argc, char **argv)
	int64_t oldsize = 0, newsize = 0;
	int64_t dlsize = 0;
	char size[7];
-
	int ch, yes = 0;
-
	const char *assume_yes = NULL;
+
	int ch;
+
	bool yes = false;

	if (geteuid() != 0) {
		warnx("upgrading can only be done as root");
@@ -45,7 +45,7 @@ exec_upgrade(int argc, char **argv)
	while ((ch = getopt(argc, argv, "yr:")) != -1) {
		switch (ch) {
			case 'y':
-
				yes = 1;
+
				yes = true;
				break;
			case 'r':
				reponame = optarg;
@@ -110,14 +110,12 @@ exec_upgrade(int argc, char **argv)
	humanize_number(size, sizeof(size), dlsize, "B", HN_AUTOSCALE, 0);
	printf("%s to be downloaded\n", size);

-
	assume_yes = pkg_config("ASSUME_ALWAYS_YES");
-
	if (assume_yes && (strcasecmp(assume_yes, "yes") == 0))
-
	    yes = 1;
-

-
	if (yes == 0)
+
	if (yes == false)
+
		pkg_config_bool(PKG_CONFIG_ASSUME_ALWAYS_YES, &yes);
+
	if (yes == false)
		yes = query_yesno("\nProceed with upgrading packages [y/N]: ");

-
	if (yes == 1)
+
	if (yes == true)
		if (pkg_jobs_apply(jobs, 0) != EPKG_OK)
			goto cleanup;

modified pkg/utils.c
@@ -9,18 +9,19 @@

#include "utils.h"

-
int
+
bool
query_yesno(const char *msg)
{
-
        int c, r = 0;
+
        int c;
+
	bool r = false;

        printf("%s", msg);

        c = getchar();
        if (c == 'y' || c == 'Y')
-
                r = 1;
+
                r = true;
        else if (c == '\n' || c == EOF)
-
                return 0;
+
                return false;

        while((c = getchar()) != '\n' && c != EOF)
                continue;
@@ -36,7 +37,7 @@ print_info(struct pkg * const pkg, unsigned int opt)
        struct pkg_category *cat = NULL;
        struct pkg_license *lic = NULL;
        struct pkg_option *option = NULL;
-
	const char *multirepos_enabled = NULL;
+
	bool multirepos_enabled = false;
        char size[7];

        if (opt & INFO_FULL) {
@@ -46,9 +47,9 @@ print_info(struct pkg * const pkg, unsigned int opt)
                printf("%-15s: %s\n", "Prefix", pkg_get(pkg, PKG_PREFIX));

		if (pkg_type(pkg) == PKG_REMOTE) {
-
			multirepos_enabled = pkg_config("PKG_MULTIREPOS");
+
			pkg_config_bool(PKG_CONFIG_MULTIREPOS, &multirepos_enabled);

-
			if (multirepos_enabled && (strcasecmp(multirepos_enabled, "yes") == 0)) {
+
			if (multirepos_enabled) {
				printf("%-15s: %s [%s]\n", "Repository",
						pkg_get(pkg, PKG_REPONAME),
						pkg_get(pkg, PKG_REPOURL));
modified pkg/utils.h
@@ -12,7 +12,7 @@
#define INFO_PREFIX (1<<8)
#define INFO_FULL (1<<9)

-
int query_yesno(const char *msg);
+
bool query_yesno(const char *msg);
int print_info(struct pkg * const pkg, unsigned int opt);

#endif
modified pkg/version.c
@@ -139,6 +139,7 @@ exec_version(int argc, char **argv)
	char limchar = '-';
	struct sbuf *cmd;
	struct sbuf *res;
+
	const char *portsdir;

	SLIST_INIT(&indexhead);

@@ -187,6 +188,9 @@ exec_version(int argc, char **argv)
	argc -= optind;
	argv += optind;

+
	if (pkg_config_string(PKG_CONFIG_PORTSDIR, &portsdir) != EPKG_OK)
+
		err(1, "Can not get portsdir config entry");
+

	if (opt & VERSION_STATUS) {
			if (limchar != '<' &&
					limchar != '>' &&
@@ -218,7 +222,7 @@ exec_version(int argc, char **argv)
	} else if (opt & VERSION_INDEX) {
		uname(&u);
		rel_major_ver = (int) strtol(u.release, NULL, 10);
-
		snprintf(indexpath, sizeof(indexpath), "%s/INDEX-%d", pkg_config("PORTSDIR"), rel_major_ver);
+
		snprintf(indexpath, sizeof(indexpath), "%s/INDEX-%d", portsdir, rel_major_ver);
		indexfile = fopen(indexpath, "r");
		if (!indexfile)
			err(EX_SOFTWARE, "Unable to open %s", indexpath);
@@ -274,7 +278,7 @@ exec_version(int argc, char **argv)

		while (pkgdb_it_next(it, &pkg, PKG_LOAD_BASIC) == EPKG_OK) {
			cmd = sbuf_new_auto();
-
			sbuf_printf(cmd, "make -C %s/%s -VPKGVERSION", pkg_config("PORTSDIR"), pkg_get(pkg, PKG_ORIGIN));
+
			sbuf_printf(cmd, "make -C %s/%s -VPKGVERSION", portsdir, pkg_get(pkg, PKG_ORIGIN));
			sbuf_finish(cmd);
			if ((res = exec_buf(sbuf_data(cmd))) != NULL) {
				buf = sbuf_data(res);