Radish alpha
H
rad:z3QDZAW2FAfuLvihrhiyDC9fAD8G9
HardenedBSD Package Manager
Radicle
Git
Introduce new events API.
jlaffaye committed 14 years ago
commit f8a04e82de5a06cad154b43a155e1d0faffcecac
parent 0632f13
20 files changed +203 -440
modified libpkg/Makefile
@@ -15,7 +15,6 @@ SRCS= pkg.c \
		pkg_elf.c \
		pkg_event.c \
		pkg_error.c \
-
		pkg_handle.c \
		pkg_jobs.c \
		pkg_manifest.c \
		pkg_ports.c \
modified libpkg/fetch.c
@@ -11,6 +11,7 @@
#include <fetch.h>

#include "pkg.h"
+
#include "pkg_event.h"
#include "pkg_error.h"

int
@@ -29,8 +30,7 @@ pkg_fetch_file(const char *url, const char *dest, void *data, fetch_cb cb)
	int retcode = EPKG_OK;

	if ((fd = open(dest, O_WRONLY|O_CREAT|O_TRUNC, 0644)) == -1) {
-
		pkg_emit_event(PKG_EVENT_IO_ERROR, /*argc*/3, "open", dest,
-
		    strerror(errno));
+
		EMIT_ERRNO("open", dest);
		retcode = EPKG_FATAL;
		goto cleanup;
	}
@@ -40,8 +40,7 @@ pkg_fetch_file(const char *url, const char *dest, void *data, fetch_cb cb)
		if (remote == NULL) {
			--retry;
			if (retry == 0) {
-
				pkg_emit_event(PKG_EVENT_FETCH_ERROR,
-
				    /*argc*/1, fetchLastErrString);
+
				EMIT_PKG_ERROR("%s: %s", url, fetchLastErrString);
				retcode = EPKG_FATAL;
				goto cleanup;
			}
@@ -55,8 +54,7 @@ pkg_fetch_file(const char *url, const char *dest, void *data, fetch_cb cb)
			break;

		if (write(fd, buf, r) != r) {
-
			pkg_emit_event(PKG_EVENT_IO_ERROR, /*argc*/3, "write",
-
			    dest, strerror(errno));
+
			EMIT_ERRNO("write", dest);
			retcode = EPKG_FATAL;
			goto cleanup;
		}
@@ -71,8 +69,7 @@ pkg_fetch_file(const char *url, const char *dest, void *data, fetch_cb cb)
	}

	if (ferror(remote)) {
-
		pkg_emit_event(PKG_EVENT_FETCH_ERROR, /*argc*/1,
-
		    fetchLastErrString);
+
		EMIT_PKG_ERROR("%s: %s", url, fetchLastErrString);
		retcode = EPKG_FATAL;
		goto cleanup;
	}
@@ -91,62 +88,3 @@ pkg_fetch_file(const char *url, const char *dest, void *data, fetch_cb cb)

	return (retcode);
}
-

-
int
-
pkg_fetch_buffer(const char *url, char **buffer, void *data, fetch_cb cb)
-
{
-
	FILE *remote = NULL;
-
	struct url_stat st;
-
	off_t done = 0;
-
	off_t r;
-
	int retry = 3;
-
	time_t begin_dl;
-
	time_t now;
-
	time_t last = 0;
-
	int retcode = EPKG_OK;
-

-
	while (remote == NULL) {
-
		remote = fetchXGetURL(url, &st, "");
-
		if (remote == NULL) {
-
			--retry;
-
			if (retry == 0) {
-
				pkg_emit_event(PKG_EVENT_FETCH_ERROR,
-
				    /*argc*/1, fetchLastErrString);
-
				retcode = EPKG_FATAL;
-
				goto cleanup;
-
			}
-
			sleep(1);
-
		}
-
	}
-

-
	*buffer = malloc(st.size + 1);
-

-
	begin_dl = time(NULL);
-
	while (done < st.size) {
-
		if ((r = fread(*buffer + done, 1, 10240, remote)) < 1)
-
			break;
-

-
		done += r;
-

-
		now = time(NULL);
-
		/* Only call the callback every second */
-

-
		if (cb != NULL && (now > last || done == st.size)) {
-
			cb(data, url, st.size, done, (now - begin_dl));
-
			last = now;
-
		}
-
	}
-

-
	if (ferror(remote)) {
-
		pkg_emit_event(PKG_EVENT_FETCH_ERROR, /*argc*/1,
-
		    fetchLastErrString);
-
		goto cleanup;
-
	}
-

-
	cleanup:
-

-
	if (remote != NULL)
-
		fclose(remote);
-

-
	return (retcode);
-
}
modified libpkg/packing.c
@@ -14,8 +14,9 @@
#include <string.h>
#include <stdlib.h>

-
#include <pkg.h>
-
#include <pkg_private.h>
+
#include "pkg.h"
+
#include "pkg_event.h"
+
#include "pkg_private.h"

static const char *packing_set_format(struct archive *a, pkg_formats format);

@@ -32,8 +33,7 @@ packing_init(struct packing **pack, const char *path, pkg_formats format)
	const char *ext;

	if ((*pack = calloc(1, sizeof(struct packing))) == NULL) {
-
		pkg_emit_event(PKG_EVENT_MALLOC_ERROR, /*argc*/1,
-
		    strerror(errno));
+
		EMIT_ERRNO("malloc", "");
	}

	(*pack)->aread = archive_read_disk_new();
