Radish alpha
H
HardenedBSD Package Manager
Radicle
Git (anonymous pull)
Log in to clone via SSH
Introduce new pkg_error error reporting facility.
jlaffaye committed 15 years ago
commit 207fe90674b14a08fe9e287ef381ec06bc3621ad
parent b08c33e65c19ab1ae975460febbcb1353a868443
11 files changed +271 -91
modified libpkg/Makefile
@@ -13,6 +13,7 @@ SRCS= pkg.c \
		pkg_conflict.c \
		pkg_delete.c \
		pkg_elf.c \
+
		pkg_error.c \
		pkg_exec.c \
		pkg_file.c \
		pkg_manifest.c \
@@ -35,7 +36,8 @@ LDADD+= -L${.CURDIR}/../external/sqlite \
		-llzma \
		-lsbuf \
		-lfetch \
-
		-lelf
+
		-lelf \
+
		-lpthread

DEBUG_FLAGS+=  -g
.if defined(PROFILE_BUILD)
modified libpkg/pkg.c
@@ -6,6 +6,7 @@
#include <errno.h>

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

@@ -14,8 +15,10 @@ static void pkg_free_void(void*);
pkg_t
pkg_type(struct pkg *pkg)
{
-
	if (pkg == NULL)
+
	if (pkg == NULL) {
+
		ERROR_BAD_ARG("pkg");
		return (PKG_NONE);
+
	}

	return (pkg->type);
}
@@ -23,8 +26,10 @@ pkg_type(struct pkg *pkg)
const char *
pkg_get(struct pkg *pkg, pkg_attr attr)
{
-
	if (pkg == NULL)
+
	if (pkg == NULL) {
+
		ERROR_BAD_ARG("pkg");
		return (NULL);
+
	}

	switch (attr) {
		case PKG_NAME:
@@ -60,11 +65,10 @@ int
pkg_set(struct pkg *pkg, pkg_attr attr, const char *value)
{
	if (pkg == NULL)
-
		return (EPKG_NULL_PKG);
+
		return (ERROR_BAD_ARG("pkg"));

-
	if (value == NULL) {
-
		return (EPKG_NULL_VALUE);
-
	}
+
	if (value == NULL)
+
		return (ERROR_BAD_ARG("value"));

	switch (attr) {
		case PKG_NAME:
@@ -104,7 +108,7 @@ pkg_set(struct pkg *pkg, pkg_attr attr, const char *value)
			return (sbuf_set(&pkg->prefix, value));
	}

-
	return (EPKG_FATAL);
+
	return (ERROR_BAD_ARG("attr"));
}

int
@@ -115,10 +119,10 @@ pkg_set_from_file(struct pkg *pkg, pkg_attr attr, const char *path)
	int ret = EPKG_OK;

	if (pkg == NULL)
-
		return (EPKG_NULL_PKG);
+
		return (ERROR_BAD_ARG("pkg"));

	if (path == NULL)
-
		return (EPKG_NULL_VALUE);
+
		return (ERROR_BAD_ARG("path"));

	if ((ret = file_to_buffer(path, &buf, &size)) !=  EPKG_OK)
		return (ret);
@@ -133,8 +137,10 @@ pkg_set_from_file(struct pkg *pkg, pkg_attr attr, const char *path)
int64_t
pkg_flatsize(struct pkg *pkg)
{
-
	if (pkg == NULL)
+
	if (pkg == NULL) {
+
		ERROR_BAD_ARG("pkg");
		return (-1);
+
	}

	return (pkg->flatsize);
}
@@ -142,8 +148,10 @@ pkg_flatsize(struct pkg *pkg)
struct pkg_script **
pkg_scripts(struct pkg *pkg)
{
-
	if (pkg == NULL)
+
	if (pkg == NULL) {
+
		ERROR_BAD_ARG("pkg");
		return (NULL);
+
	}

	return ((struct pkg_script **)pkg->scripts.data);
}
@@ -151,8 +159,10 @@ pkg_scripts(struct pkg *pkg)
struct pkg_exec **
pkg_execs(struct pkg *pkg)
{
-
	if (pkg == NULL)
+
	if (pkg == NULL) {
+
		ERROR_BAD_ARG("pkg");
		return (NULL);
+
	}

	return (struct pkg_exec **) pkg->exec.data;
}
@@ -160,8 +170,10 @@ pkg_execs(struct pkg *pkg)
struct pkg **
pkg_deps(struct pkg *pkg)
{
-
	if (pkg == NULL)
+
	if (pkg == NULL) {
+
		ERROR_BAD_ARG("pkg");
		return (NULL);
+
	}

	return ((struct pkg **)pkg->deps.data);
}
@@ -169,8 +181,10 @@ pkg_deps(struct pkg *pkg)
struct pkg_option **
pkg_options(struct pkg *pkg)
{
-
	if (pkg == NULL)
+
	if (pkg == NULL) {
+
		ERROR_BAD_ARG("pkg");
		return (NULL);
+
	}

	return ((struct pkg_option **)pkg->options.data);
}
@@ -184,6 +198,7 @@ pkg_resolvdeps(struct pkg *pkg, struct pkgdb *db) {

	deps = pkg_deps(pkg);
	if (deps == NULL)
+
		// TODO: error reporting
		return (-1);

	pkg_new(&p);
@@ -199,14 +214,16 @@ pkg_resolvdeps(struct pkg *pkg, struct pkgdb *db) {
	}
	pkg_free(p);

-
	return (1);
+
	return (EPKG_OK);
}

struct pkg **
pkg_rdeps(struct pkg *pkg)
{
-
	if (pkg == NULL)
+
	if (pkg == NULL) {
+
		ERROR_BAD_ARG("pkg");
		return (NULL);
+
	}

	return ((struct pkg **)pkg->rdeps.data);
}
@@ -214,8 +231,10 @@ pkg_rdeps(struct pkg *pkg)
struct pkg_file **
pkg_files(struct pkg *pkg)
{
-
	if (pkg == NULL)
+
	if (pkg == NULL) {
+
		ERROR_BAD_ARG("pkg");
		return (NULL);
+
	}

	return ((struct pkg_file **)pkg->files.data);
}
@@ -223,8 +242,10 @@ pkg_files(struct pkg *pkg)
struct pkg_conflict **
pkg_conflicts(struct pkg *pkg)
{
-
	if (pkg == NULL)
+
	if (pkg == NULL) {
+
		ERROR_BAD_ARG("pkg");
		return (NULL);
+
	}

	return ((struct pkg_conflict **)pkg->conflicts.data);
}
@@ -236,14 +257,15 @@ pkg_open(const char *path, struct pkg **pkg_p, int query_flags)
	struct archive_entry *ae;
	struct pkg *pkg;
	struct pkg_script *script;
+
	pkg_error_t retcode = EPKG_OK;
	int ret;
	int64_t size;
	char *manifest;
	const char *fpath;
-
	char buf[1024];
+
	char buf[2048];

	if (path == NULL)
-
		return (EPKG_NULL_VALUE);
+
		return (ERROR_BAD_ARG("path"));

	/* search for http(s) or ftp(s) */
	if (STARTS_WITH(path, "http://") || STARTS_WITH(path, "https://")
@@ -267,13 +289,14 @@ pkg_open(const char *path, struct pkg **pkg_p, int query_flags)
	pkg->type = PKG_FILE;
	pkg->path = path;

-
	if (archive_read_open_filename(a, path, 4096) != ARCHIVE_OK)
-
		goto error;
+
	if (archive_read_open_filename(a, path, 4096) != ARCHIVE_OK) {
+
		archive_read_finish(a);
+
		return (pkg_error_set(EPKG_FATAL, "%s", archive_error_string(a)));
+
	}

	/* first path to check is the archive is corrupted bye the way retreive
	 * informations */

-

	array_init(&pkg->scripts, 10);
	array_init(&pkg->files, 10);

@@ -289,10 +312,13 @@ pkg_open(const char *path, struct pkg **pkg_p, int query_flags)
			archive_read_data(a, manifest, size);
			ret = pkg_parse_manifest(pkg, manifest);
			free(manifest);
-
			if (ret != EPKG_OK)
-
				goto error;
+
			if (ret != EPKG_OK) {
+
				retcode = EPKG_FATAL;
+
				break;
+
			}
		}

+
		/* TODO: replace macros by loop - jlaffaye */
#define COPY_FILE(fname, dest)												\
	if (strcmp(fpath, fname) == 0) {										\
		dest = sbuf_new_auto();												\
@@ -329,24 +355,18 @@ pkg_open(const char *path, struct pkg **pkg_p, int query_flags)
	}

	if (ret != ARCHIVE_OK && ret != ARCHIVE_EOF) {
-
		warnx("libarchive: %s", archive_error_string(a));
-
		goto error;
+
		retcode = pkg_error_set(EPKG_FATAL, "%s", archive_error_string(a));
	}

	archive_read_finish(a);
-
	return (EPKG_OK);
-

-
error:
-
	archive_read_finish(a);
-

-
	return (EPKG_ERROR_ARCHIVE);
+
	return (retcode);
}

int
pkg_new(struct pkg **pkg)
{
	if ((*pkg = calloc(1, sizeof(struct pkg))) == NULL)
-
		err(EXIT_FAILURE, "calloc()");
+
		return(pkg_error_seterrno());

	return (EPKG_OK);
}
@@ -423,10 +443,10 @@ int
pkg_setflatsize(struct pkg *pkg, int64_t size)
{
	if (pkg == NULL)
-
		return (EPKG_NULL_PKG);
+
		return (ERROR_BAD_ARG("pkg"));

	if (size <= 0)
-
		return (EPKG_FATAL);
+
		return (ERROR_BAD_ARG("size"));

	pkg->flatsize = size;
	return (EPKG_OK);
@@ -442,10 +462,10 @@ pkg_addscript(struct pkg *pkg, const char *path)
	off_t sz = 0;

	if (pkg == NULL)
-
		return (EPKG_NULL_PKG);
+
		return (ERROR_BAD_ARG("pkg"));

	if (path == NULL)
-
		return (EPKG_NULL_VALUE);
+
		return (ERROR_BAD_ARG("path"));

	if ((ret = file_to_buffer(path, &raw_script, &sz)) != EPKG_OK)
		return (ret);
@@ -477,7 +497,7 @@ pkg_addscript(struct pkg *pkg, const char *path)
	} else if (strcmp(filename, "pkg-upgrade") == 0) {
		script->type = PKG_SCRIPT_UPGRADE;
	} else {
-
		return (EPKG_UNKNOWN_SCRIPT);
+
		return (pkg_error_set(EPKG_FATAL, "unknown script"));
	}

	array_init(&pkg->scripts, 6);
@@ -492,10 +512,10 @@ pkg_addexec(struct pkg *pkg, const char *cmd, pkg_exec_t type)
	struct pkg_exec *exec;

	if (pkg == NULL)
-
		return (EPKG_NULL_PKG);
+
		return (ERROR_BAD_ARG("pkg"));

	if (cmd == NULL || cmd[0] == '\0')
-
		return (EPKG_NULL_VALUE);
+
		return (ERROR_BAD_ARG("cmd"));

	pkg_exec_new(&exec);

@@ -514,10 +534,13 @@ pkg_addoption(struct pkg *pkg, const char *opt, const char *value)
	struct pkg_option *option;

	if (pkg == NULL)
-
		return (EPKG_NULL_PKG);
+
		return (ERROR_BAD_ARG("pkg"));
+

+
	if (opt == NULL || opt[0] == '\0')
+
		return (ERROR_BAD_ARG("opt"));

-
	if (opt == NULL || opt[0] == '\0' || value == NULL || value[0] == '\0')
-
		return (EPKG_NULL_VALUE);
+
	if (value == NULL || value[0] == '\0')
+
		return (ERROR_BAD_ARG("value"));

	pkg_option_new(&option);

@@ -536,11 +559,16 @@ pkg_adddep(struct pkg *pkg, const char *name, const char *origin, const char *ve
	struct pkg *dep;

	if (pkg == NULL)
-
		return (EPKG_NULL_PKG);
+
		return (ERROR_BAD_ARG("pkg"));
+

+
	if (name == NULL || name[0] == '\0')
+
		return (ERROR_BAD_ARG("name"));
+

+
	if (origin == NULL || origin[0] == '\0')
+
		return (ERROR_BAD_ARG("origin"));

-
	if (name == NULL || name[0] == '\0' || origin == NULL || origin[0] == '\0'
-
		|| version == NULL || version[0] == '\0')
-
		return (EPKG_NULL_VALUE);
+
	if (version == NULL || version[0] == '\0')
+
		return (ERROR_BAD_ARG("version"));

	pkg_new(&dep);

@@ -561,15 +589,16 @@ pkg_addfile(struct pkg *pkg, const char *path, const char *sha256)
	struct pkg_file *file;

	if (pkg == NULL)
-
		return (EPKG_NULL_PKG);
+
		return (ERROR_BAD_ARG("pkg"));

	if (path == NULL || path[0] == '\0')
-
		return (EPKG_NULL_VALUE);
+
		return (ERROR_BAD_ARG("path"));

	pkg_file_new(&file);

	strlcpy(file->path, path, sizeof(file->path));

+
	/* TODO: when is it not required? - jlaffaye */
	if (sha256 != NULL)
		strlcpy(file->sha256, sha256, sizeof(file->sha256));

@@ -585,10 +614,10 @@ pkg_addconflict(struct pkg *pkg, const char *glob)
	struct pkg_conflict *conflict;

	if (pkg == NULL)
-
		return (EPKG_NULL_PKG);
+
		return (ERROR_BAD_ARG("pkg"));

	if (glob == NULL || glob[0] == '\0')
-
		return (EPKG_NULL_VALUE);
+
		return (ERROR_BAD_ARG("glob"));

	pkg_conflict_new(&conflict);
	sbuf_set(&conflict->glob, glob);
modified libpkg/pkg.h
@@ -127,18 +127,9 @@ typedef enum {
	 * errno was set to describe the error.
	 */
	EPKG_FATAL,
-
	EPKG_NULL_PKG,
-
	EPKG_NULL_VALUE,
-
	EPKG_ERROR_MALLOC,
-
	EPKG_ERROR_STAT,
-
	EPKG_ERROR_OPEN,
-
	EPKG_ERROR_READ,
-
	EPKG_ERROR_ARCHIVE,
-
	EPKG_UNKNOWN_SCRIPT,
+
	EPKG_REQUIRED,
	EPKG_NOT_ORIGIN,
	EPKG_NOT_NAME,
-
	EPKG_ERROR_MTREE,
-
	EPKG_BAD_PACKAGE,
} pkg_error_t;

/**
@@ -361,4 +352,8 @@ int ports_parse_conflicts(struct pkg *, char *);
int ports_parse_scripts(struct pkg *, char *);
int ports_parse_options(struct pkg *, char *);

+
pkg_error_t pkg_error_number(void);
+
const char * pkg_error_string(void);
+
void pkg_error_warn(const char *fmt, ...);
+

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

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

#define EXTRACT_ARCHIVE_FLAGS  (ARCHIVE_EXTRACT_OWNER |ARCHIVE_EXTRACT_PERM| \
@@ -23,7 +24,7 @@ pkg_extract(const char *path)

	if (archive_read_open_filename(a, path, 4096) != ARCHIVE_OK) {
		archive_read_finish(a);
-
		return (-1);
+
		return (pkg_error_set(EPKG_FATAL, "%s", archive_error_string(a)));
	}

	while ((ret = archive_read_next_header(a, &ae)) == ARCHIVE_OK) {
@@ -34,9 +35,8 @@ pkg_extract(const char *path)
		}
	}

-
	/* this should never happen */
	if (ret != ARCHIVE_EOF)
-
		return (EPKG_ERROR_ARCHIVE);
+
		return (pkg_error_set(EPKG_FATAL, "%s", archive_error_string(a)));

	archive_read_finish(a);

@@ -49,10 +49,11 @@ pkg_add(struct pkgdb *db, struct pkg *pkg)
	struct pkg_exec **execs;
	struct pkg_script **scripts;
	struct sbuf *script_cmd;
+
	int retcode = EPKG_OK;
	int i;

	if (pkg_type(pkg) != PKG_FILE || pkg->path == NULL)
-
		return (EPKG_BAD_PACKAGE);
+
		return (ERROR_BAD_ARG("pkg"));

	script_cmd = sbuf_new_auto();

@@ -78,8 +79,8 @@ pkg_add(struct pkgdb *db, struct pkg *pkg)
			}
		}

-
	if (pkg_extract(pkg->path) != EPKG_OK)
-
		return (EPKG_ERROR_ARCHIVE);
+
	if ((retcode = pkg_extract(pkg->path)) != EPKG_OK)
+
		return (retcode);

	/* execute post install scripts */
	if (scripts != NULL)
modified libpkg/pkg_delete.c
@@ -8,6 +8,7 @@
#include <stdlib.h>

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

static
@@ -38,19 +39,23 @@ pkg_delete(struct pkg *pkg, struct pkgdb *db, int force)
	struct sbuf *script_cmd;
	int ret, i;

-
	if (pkg == NULL || db == NULL)
-
		return (-1);
+
	if (pkg == NULL)
+
		return (ERROR_BAD_ARG("pkg"));
+

+
	if (db == NULL)
+
		return (ERROR_BAD_ARG("db"));

	rdeps = pkg_rdeps(pkg);
	files = pkg_files(pkg);
	prefix = pkg_get(pkg, PKG_PREFIX);

	if (rdeps == NULL || files == NULL)
-
		return (-1);
+
		return (pkg_error_set(EPKG_FATAL, "missing deps and files infos"));

	if (rdeps[0] != NULL && force == 0) {
		warnx("%s is required by other packages", pkg_get(pkg, PKG_ORIGIN));
-
		return (-1); /* TODO: special return code */
+
		return (pkg_error_set(EPKG_REQUIRED, "%s is required by other"
+
							  "packages", pkg_get(pkg, PKG_NAME)));
	}

	script_cmd = sbuf_new_auto();