@@ -94,8 +94,7 @@ packing_append_file(struct packing *pack, const char *filepath, const char *newp

	retcode = archive_read_disk_entry_from_file(pack->aread, pack->entry, -1, NULL);
	if (retcode != ARCHIVE_OK) {
-
		pkg_emit_event(PKG_EVENT_ARCHIVE_ERROR, /*argc*/2,
-
		    filepath, pack->aread);
+
		EMIT_PKG_ERROR("%s: %s", filepath, archive_error_string(pack->aread));
		retcode = EPKG_FATAL;
		goto cleanup;
	}
@@ -121,8 +120,7 @@ packing_append_file(struct packing *pack, const char *filepath, const char *newp

	if (archive_entry_size(pack->entry) > 0) {
		if ((fd = open(filepath, O_RDONLY)) < 0) {
-
			pkg_emit_event(PKG_EVENT_IO_ERROR, /*argc*/3,
-
			    "open", filepath, strerror(errno));
+
			EMIT_ERRNO("open", filepath);
			retcode = EPKG_FATAL;
			goto cleanup;
		}
@@ -208,22 +206,19 @@ packing_set_format(struct archive *a, pkg_formats format)
			if (archive_write_set_compression_xz(a) == ARCHIVE_OK) {
				return ("txz");
			} else {
-
				pkg_emit_event(PKG_EVENT_ARCHIVE_COMP_UNSUP,
-
				    /*argc*/2, "xz", "bzip2");
+
				EMIT_PKG_ERROR("%s", "xz is not supported, trying bzip2");
			}
		case TBZ:
			if (archive_write_set_compression_bzip2(a) == ARCHIVE_OK) {
				return ("tbz");
			} else {
-
				pkg_emit_event(PKG_EVENT_ARCHIVE_COMP_UNSUP,
-
				    /*argc*/2, "bzip2", "gzip");
+
				EMIT_PKG_ERROR("%s", "bzip2 is not supported, trying gzip");
			}
		case TGZ:
			if (archive_write_set_compression_gzip(a) == ARCHIVE_OK) {
				return ("tgz");
			} else {
-
				pkg_emit_event(PKG_EVENT_ARCHIVE_COMP_UNSUP,
-
				    /*argc*/2, "gzip", "plain tar");
+
				EMIT_PKG_ERROR("%s", "gzip is not supported, trying plain tar");
			}
		case TAR:
			archive_write_set_compression_none(a);
modified libpkg/pkg.c
@@ -7,6 +7,7 @@
#include <sysexits.h>

#include "pkg.h"
+
#include "pkg_event.h"
#include "pkg_error.h"
#include "pkg_private.h"
#include "pkg_util.h"
@@ -15,8 +16,7 @@ int
pkg_new(struct pkg **pkg, pkg_t type)
{
	if ((*pkg = calloc(1, sizeof(struct pkg))) == NULL) {
-
		pkg_emit_event(PKG_EVENT_MALLOC_ERROR, /*argc*/1,
-
		    strerror(errno));
+
		EMIT_ERRNO("malloc", "");
		return EPKG_FATAL;
	}

@@ -597,7 +597,7 @@ pkg_addscript_file(struct pkg *pkg, const char *path)
			strcmp(filename, "+UPGRADE") == 0) {
		type = PKG_SCRIPT_UPGRADE;
	} else {
-
		pkg_emit_event(PKG_EVENT_UNKNOWN_SCRIPT, /*argc*/1, filename);
+
		EMIT_PKG_ERROR("unknown script '%s'", filename);
		return EPKG_FATAL;
	}

@@ -793,8 +793,8 @@ pkg_open2(struct pkg **pkg_p, struct archive **a, struct archive_entry **ae, con
	archive_read_support_format_tar(*a);

	if (archive_read_open_filename(*a, path, 4096) != ARCHIVE_OK) {
-
		pkg_emit_event(PKG_EVENT_ARCHIVE_ERROR, /*argc*/2,
-
		    archive_entry_pathname(*ae), *a);
+
		EMIT_PKG_ERROR("archive_read_open_filename(%s): %s", path,
+
					   archive_error_string(*a));
		retcode = EPKG_FATAL;
		goto cleanup;
	}
@@ -841,8 +841,8 @@ pkg_open2(struct pkg **pkg_p, struct archive **a, struct archive_entry **ae, con
	}

	if (ret != ARCHIVE_OK && ret != ARCHIVE_EOF) {
-
		pkg_emit_event(PKG_EVENT_ARCHIVE_ERROR, /*argc*/2,
-
		    archive_entry_pathname(*ae), *a);
+
		EMIT_PKG_ERROR("archive_read_next_header(): %s",
+
					   archive_error_string(*a));
		retcode = EPKG_FATAL;
	}

modified libpkg/pkg.h
@@ -585,12 +585,6 @@ int pkg_version_cmp(const char * const , const char * const);
 */
int pkg_fetch_file(const char *url, const char *dest, void *data, fetch_cb cb);

-
/**
-
 * Fetch to a given buffer
-
 * @return An error code
-
 */
-
int pkg_fetch_buffer(const char *url, char **buf, void *data, fetch_cb cb);
-

/* glue to deal with ports */
int ports_parse_plist(struct pkg *, char *);

@@ -631,54 +625,51 @@ int pkg_script_run(struct pkg *, pkg_script_t type);
typedef enum {
	/* informational */
	PKG_EVENT_INSTALL_BEGIN = 0,
-

+
	PKG_EVENT_ERROR,
+
	PKG_EVENT_ERRNO,
	/* errors */
	PKG_EVENT_ARCHIVE_COMP_UNSUP = 65536,
-
	PKG_EVENT_ARCHIVE_ERROR,
	PKG_EVENT_ALREADY_INSTALLED,
-
	PKG_EVENT_CKSUM_ERROR,
-
	PKG_EVENT_CONFIG_KEY_NOTFOUND,
+
	PKG_EVENT_FAILED_CKSUM,
	PKG_EVENT_CREATE_DB_ERROR,
	PKG_EVENT_DELETE_DEP_EXISTS,
-
	PKG_EVENT_ERROR_INSTALLING_DEP,
-
	PKG_EVENT_FETCH_ERROR,
-
	PKG_EVENT_INVALID_DB_STATE,
-
	PKG_EVENT_IO_ERROR,
-
	PKG_EVENT_MALLOC_ERROR,
	PKG_EVENT_MISSING_DEP,
-
	PKG_EVENT_OPEN_DB_ERROR,
-
	PKG_EVENT_PARSE_ERROR,
-
	PKG_EVENT_REPO_KEY_UNAVAIL,
-
	PKG_EVENT_REPO_KEY_UNUSABLE,
-
	PKG_EVENT_SQLITE_CONSTRAINT,
-
	PKG_EVENT_SQLITE_ERROR,
-
	PKG_EVENT_UNKNOWN_SCRIPT,
} pkg_event_t;

-
/**
-
 * Package handle for global state information
-
 */
+
struct pkg_event {
+
	pkg_event_t type;
+
	uint16_t line;
+
	const char *file;
+
	union {
+
		struct {
+
			const char *func;
+
			const char *arg;
+
		} e_errno;
+
		struct {
+
			char *msg;
+
		} e_pkg_error;
+
		struct {
+
			struct pkg *pkg;
+
		} e_already_installed;
+
		struct {
+
			struct pkg *pkg;
+
		} e_begin_install;
+
		struct {
+
			struct pkg *pkg;
+
			struct pkg_dep *dep;
+
		} e_missing_dep;
+
		struct {
+
			struct pkg *pkg;
+
		} e_failed_cksum;
+
	};
+
};

/**
 * Event callback mechanism.  Events will be reported using this callback,
 * providing an event identifier and up to two event-specific pointers.
 */
-
typedef int(*pkg_event_cb)(pkg_event_t, const char *, int, void **);
-

-
struct pkg_handle {
-
	pkg_event_cb event_cb;
-
	int debug;
-
};
-

-
struct pkg_handle *pkg_get_handle(void);
-
pkg_event_cb pkg_handle_get_event_callback(struct pkg_handle *);
-
void pkg_handle_set_event_callback(struct pkg_handle *, pkg_event_cb);
-
void pkg_handle_set_debug(struct pkg_handle *, int);
-
int pkg_handle_get_debug(struct pkg_handle *);
-

-
void __pkg_emit_event(struct pkg_handle *, const char *, int, pkg_event_t, int, ...);
+
typedef int(*pkg_event_cb)(void *, struct pkg_event *);

-
#define	pkg_emit_event(ev, argc, argv...) \
-
	__pkg_emit_event(pkg_get_handle(), __FILE__, __LINE__, ev, argc, argv)
+
void pkg_event_register(pkg_event_cb cb, void *data);

#endif
modified libpkg/pkg_add.c
@@ -8,6 +8,7 @@
#include <errno.h>

#include "pkg.h"
+
#include "pkg_event.h"
#include "pkg_error.h"
#include "pkg_private.h"

@@ -41,8 +42,8 @@ do_extract(struct archive *a, struct archive_entry *ae)

	do {
		if (archive_read_extract(a, ae, EXTRACT_ARCHIVE_FLAGS) != ARCHIVE_OK) {
-
			pkg_emit_event(PKG_EVENT_ARCHIVE_ERROR, /*argc*/2,
-
			    archive_entry_pathname(ae), a);
+
			EMIT_PKG_ERROR("archive_read_extract(): %s",
+
						   archive_error_string(a));
			retcode = EPKG_FATAL;
			break;
		}
@@ -59,8 +60,8 @@ do_extract(struct archive *a, struct archive_entry *ae)
		    && lstat(path, &st) == ENOENT) {
			archive_entry_set_pathname(ae, path);
			if (archive_read_extract(a, ae, EXTRACT_ARCHIVE_FLAGS) != ARCHIVE_OK) {
-
				pkg_emit_event(PKG_EVENT_ARCHIVE_ERROR, /*argc*/2,
-
				    archive_entry_pathname(ae), a);
+
				EMIT_PKG_ERROR("archive_read_extract(): %s",
+
							   archive_error_string(a));
				retcode = EPKG_FATAL;
				break;
			}
@@ -68,8 +69,8 @@ do_extract(struct archive *a, struct archive_entry *ae)
	} while ((ret = archive_read_next_header(a, &ae)) == ARCHIVE_OK);

	if (ret != ARCHIVE_EOF) {
-
		pkg_emit_event(PKG_EVENT_ARCHIVE_ERROR, /*argc*/2,
-
		    archive_entry_pathname(ae), a);
+
		EMIT_PKG_ERROR("archive_read_next_header(): %s",
+
					   archive_error_string(a));
		retcode = EPKG_FATAL;
	}

@@ -121,7 +122,7 @@ pkg_add(struct pkgdb *db, const char *path, struct pkg **pkg_p)
	pkgdb_it_free(it);

	if (ret == EPKG_OK) {
-
		pkg_emit_event(PKG_EVENT_ALREADY_INSTALLED, /*argc*/1, p);
+
		EMIT_ALREADY_INSTALLED(pkg);
		retcode = EPKG_INSTALLED;
		goto cleanup;
	} else if (ret != EPKG_END) {
@@ -147,18 +148,12 @@ pkg_add(struct pkgdb *db, const char *path, struct pkg **pkg_p)

			if (access(dpath, F_OK) == 0) {
				if (pkg_add(db, dpath, NULL) != EPKG_OK) {
-
					/* XXX: maybe the pkg_error_string()
-
					 * should be handled in the event
-
					 * handler */
-
					pkg_emit_event(PKG_EVENT_ERROR_INSTALLING_DEP,
-
					    /*argc*/2, dpath, pkg_error_string());
					retcode = EPKG_FATAL;
					goto cleanup;
				}
			} else {
				retcode = EPKG_FATAL;
-
				pkg_emit_event(PKG_EVENT_MISSING_DEP, /*argc*/2,
-
				    pkg_dep_name(dep), pkg_dep_version(dep));
+
				EMIT_MISSING_DEP(pkg, dep);
				goto cleanup;
			}
		}
@@ -170,7 +165,7 @@ pkg_add(struct pkgdb *db, const char *path, struct pkg **pkg_p)
	if (retcode != EPKG_OK || pkgdb_has_flag(db, PKGDB_FLAG_IN_FLIGHT) == 0)
		goto cleanup_reg;

-
	pkg_emit_event(PKG_EVENT_INSTALL_BEGIN, /*argc*/1, pkg);
+
	EMIT_INSTALL_BEGIN(pkg);

	/*
	 * Execute pre-install scripts
modified libpkg/pkg_config.c
@@ -9,6 +9,7 @@
#include <unistd.h>

#include "pkg.h"
+
#include "pkg_event.h"
#include "pkg_error.h"

struct _config {
@@ -68,6 +69,5 @@ pkg_config(const char *key)
		}
	}

-
	pkg_emit_event(PKG_EVENT_CONFIG_KEY_NOTFOUND, /*argc*/1, key);
	return (NULL);
}
modified libpkg/pkg_create_repo.c
@@ -14,6 +14,7 @@
#include <openssl/ssl.h>

#include "pkg.h"
+
#include "pkg_event.h"
#include "pkg_error.h"
#include "pkg_private.h"
#include "pkg_util.h"
@@ -75,8 +76,7 @@ pkg_create_repo(char *path, void (progress)(struct pkg *pkg, void *data), void *
		"VALUES (?1, ?2, ?3, ?4);";

	if (!is_dir(path)) {
-
		pkg_emit_event(PKG_EVENT_CREATE_DB_ERROR, /*argc*/3,
-
		    path, "not a directory", NULL);
+
		EMIT_PKG_ERROR("%s is not a directory", path);
		return EPKG_FATAL;
	}

@@ -87,8 +87,7 @@ pkg_create_repo(char *path, void (progress)(struct pkg *pkg, void *data), void *

	if (stat(repodb, &st) != -1)
		if (unlink(repodb) != 0) {
-
			pkg_emit_event(PKG_EVENT_CREATE_DB_ERROR,
-
			    /*argc*/3, path, repodb, strerror(errno));
+
			EMIT_ERRNO("unlink", path);
			return EPKG_FATAL;
		}

@@ -96,14 +95,14 @@ pkg_create_repo(char *path, void (progress)(struct pkg *pkg, void *data), void *
		return (EPKG_FATAL);

	if (sqlite3_exec(sqlite, initsql, NULL, NULL, &errmsg) != SQLITE_OK) {
-
		pkg_emit_event(PKG_EVENT_SQLITE_ERROR, /*argc*/1, errmsg);
+
		EMIT_PKG_ERROR("sqlite: %s", errmsg);
		retcode = EPKG_FATAL;
		goto cleanup;
	}

	if (sqlite3_exec(sqlite, "BEGIN TRANSACTION;", NULL, NULL, &errmsg) !=
		SQLITE_OK) {
-
		pkg_emit_event(PKG_EVENT_SQLITE_ERROR, /*argc*/1, errmsg);
+
		EMIT_PKG_ERROR("sqlite: %s", errmsg);
		retcode = EPKG_FATAL;
		goto cleanup;
	}
@@ -119,8 +118,7 @@ pkg_create_repo(char *path, void (progress)(struct pkg *pkg, void *data), void *
	}

	if ((fts = fts_open(repopath, FTS_PHYSICAL, NULL)) == NULL) {
-
		pkg_emit_event(PKG_EVENT_OPEN_DB_ERROR, /*argc*/2,
-
		    repopath, strerror(errno));
+
		EMIT_ERRNO("fts_open", path);
		retcode = EPKG_FATAL;
		goto cleanup;
	}
@@ -148,13 +146,7 @@ pkg_create_repo(char *path, void (progress)(struct pkg *pkg, void *data), void *
			pkg_path++;

		if (pkg_open(&pkg, ent->fts_accpath) != EPKG_OK) {
-
			if (progress != NULL) {
-
				pkg_emit_event(PKG_EVENT_OPEN_DB_ERROR,
-
				    /*argc*/2, ent->fts_name,
-
				    pkg_error_string());
-
				retcode = EPKG_WARN;
-
				progress(NULL, data);
-
			}
+
			retcode = EPKG_WARN;
			continue;
		}

@@ -200,7 +192,7 @@ pkg_create_repo(char *path, void (progress)(struct pkg *pkg, void *data), void *
	}

	if (sqlite3_exec(sqlite, "COMMIT;", NULL, NULL, &errmsg) != SQLITE_OK) {
-
		pkg_emit_event(PKG_EVENT_SQLITE_ERROR, /*argc*/1, errmsg);
+
		EMIT_PKG_ERROR("sqlite: %s", errmsg);
		retcode = EPKG_FATAL;
	}

@@ -267,8 +259,7 @@ pkg_finish_repo(char *path, pem_password_cb *password_cb, char *rsa_key_path)
	packing_init(&pack, repo_archive, TXZ);
	if (rsa_key_path != NULL) {
		if (access(rsa_key_path, R_OK) == -1) {
-
			pkg_emit_event(PKG_EVENT_REPO_KEY_UNAVAIL, /*argc*/2,
-
			    rsa_key_path, strerror(errno));
+
			EMIT_ERRNO("access", rsa_key_path);
			return EPKG_FATAL;
		}

@@ -285,8 +276,8 @@ pkg_finish_repo(char *path, pem_password_cb *password_cb, char *rsa_key_path)
		sha256_file(repo_path, sha256);

		if (RSA_sign(NID_sha1, sha256, 65, sigret, &siglen, rsa) == 0) {
-
			pkg_emit_event(PKG_EVENT_REPO_KEY_UNUSABLE, /*argc*/2,
-
			    rsa_key_path, ERR_get_error()); /* XXX pass back RSA errors correctly */
+
			/* XXX pass back RSA errors correctly */
+
			EMIT_PKG_ERROR("%s: %lu", rsa_key_path, ERR_get_error());
			return EPKG_FATAL;
		}

modified libpkg/pkg_delete.c
@@ -7,6 +7,7 @@
#include <sys/stat.h>

#include "pkg.h"
+
#include "pkg_event.h"
#include "pkg_error.h"
#include "pkg_private.h"
#include "pkg_util.h"
@@ -50,8 +51,8 @@ pkg_delete(struct pkg *pkg, struct pkgdb *db, int force)
	if (rdep_msg != NULL) {
		if (!force) {
			sbuf_finish(rdep_msg);
-
			pkg_emit_event(PKG_EVENT_DELETE_DEP_EXISTS, /*argc*/1,
-
			    sbuf_get(rdep_msg));
+
			/*pkg_emit_event(PKG_EVENT_DELETE_DEP_EXISTS, 1,
+
			    sbuf_get(rdep_msg));*/
			ret = EPKG_REQUIRED;
			sbuf_free(rdep_msg);
			return ret;
modified libpkg/pkg_event.c
@@ -1,159 +1,22 @@
-
#include <assert.h>
-
#include <archive.h>
#include "pkg.h"
-
#include "pkg_error.h"
-
#include <sys/sbuf.h>
+
#include "pkg_event.h"

-
/* Guard-rail against incorrect number of arguments */
-
static void
-
pkg_event_argument_check(pkg_event_t ev, int argc)
-
{
-

-
	switch(ev) {
-
	case PKG_EVENT_ALREADY_INSTALLED:
-
	case PKG_EVENT_CKSUM_ERROR:
-
	case PKG_EVENT_CONFIG_KEY_NOTFOUND:
-
	case PKG_EVENT_DELETE_DEP_EXISTS:
-
	case PKG_EVENT_FETCH_ERROR:
-
	case PKG_EVENT_INSTALL_BEGIN:
-
	case PKG_EVENT_INVALID_DB_STATE:
-
	case PKG_EVENT_MALLOC_ERROR:
-
	case PKG_EVENT_UNKNOWN_SCRIPT:
-
	case PKG_EVENT_SQLITE_ERROR:
-
		assert(argc == 1);
-
		break;
-
	case PKG_EVENT_ARCHIVE_COMP_UNSUP:
-
	case PKG_EVENT_ARCHIVE_ERROR:
-
	case PKG_EVENT_ERROR_INSTALLING_DEP:
-
	case PKG_EVENT_MISSING_DEP:
-
	case PKG_EVENT_OPEN_DB_ERROR:
-
	case PKG_EVENT_PARSE_ERROR:
-
	case PKG_EVENT_REPO_KEY_UNAVAIL:
-
	case PKG_EVENT_REPO_KEY_UNUSABLE:
-
	case PKG_EVENT_SQLITE_CONSTRAINT:
-
		assert(argc == 2);
-
		break;
-
	case PKG_EVENT_CREATE_DB_ERROR:
-
	case PKG_EVENT_IO_ERROR:
-
		assert(argc == 3);
-
		break;
-
	default:
-
		break;
-
	}
-
}
+
static pkg_event_cb _cb = NULL;
+
static void *_data = NULL;

-
/**
-
 * This function's purpose is to perform global event handling.
-
 */
-
static void
-
libpkg_handle_event(struct pkg_handle *hdl, pkg_event_t ev, const char *filename, int line, void **argv)
+
void
+
pkg_event_register(pkg_event_cb cb, void *data)
{
-
	pkg_error_t ret = EPKG_FATAL; /* most of these are this code */
-
	struct sbuf *sb;
-

-
	sb = sbuf_new_auto();
-
	switch(ev) {
-
	case PKG_EVENT_ALREADY_INSTALLED:
-
		sbuf_printf(sb, "package '%s' already installed", pkg_get(argv[0], PKG_NAME));
-
		ret = EPKG_INSTALLED;
-
		break;
-
	case PKG_EVENT_ARCHIVE_COMP_UNSUP:
-
		ret = EPKG_OK; /* XXX needs an error message? */
-
		break;
-
	case PKG_EVENT_ARCHIVE_ERROR:
-
		sbuf_printf(sb, "archive error at %s: %s", (const char *)argv[0], archive_error_string(argv[1]));
-
		break;
-
	case PKG_EVENT_CKSUM_ERROR:
-
		sbuf_printf(sb, "package '%s' failed checksum", pkg_get(argv[0], PKG_NAME));
-
		break;
-
	case PKG_EVENT_CONFIG_KEY_NOTFOUND:
-
		sbuf_printf(sb, "unknown configuration key `%s'", (const char *)argv[0]);
-
		break;
-
	case PKG_EVENT_CREATE_DB_ERROR:
-
		if (argv[2] == NULL)
-
			sbuf_printf(sb, "%s: %s", (char *)argv[0], (char *)argv[1]);
-
		else
-
			sbuf_printf(sb, "%s(%s): %s", (char *)argv[0], (char *)argv[1], (char *)argv[2]);
-
		break;
-
	case PKG_EVENT_DELETE_DEP_EXISTS:
-
		sbuf_printf(sb, "%s", (char *)argv[0]);
-
		ret = EPKG_REQUIRED;
-
		break;
-
	case PKG_EVENT_ERROR_INSTALLING_DEP:
-
		sbuf_printf(sb, "error while installing dependency %s: %s", (char *)argv[0], (char *)argv[1]);
-
		break;
-
	case PKG_EVENT_FETCH_ERROR:
-
		sbuf_printf(sb, "%s", (char *)argv[0]);
-
		break;
-
	case PKG_EVENT_INVALID_DB_STATE:
-
		sbuf_printf(sb, "%s", (char *)argv[0]);
-
		break;
-
	case PKG_EVENT_IO_ERROR:
-
		sbuf_printf(sb, "I/O error: %s(%s): %s", /*call*/(char *)argv[0],
-
		    /*arg*/(char *)argv[1], /*strerror*/(char *)argv[2]);
-
		break;
-
	case PKG_EVENT_MALLOC_ERROR:
-
		sbuf_printf(sb, "allocation error: %s", (char *)argv[0]);
-
		break;
-
	case PKG_EVENT_MISSING_DEP:
-
		sbuf_printf(sb, "missing %s-%s dependency", (char *)argv[0], (char *)argv[1]);
-
		ret = EPKG_DEPENDENCY;
-
		break;
-
	case PKG_EVENT_OPEN_DB_ERROR:
-
		sbuf_printf(sb, "db open(%s) failed: %s", (char *)argv[0], (char *)argv[1]);
-
		break;
-
	case PKG_EVENT_PARSE_ERROR:
-
		sbuf_printf(sb, "parse error(%s): %s", (char *)argv[0], (char *)argv[1]);
-
		break;
-
	case PKG_EVENT_REPO_KEY_UNAVAIL:
-
		sbuf_printf(sb, "RSA key %s invalid: %s", (char *)argv[0], (char *)argv[1]);
-
		break;
-
	case PKG_EVENT_REPO_KEY_UNUSABLE:
-
		sbuf_printf(sb, "RSA key %s unusable: %s", (char *)argv[0], (char *)argv[1]);
-
		break;
-
	case PKG_EVENT_SQLITE_CONSTRAINT:
-
		sbuf_printf(sb, "constraint violation on %s: %s", (char *)argv[0], (char *)argv[1]);
-
		break;
-
	case PKG_EVENT_SQLITE_ERROR:
-
		sbuf_printf(sb, "sqlite error: %s", (char *)argv[0]);
-
		break;
-
	case PKG_EVENT_UNKNOWN_SCRIPT:
-
		sbuf_printf(sb, "unknown script '%s'", (char *)argv[0]);
-
		break;
-
	default:
-
		ret = EPKG_OK; /* unhandled error */
-
		break;
-
	}
-
	if (filename != NULL && line >= 0 && pkg_handle_get_debug(hdl) > 0)
-
		sbuf_printf(sb, " [at %s:%d]", filename, line);
-
	sbuf_done(sb);
-
	if (ret != 0)
-
		pkg_error_set(ret, sbuf_data(sb));
-
	sbuf_delete(sb);
+
	_cb = cb;
+
	_data = data;
}

void
-
__pkg_emit_event(struct pkg_handle *hdl, const char *filename, int line, pkg_event_t ev, int argc, ...)
+
pkg_emit_event(struct pkg_event *ev, const char *file, uint16_t line)
{
-
	va_list ap;
-
	void **argv;
-
	int i;
-

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

-
	pkg_event_argument_check(ev, argc);
-

-
	/* Generate the argument vector to pass in. */
-
	argv = calloc(argc, sizeof(void *));
-
	va_start(ap, argc);
-
	for (i = 0;i < argc; i++)
-
		argv[i] = va_arg(ap, void *);
-
	va_end(ap);
-

-
	libpkg_handle_event(hdl, ev, filename, line, argv);
+
	ev->file = file;
+
	ev->line = line;

-
	if (hdl->event_cb != NULL)
-
		hdl->event_cb(ev, filename, line, argv);
-
	free(argv);
+
	if (_cb != NULL)
+
		_cb(_data, ev);
}
added libpkg/pkg_event.h
@@ -0,0 +1,61 @@
+
#ifndef _PKG_EVENT
+
#define _PKG_EVENT
+

+
#define _EV_START \
+
	do { \
+
		struct pkg_event ev
+

+
#define _EV_EMIT \
+
	pkg_emit_event(&ev, __FILE__, __LINE__)
+

+
#define _EV_END \
+
	} while(0)
+

+
#define EMIT_PKG_ERROR(fmt, ...) \
+
	_EV_START; \
+
	ev.type = PKG_EVENT_ERROR; \
+
	asprintf(&ev.e_pkg_error.msg, fmt, __VA_ARGS__); \
+
	_EV_EMIT; \
+
	free(ev.e_pkg_error.msg); \
+
	_EV_END
+

+
#define EMIT_ERRNO(f, a) \
+
	_EV_START; \
+
	ev.type = PKG_EVENT_ERRNO; \
+
	ev.e_errno.func = f; \
+
	ev.e_errno.arg = a; \
+
	_EV_EMIT; \
+
	_EV_END
+

+
#define EMIT_ALREADY_INSTALLED(p) \
+
	_EV_START; \
+
	ev.type = PKG_EVENT_ALREADY_INSTALLED; \
+
	ev.e_already_installed.pkg = p; \
+
	_EV_EMIT; \
+
	_EV_END
+

+
#define EMIT_INSTALL_BEGIN(p) \
+
	_EV_START; \
+
	ev.type = PKG_EVENT_INSTALL_BEGIN; \
+
	ev.e_begin_install.pkg = p; \
+
	_EV_EMIT; \
+
	_EV_END
+

+
#define EMIT_MISSING_DEP(p, d) \
+
	_EV_START; \
+
	ev.type = PKG_EVENT_MISSING_DEP; \
+
	ev.e_missing_dep.pkg = p; \
+
	ev.e_missing_dep.dep = d;  \
+
	_EV_EMIT; \
+
	_EV_END
+

+
#define EMIT_FAILED_CKSUM(p) \
+
	_EV_START; \
+
	ev.type = PKG_EVENT_FAILED_CKSUM; \
+
	ev.e_failed_cksum.pkg = p; \
+
	_EV_EMIT; \
+
	_EV_END
+

+
void pkg_emit_event(struct pkg_event *, const char *, uint16_t);
+

+
#endif
deleted libpkg/pkg_handle.c
@@ -1,32 +0,0 @@
-
#include "pkg.h"
-

-
struct pkg_handle __pkg_handle_singleton;
-

-
struct pkg_handle *
-
pkg_get_handle(void)
-
{
-
	return &__pkg_handle_singleton;
-
}
-

-
void
-
pkg_handle_set_event_callback(struct pkg_handle *hdl, pkg_event_cb event_cb)
-
{
-
	hdl->event_cb = event_cb;
-
}
-

-
pkg_event_cb
-
pkg_handle_get_event_callback(struct pkg_handle *hdl)
-
{
-
	return hdl->event_cb;
-
}
-

-
void
-
pkg_handle_set_debug(struct pkg_handle *hdl, int debug)
-
{
-
	hdl->debug = debug;
-
}
-
int
-
pkg_handle_get_debug(struct pkg_handle *hdl)
-
{
-
	return hdl->debug;
-
}
modified libpkg/pkg_manifest.c
@@ -12,6 +12,7 @@
#include <yaml.h>

#include "pkg.h"
+
#include "pkg_event.h"
#include "pkg_error.h"
#include "pkg_util.h"
#include "pkg_private.h"
modified libpkg/pkg_repo.c
@@ -4,6 +4,7 @@
#include <unistd.h>

#include "pkg.h"
+
#include "pkg_event.h"
#include "pkg_error.h"
#include "pkg_private.h"

@@ -47,7 +48,7 @@ pkg_repo_fetch(struct pkg *pkg, void *data, fetch_cb cb)
	retcode = sha256_file(dest, cksum);
	if (retcode == EPKG_OK)
		if (strcmp(cksum, pkg_get(pkg, PKG_CKSUM))) {
-
			pkg_emit_event(PKG_EVENT_CKSUM_ERROR, /*argc*/1, pkg);
+
			EMIT_FAILED_CKSUM(pkg);
			retcode = EPKG_FATAL;
		}

modified libpkg/pkg_util.c
@@ -11,10 +11,10 @@
#include <unistd.h>
#include <string.h>

-

#include <openssl/sha.h>

#include "pkg.h"
+
#include "pkg_event.h"
#include "pkg_error.h"
#include "pkg_util.h"

@@ -106,32 +106,28 @@ file_to_buffer(const char *path, char **buffer, off_t *sz)
		return (ERROR_BAD_ARG("sz"));

	if ((fd = open(path, O_RDONLY)) == -1) {
-
		pkg_emit_event(PKG_EVENT_IO_ERROR, /*argc*/3, "open",
-
		    path, strerror(errno));
+
		EMIT_ERRNO("open", path);
		retcode = EPKG_FATAL;
		goto cleanup;
	}

	if (fstat(fd, &st) == -1) {
		close(fd);
-
		pkg_emit_event(PKG_EVENT_IO_ERROR, /*argc*/3, "fstat",
-
		    path, strerror(errno));
+
		EMIT_ERRNO("fstat", path);
		retcode = EPKG_FATAL;
		goto cleanup;
	}

	if ((*buffer = malloc(st.st_size + 1)) == NULL) {
		close(fd);
-
		pkg_emit_event(PKG_EVENT_MALLOC_ERROR, /*argc*/1,
-
		    strerror(errno));
+
		EMIT_ERRNO("malloc", "");
		retcode = EPKG_FATAL;
		goto cleanup;
	}

	if (read(fd, *buffer, st.st_size) == -1) {
		close(fd);
-
		pkg_emit_event(PKG_EVENT_IO_ERROR, /*argc*/3, "read",
-
		    path, strerror(errno));
+
		EMIT_ERRNO("read", path);
		retcode = EPKG_FATAL;
		goto cleanup;
	}
@@ -262,8 +258,7 @@ sha256_file(const char *path, char out[65])
	SHA256_CTX sha256;

	if ((fp = fopen(path, "rb")) == NULL) {
-
		pkg_emit_event(PKG_EVENT_IO_ERROR, /*argc*/3, "open",
-
		    path, strerror(errno));
+
		EMIT_ERRNO("fopen", path);
		return EPKG_FATAL;
	}

@@ -275,8 +270,7 @@ sha256_file(const char *path, char out[65])
	if (ferror(fp) != 0) {
		fclose(fp);
		out[0] = '\0';
-
		pkg_emit_event(PKG_EVENT_IO_ERROR, /*argc*/3, "read",
-
		    path, strerror(errno));
+
		EMIT_ERRNO("fread", path);
		return EPKG_FATAL;
	}

modified libpkg/pkgdb.c
@@ -13,6 +13,7 @@
#include <sqlite3.h>

#include "pkg.h"
+
#include "pkg_event.h"
#include "pkg_error.h"
#include "pkg_private.h"
#include "pkgdb.h"
@@ -227,7 +228,7 @@ pkgdb_init(sqlite3 *sdb)
	;

	if (sqlite3_exec(sdb, sql, NULL, NULL, &errmsg) != SQLITE_OK) {
-
		pkg_emit_event(PKG_EVENT_SQLITE_ERROR, /*argc*/1, errmsg);
+
		EMIT_PKG_ERROR("sqlite: %s", errmsg);
		sqlite3_free(errmsg);
		return (EPKG_FATAL);
	}
@@ -248,8 +249,7 @@ pkgdb_open(struct pkgdb **db, pkgdb_t type)
	dbdir = pkg_config("PKG_DBDIR");

	if ((*db = calloc(1, sizeof(struct pkgdb))) == NULL) {
-
		pkg_emit_event(PKG_EVENT_MALLOC_ERROR, /*argc*/1,
-
		    strerror(errno));
+
		EMIT_ERRNO("malloc", "");
		return EPKG_FATAL;
	}

@@ -259,13 +259,11 @@ pkgdb_open(struct pkgdb **db, pkgdb_t type)
	retcode = access(localpath, R_OK);
	if (retcode == -1) {
		if (errno != ENOENT) {
-
			pkg_emit_event(PKG_EVENT_IO_ERROR, /*argc*/3, "access",
-
			    localpath, strerror(errno));
+
			EMIT_ERRNO("access", localpath);
			return EPKG_FATAL;
		}
		else if (eaccess(dbdir, W_OK) != 0) {
-
			pkg_emit_event(PKG_EVENT_IO_ERROR, /*argc*/3, "eaccess",
-
			    dbdir, strerror(errno));
+
			EMIT_ERRNO("eaccess", dbdir);
			return EPKG_FATAL;
		}
	}
@@ -277,15 +275,14 @@ pkgdb_open(struct pkgdb **db, pkgdb_t type)
		snprintf(remotepath, sizeof(remotepath), "%s/repo.sqlite", dbdir);

		if (access(remotepath, R_OK) != 0) {
-
			pkg_emit_event(PKG_EVENT_IO_ERROR, /*argc*/3, "access",
-
			    remotepath, strerror(errno));
+
			EMIT_ERRNO("access", remotepath);
			return EPKG_FATAL;
		}

		sqlite3_snprintf(sizeof(sql), sql, "ATTACH \"%s\" as remote;", remotepath);

		if (sqlite3_exec((*db)->sqlite, sql, NULL, NULL, &errmsg) != SQLITE_OK) {
-
			pkg_emit_event(PKG_EVENT_SQLITE_ERROR, /*argc*/1, errmsg);
+
			EMIT_PKG_ERROR("sqlite: %s", errmsg);
			sqlite3_free(errmsg);
			return (EPKG_FATAL);
		}
@@ -311,7 +308,7 @@ pkgdb_open(struct pkgdb **db, pkgdb_t type)
	 */
	if (sqlite3_exec((*db)->sqlite, "PRAGMA foreign_keys = ON;", NULL, NULL,
		&errmsg) != SQLITE_OK) {
-
		pkg_emit_event(PKG_EVENT_SQLITE_ERROR, /*argc*/1, errmsg);
+
		EMIT_PKG_ERROR("sqlite: %s", errmsg);
		sqlite3_free(errmsg);
		return (EPKG_FATAL);
	}
@@ -341,8 +338,7 @@ pkgdb_it_new(struct pkgdb *db, sqlite3_stmt *s, int type)
	struct pkgdb_it *it;

	if ((it = malloc(sizeof(struct pkgdb_it))) == NULL) {
-
		pkg_emit_event(PKG_EVENT_MALLOC_ERROR, /*argc*/1,
-
		    strerror(errno));
+
		EMIT_ERRNO("malloc", "");
		sqlite3_finalize(s);
		return (NULL);
	}
@@ -970,15 +966,14 @@ pkgdb_register_pkg(struct pkgdb *db, struct pkg *pkg)
		"VALUES (?1, ?2);";

	if (pkgdb_has_flag(db, PKGDB_FLAG_IN_FLIGHT)) {
-
		pkg_emit_event(PKG_EVENT_INVALID_DB_STATE, /*argc*/1,
-
		    "tried to register a package with an in-flight SQL command");
+
		EMIT_PKG_ERROR("%s", "tried to register a package with an in-flight SQL command");
		return (EPKG_FATAL);
	}

	s = db->sqlite;

	if (sqlite3_exec(s, sql_begin, NULL, NULL, &errmsg) != SQLITE_OK) {
-
		pkg_emit_event(PKG_EVENT_SQLITE_ERROR, /*argc*/1, errmsg);
+
		EMIT_PKG_ERROR("sqlite: %s", errmsg);
		sqlite3_free(errmsg);
		return (EPKG_FATAL);
	}
@@ -1007,12 +1002,7 @@ pkgdb_register_pkg(struct pkgdb *db, struct pkg *pkg)
	sqlite3_bind_int(stmt_pkg, 14, pkg_isautomatic(pkg));

	if ((ret = sqlite3_step(stmt_pkg)) != SQLITE_DONE) {
-
		if ( ret == SQLITE_CONSTRAINT) {
-
			pkg_emit_event(PKG_EVENT_SQLITE_CONSTRAINT, /*argc*/2,
-
			    "pkg", pkg_get(pkg, PKG_ORIGIN));
-
			retcode = EPKG_FATAL;
-
		} else
-
			retcode = ERROR_SQLITE(s);
+
		retcode = ERROR_SQLITE(s);
		goto cleanup;
	}

@@ -1051,12 +1041,7 @@ pkgdb_register_pkg(struct pkgdb *db, struct pkg *pkg)
		sqlite3_bind_int64(stmt_dep, 4, package_id);

		if ((ret = sqlite3_step(stmt_dep)) != SQLITE_DONE) {
-
			if ( ret == SQLITE_CONSTRAINT) {
-
				pkg_emit_event(PKG_EVENT_SQLITE_CONSTRAINT,
-
				    /*argc*/2, "deps", pkg_dep_origin(dep));
-
				retcode = EPKG_FATAL;
-
			} else
-
				retcode = ERROR_SQLITE(s);
+
			retcode = ERROR_SQLITE(s);
			goto cleanup;
		}

@@ -1077,13 +1062,7 @@ pkgdb_register_pkg(struct pkgdb *db, struct pkg *pkg)
		sqlite3_bind_int64(stmt_conflict, 2, package_id);

		if ((ret = sqlite3_step(stmt_conflict)) != SQLITE_DONE) {
-
			if ( ret == SQLITE_CONSTRAINT) {
-
				pkg_emit_event(PKG_EVENT_SQLITE_CONSTRAINT,
-
				    /*argc*/2, "conflicts",
-
				    pkg_conflict_glob(conflict));
-
				retcode = EPKG_FATAL;
-
			} else
-
				retcode = ERROR_SQLITE(s);
+
			retcode = ERROR_SQLITE(s);
			goto cleanup;
		}

@@ -1107,8 +1086,8 @@ pkgdb_register_pkg(struct pkgdb *db, struct pkg *pkg)

		if ((ret = sqlite3_step(stmt_file)) != SQLITE_DONE) {
			if (ret == SQLITE_CONSTRAINT) {
-
				pkg_emit_event(PKG_EVENT_SQLITE_CONSTRAINT,
-
				    /*argc*/2, "path", pkg_file_path(file));
+
				    EMIT_PKG_ERROR("sqlite constraint violation on files.path:"
+
								   " %s", pkg_file_path(file));
				retcode = EPKG_FATAL;
			} else
				retcode = ERROR_SQLITE(s);
@@ -1132,8 +1111,8 @@ pkgdb_register_pkg(struct pkgdb *db, struct pkg *pkg)
			
		if ((ret = sqlite3_step(stmt_dirs)) != SQLITE_DONE) {
			if ( ret == SQLITE_CONSTRAINT) {
-
				pkg_emit_event(PKG_EVENT_SQLITE_CONSTRAINT,
-
				    /*argc*/2, "dirs", pkg_dir_path(dir));
+
				EMIT_PKG_ERROR("sqlite: constraint violation on dirs.path: %s",
+
			 					pkg_dir_path(dir));
				retcode = EPKG_FATAL;
			} else
				retcode = ERROR_SQLITE(s);
@@ -1157,13 +1136,7 @@ pkgdb_register_pkg(struct pkgdb *db, struct pkg *pkg)
		sqlite3_bind_int64(stmt_script, 3, package_id);

		if (sqlite3_step(stmt_script) != SQLITE_DONE) {
-
			if ( ret == SQLITE_CONSTRAINT) {
-
				pkg_emit_event(PKG_EVENT_SQLITE_CONSTRAINT,
-
				    /*argc*/2, "scripts",
-
				    pkg_script_data(script));
-
				retcode = EPKG_FATAL;
-
			} else
-
				retcode = ERROR_SQLITE(s);
+
			retcode = ERROR_SQLITE(s);
			goto cleanup;
		}

@@ -1230,14 +1203,13 @@ pkgdb_register_finale(struct pkgdb *db, int retcode)
	char *errmsg;

	if (!pkgdb_has_flag(db, PKGDB_FLAG_IN_FLIGHT)) {
-
		pkg_emit_event(PKG_EVENT_INVALID_DB_STATE, /*argc*/1,
-
		    "database command not in flight");
+
		EMIT_PKG_ERROR("%s", "database command not in flight (misuse)");
		return EPKG_FATAL;
	}

	command = (retcode == EPKG_OK) ? commands[0] : commands[1];
	if (sqlite3_exec(db->sqlite, command, NULL, NULL, &errmsg) != SQLITE_OK) {
-
		pkg_emit_event(PKG_EVENT_SQLITE_ERROR, /*argc*/1, errmsg);
+
		EMIT_PKG_ERROR("sqlite: %s", errmsg);
		ret = EPKG_FATAL;
		sqlite3_free(errmsg);
	}
@@ -1327,7 +1299,7 @@ pkgdb_compact(struct pkgdb *db)
		return (EPKG_OK);

	if (sqlite3_exec(db->sqlite, "VACUUM;", NULL, NULL, &errmsg) != SQLITE_OK){
-
		pkg_emit_event(PKG_EVENT_SQLITE_ERROR, /*argc*/1, errmsg);
+
		EMIT_PKG_ERROR("sqlite: %s", errmsg);
		retcode = EPKG_FATAL;
		sqlite3_free(errmsg);
	}
@@ -1341,8 +1313,7 @@ pkgdb_query_upgrades(struct pkgdb *db)
	sqlite3_stmt *stmt;

	if (db->type != PKGDB_REMOTE) {
-
		pkg_emit_event(PKG_EVENT_INVALID_DB_STATE, /*argc*/1,
-
		    "remote database not attached");
+
		EMIT_PKG_ERROR("%s", "remote database not attached (misuse)");
		return (NULL);
	}

@@ -1369,8 +1340,7 @@ pkgdb_query_downgrades(struct pkgdb *db)
	sqlite3_stmt *stmt;

	if (db->type != PKGDB_REMOTE) {
-
		pkg_emit_event(PKG_EVENT_INVALID_DB_STATE, /*argc*/1,
-
		    "remote database not attached");
+
		EMIT_PKG_ERROR("%s", "remote database not attached (misuse)");
		return (NULL);
	}

@@ -1418,8 +1388,7 @@ pkgdb_rquery(struct pkgdb *db, const char *pattern, match_t match, unsigned int
	struct sbuf *sql = sbuf_new_auto();

	if (db->type != PKGDB_REMOTE) {
-
		pkg_emit_event(PKG_EVENT_INVALID_DB_STATE, /*argc*/1,
-
		    "remote database not attached");
+
		EMIT_PKG_ERROR("%s", "remote database not attached (misuse)");
		return (NULL);
	}

modified pkg/event.c
@@ -1,25 +1,20 @@
-
#include <archive.h>
#include <err.h>

#include "pkg.h"
#include "event.h"

int
-
event_callback(pkg_event_t ev, const char *filename, int line, void **argv)
+
event_callback(void *data __unused, struct pkg_event *ev)
{

-
	switch(ev) {
-
	case PKG_EVENT_INSTALL_BEGIN:
-
		printf("Installing %s\n", pkg_get((struct pkg *)argv[0], PKG_NAME));
+
	switch(ev->type) {
+
	case PKG_EVENT_ERRNO:
+
		warn("%s(%s)", ev->e_errno.func, ev->e_errno.arg);
		break;
-
	case PKG_EVENT_ARCHIVE_ERROR:
-
		fprintf(stderr, "archive error on %s: %s [at %s:%d]\n",
-
		    (const char *)argv[0], archive_error_string(argv[1]),
-
		    filename, line);
+
	case PKG_EVENT_ERROR:
+
		warnx("%s", ev->e_pkg_error.msg);
		break;
-
	case PKG_EVENT_ARCHIVE_COMP_UNSUP:
-
		warnx("%s is not supported, trying %s",
-
		    (const char *)argv[0], (const char *)argv[1]);
+
	case PKG_EVENT_INSTALL_BEGIN:
		break;
	default:
		break;
modified pkg/event.h
@@ -1,6 +1,6 @@
#ifndef __PKG_EVENT_H__
#define	__PKG_EVENT_H__

-
int event_callback(pkg_event_t ev, const char *, int, void **argv);
+
int event_callback(void *data, struct pkg_event *ev);

#endif
modified pkg/main.c
@@ -111,15 +111,13 @@ main(int argc, char **argv)
	struct commands *command = NULL;
	unsigned int ambiguous = 0;
	size_t len;
-
	struct pkg_handle *hdl;
	char ch;
	int debug = 0;

	if (argc < 2)
		usage();

-
	hdl = pkg_get_handle();
-
	pkg_handle_set_event_callback(hdl, event_callback);
+
	pkg_event_register(&event_callback, NULL);

	while ((ch = getopt(argc, argv, "d")) != -1) {
		switch(ch) {
@@ -130,7 +128,6 @@ main(int argc, char **argv)
				break;
		}
	}
-
	pkg_handle_set_debug(hdl, debug);
	argc -= optind;
	argv += optind;
	/* reset getopt for the next call */
modified pkg/update.c
@@ -51,9 +51,8 @@ exec_update(int argc, char **argv)
{
	char url[MAXPATHLEN];
	const char *packagesite = NULL;
+
	char *tmp;
	int retcode = 0;
-
	int size = 0;
-
	char *repo;
	struct archive *a;
	struct archive_entry *ae;

@@ -78,7 +77,10 @@ exec_update(int argc, char **argv)
	else
		snprintf(url, MAXPATHLEN, "%s/repo.txz", packagesite);

-
	if (pkg_fetch_buffer(url, &repo, &size, &fetch_status) != EPKG_OK) {
+
	
+
	tmp = mktemp(strdup("/tmp/repo.txz.XXXXXX"));
+

+
	if (pkg_fetch_file(url, tmp, NULL, &fetch_status) != EPKG_OK) {
		pkg_error_warn("can not fetch %s", url);
		retcode = 1;
	}
@@ -87,7 +89,7 @@ exec_update(int argc, char **argv)
	archive_read_support_compression_all(a);
	archive_read_support_format_tar(a);

-
	archive_read_open_memory(a, repo, size);
+
	archive_read_open_filename(a, tmp, 4096);

	while (archive_read_next_header(a, &ae) == ARCHIVE_OK) {
		if (strcmp(archive_entry_pathname(ae), "repo.sqlite") == 0) {
@@ -98,6 +100,8 @@ exec_update(int argc, char **argv)
	}

	archive_read_finish(a);
+
	unlink(tmp);
+
	free(tmp);

	return (retcode);
}