@@ -81,7 +86,7 @@ pkg_delete(struct pkg *pkg, struct pkgdb *db, int force)

	mtree = pkg_get(pkg, PKG_MTREE);
	if (archive_read_open_memory(a, strdup(mtree), strlen(mtree)) != ARCHIVE_OK)
-
		return (EPKG_ERROR_MTREE);
+
		return (pkg_error_set(EPKG_FATAL, "mtree: %s", archive_error_string(a)));

	bzero(&mtreedirs, sizeof(mtreedirs));
	array_init(&mtreedirs, 20);
added libpkg/pkg_error.c
@@ -0,0 +1,127 @@
+
#include <err.h>
+
#include <errno.h>
+
#include <pthread.h>
+
#include <stdarg.h>
+
#include <stdio.h>
+
#include <stdlib.h>
+
#include <string.h>
+

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

+
struct pkg_error {
+
	pkg_error_t number;
+
	char *string;
+
};
+

+
pthread_once_t pkg_error_once = PTHREAD_ONCE_INIT;
+
pthread_key_t pkg_error_key;
+

+
static struct pkg_error * pkg_error_init(void);
+
static void pkg_error_init_once(void);
+
static void pkg_error_key_free(void *);
+

+
pkg_error_t
+
pkg_error_set(pkg_error_t num, const char *fmt, ...)
+
{
+
	struct pkg_error *e;
+
	va_list ap;
+

+
	e = pkg_error_init();
+

+
	if (e->string != NULL)
+
		free(e->string);
+

+
	e->number = num;
+

+
	va_start(ap, fmt);
+
	vasprintf(&e->string, fmt, ap);
+
	va_end(ap);
+

+
	return (num);
+
}
+

+
pkg_error_t
+
pkg_error_seterrno(void)
+
{
+
	return (pkg_error_set(EPKG_FATAL, "%s", strerror(errno)));
+
}
+

+
pkg_error_t
+
pkg_error_number(void)
+
{
+
	struct pkg_error *e;
+

+
	e = pkg_error_init();
+

+
	return (e->number);
+
}
+

+
const char *
+
pkg_error_string(void)
+
{
+
	struct pkg_error *e;
+

+
	e = pkg_error_init();
+

+
	if (e->number == EPKG_OK)
+
		return ("(Empty error message)");
+
	else
+
		return (e->string);
+
}
+

+
void
+
pkg_error_warn(const char *fmt, ...)
+
{
+
	va_list ap;
+
	char *str = NULL;
+

+
	va_start(ap, fmt);
+
	vasprintf(&str, fmt, ap);
+
	va_end(ap);
+

+
	fprintf(stderr, "%s: %s\n", str, pkg_error_string());
+
	free(str);
+
}
+

+
static struct pkg_error *
+
pkg_error_init(void)
+
{
+
	struct pkg_error *e;
+

+
	if (pthread_once(&pkg_error_once, pkg_error_init_once) != 0)
+
		err(1, "pthread_once()");
+

+
	e = pthread_getspecific(pkg_error_key);
+

+
	if (e == NULL) {
+
		e = malloc(sizeof(e));
+

+
		if (e == NULL)
+
			err(1, "malloc()");
+

+
		e->number = EPKG_OK;
+
		e->string = NULL;
+

+
		if (pthread_setspecific(pkg_error_key, e) != 0)
+
			err(1, "pthread_setspecific()");
+
	}
+

+
	return (e);
+
}
+

+
static void
+
pkg_error_init_once(void)
+
{
+
	if (pthread_key_create(&pkg_error_key, pkg_error_key_free) != 0)
+
		err(1, "pthread_key_create()");
+
}
+

+
static void
+
pkg_error_key_free(void *data)
+
{
+
	struct pkg_error *e = data;
+

+
	free(e->string);
+
	free(e);
+
}
added libpkg/pkg_error.h
@@ -0,0 +1,10 @@
+
#ifndef _PKG_ERROR_H
+
#define _PKG_ERROR_H
+

+
#define ERROR_BAD_ARG(name) \
+
	pkg_error_set(EPKG_FATAL, "Bad argument %s in %s", name, __FUNCTION__)
+

+
pkg_error_t pkg_error_set(pkg_error_t, const char *, ...);
+
pkg_error_t pkg_error_seterrno(void);
+

+
#endif
modified libpkg/pkg_ports.c
@@ -1,13 +1,15 @@
-
#include <pkg.h>
-
#include <pkg_private.h>
+
#include <sys/stat.h>

-
#include <sha256.h>
#include <err.h>
+
#include <sha256.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
-
#include <sys/stat.h>
+

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

int
ports_parse_plist(struct pkg *pkg, char *plist)
@@ -27,8 +29,11 @@ ports_parse_plist(struct pkg *pkg, char *plist)
	buf = NULL;
	p = NULL;

+
	if (pkg == NULL)
+
		return (ERROR_BAD_ARG("pkg"));
+

	if (plist == NULL)
-
		return (EPKG_NULL_VALUE);
+
		return (ERROR_BAD_ARG("plist"));

	if ((ret = file_to_buffer(plist, &plist_buf, &sz)) != EPKG_OK)
		return (ret);
modified libpkg/pkg_util.c
@@ -12,8 +12,9 @@
#include <fetch.h>
#include <libutil.h>

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

void
array_init(struct array *a, size_t c)
@@ -118,28 +119,29 @@ file_to_buffer(const char *path, char **buffer, off_t *sz)
	int fd;
	struct stat st;

-
	assert(path != NULL);
-
	assert(buffer != NULL);
+
	if (path == NULL || path[0] == '\0')
+
		return (ERROR_BAD_ARG("path"));
+

+
	if (buffer == NULL)
+
		return (ERROR_BAD_ARG("buffer"));

	if ((fd = open(path, O_RDONLY)) == -1) {
-
		return (EPKG_ERROR_OPEN);
+
		return (pkg_error_seterrno());
	}

	if (fstat(fd, &st) == -1) {
		close(fd);
-
		return (EPKG_ERROR_STAT);
+
		return (pkg_error_seterrno());
	}

	if ((*buffer = malloc(st.st_size + 1)) == NULL) {
-
		warn("malloc(%llu)", (unsigned long long)st.st_size + 1);
		close(fd);
-
		return (EPKG_ERROR_MALLOC);
+
		return (pkg_error_seterrno());
	}

	if (read(fd, *buffer, st.st_size) == -1) {
-
		warn("read()");
		close(fd);
-
		return (EPKG_ERROR_READ);
+
		return (pkg_error_seterrno());
	}

	close(fd);
modified libpkg/pkgdb.c
@@ -20,6 +20,8 @@

#define PKG_DBDIR "/var/db/pkg"

+
/* TODO: error reporting for all the function that can fail */
+

static struct pkgdb_it * pkgdb_it_new(struct pkgdb *, sqlite3_stmt *, pkgdb_it_t);
static void pkgdb_regex(sqlite3_context *, int, sqlite3_value **, int);
static void pkgdb_regex_basic(sqlite3_context *, int, sqlite3_value **);
modified pkg/add.c
@@ -29,7 +29,8 @@ exec_add(int argc, char **argv)
		return (-1);
	}

-
	if (pkg_open(argv[1], &pkg, 0) != 0) {
+
	if (pkg_open(argv[1], &pkg, 0) != EPKG_OK) {
+
		pkg_error_warn("%s", argv[1]);
		return (-1);
	}

@@ -69,11 +70,12 @@ exec_add(int argc, char **argv)
		}
	}

-
	if (ret != 0)
+
	if (ret != 0) {
		return (ret);
+
	}

	if (pkg_add(db, pkg) != EPKG_OK)
-
		err(1, "installation of %s failed", argv[1]);
+
		pkg_error_warn("Can not install %s", argv[1]);

	pkgdb_close(db);
	pkg_free(pkg);