Radish alpha
H
HardenedBSD Package Manager
Radicle
Git (anonymous pull)
Log in to clone via SSH
libpkg functional with jansson.
jlaffaye committed 15 years ago
commit 55d467660711b180ea04bb039548fda71dae12e0
parent 0c8729567df6ef638ca8c76b43ef0143f9d48cf2
9 files changed +244 -289
modified libpkg/Makefile
@@ -6,13 +6,12 @@ WARNS= 6
SHLIBDIR?=	/usr/lib
SHLIB_MAJOR=	0

-
SRCS=pkg_manifest.c
-
#SRCS=		pkg.c \
-
#		pkgdb.c \
-
#		pkgdb_cache.c \
-
#		pkg_compat.c \
-
#		pkg_manifest.c \
-
#		util.c
+
SRCS=		pkg.c \
+
		pkgdb.c \
+
		pkgdb_cache.c \
+
		pkg_compat.c \
+
		pkg_manifest.c \
+
		util.c

CFLAGS+=	-std=c99
CFLAGS+=	-I${.CURDIR} \
modified libpkg/pkg.c
@@ -1,15 +1,17 @@
-
#include <err.h>
-
#include <stdlib.h>
+
#include <sys/stat.h>
#include <sys/param.h>
+

#include <archive.h>
#include <archive_entry.h>
-
#include <pkgdb.h>
+
#include <err.h>
+
#include <stdlib.h>
#include <glob.h>
-
#include <sys/stat.h>
#include <libgen.h>
#include <string.h>
#include <fcntl.h>
-
#include <cJSON.h>
+

+
#include "pkg_manifest.h"
+
#include "pkgdb.h"
#include "util.h"

#define METADATA_GLOB "+{DEINSTALL,INSTALL,MTREE_DIRS}"
@@ -22,14 +24,14 @@ pkg_create_from_dir(char *path, const char *root, struct archive *pkg_archive)
	struct archive_entry *entry;
	char glob_pattern[MAXPATHLEN + sizeof(METADATA_GLOB)];
	glob_t g;
-
	int fd, j;
+
	int fd;
	size_t len, i = 0;
	char buf[BUFSIZ];
-
	cJSON *manifest, *files, *file;
	char *buffer;
	char manifestpath[MAXPATHLEN], fpath[MAXPATHLEN];
-
	char *filepath;
+
	const char *filepath;
	struct archive *ar;
+
	struct pkg_manifest *m;

	ar = archive_read_disk_new();
	archive_read_disk_set_standard_lookup(ar);
@@ -37,19 +39,8 @@ pkg_create_from_dir(char *path, const char *root, struct archive *pkg_archive)
	snprintf(manifestpath, sizeof(manifestpath), "%s+MANIFEST", path);
	entry = archive_entry_new();

-
	if ((file_to_buffer(manifestpath, &buffer)) == -1) {
-
		/* TODO */
-
		warnx("fail");
-
		return (-1);
-
	}
-

-
	if ((manifest = cJSON_Parse(buffer)) == 0) {
-
		warnx("%s: Manifest corrupted, skipping", manifestpath);
-
		free(buffer);
-
		return (-1);
-
	}
-

-
	free(buffer);
+
	if ((m = pkg_manifest_load_file(manifestpath)) == NULL)
+
		errx(EXIT_FAILURE, "Can not continue without manifest");

	/* Add the metadatas */
	snprintf(glob_pattern, sizeof(glob_pattern), "%s"METADATA_GLOB, path);
@@ -72,9 +63,9 @@ pkg_create_from_dir(char *path, const char *root, struct archive *pkg_archive)
		}
	}
	globfree(&g);
-
	cJSON_DeleteItemFromObject(manifest, "automatic");

-
	buffer = cJSON_Print(manifest);
+
	/* TODO: remove automatic */
+
	buffer = pkg_manifest_dump_buffer(m);

	archive_entry_copy_sourcepath(entry, manifestpath);
	if (archive_read_disk_entry_from_file(ar, entry, -1, 0) != ARCHIVE_OK)
@@ -88,11 +79,9 @@ pkg_create_from_dir(char *path, const char *root, struct archive *pkg_archive)

	free(buffer);

-
	files = cJSON_GetObjectItem(manifest, "files");
-

-
	for (j = 0; j < cJSON_GetArraySize(files); j++) {
-
		file = cJSON_GetArrayItem(files, j);
-
		filepath = cJSON_GetObjectItem(file, "path")->valuestring;
+
	pkg_manifest_file_init(m);
+
	while (pkg_manifest_file_next(m) == 0) {
+
		filepath = pkg_manifest_file_path(m);
		snprintf(fpath, sizeof(MAXPATHLEN), "%s/%s", root, filepath);
		archive_entry_copy_sourcepath(entry, filepath);

@@ -111,7 +100,7 @@ pkg_create_from_dir(char *path, const char *root, struct archive *pkg_archive)
		archive_entry_clear(entry);
	}

-
	cJSON_Delete(manifest);
+
	pkg_manifest_free(m);
	archive_entry_free(entry);
	archive_read_finish(ar);

modified libpkg/pkg_compat.c
@@ -1,14 +1,16 @@
+
#include <sys/param.h>
+
#include <sys/stat.h>
+
#include <sys/utsname.h>
+

#include <ctype.h>
#include <err.h>
#include <stdlib.h>
#include <string.h>
#include <libgen.h>
-
#include <sys/param.h>
-
#include <sys/stat.h>
-
#include <sys/utsname.h>

#include "util.h"
#include "pkg_compat.h"
+
#include "pkg_manifest.h"

static struct {
	const char *key;
@@ -94,7 +96,7 @@ pkg_compat_plist_cmd(char *s, char **arg)
}

static void
-
pkg_compat_read_plist(cJSON *pkg, char *plist_str)
+
pkg_compat_read_plist(struct pkg_manifest *m, char *plist_str)
{
	int cmd;
	char *buf, *next, *cp = NULL;
@@ -103,7 +105,6 @@ pkg_compat_read_plist(cJSON *pkg, char *plist_str)
	char *dep = NULL;
	char *prefix = NULL;
	char path_file[MAXPATHLEN];
-
	cJSON *object;

	buf = plist_str;
	while ((next = strchr(buf, '\n')) != NULL) {
@@ -133,12 +134,12 @@ pkg_compat_read_plist(cJSON *pkg, char *plist_str)
				tmp = strrchr(cp, '-');
				tmp[0] = '\0';
				tmp++;
-
				cJSON_AddStringToObject(pkg, "name", cp);
-
				cJSON_AddStringToObject(pkg, "version", tmp);
+
				pkg_manifest_add_value(m, "name", cp);
+
				pkg_manifest_add_value(m, "version", tmp);
				break;

			case PLIST_ORIGIN:
-
				cJSON_AddStringToObject(pkg, "origin", cp);
+
				pkg_manifest_add_value(m, "origin", cp);
				break;

			case PLIST_CWD:
@@ -152,21 +153,18 @@ pkg_compat_read_plist(cJSON *pkg, char *plist_str)
				break;

			case PLIST_MD5:
-
				object = cJSON_CreateObject();
-
				cJSON_AddStringToObject(object, "path", path_file);
-
				cJSON_AddStringToObject(object, "md5", cp);
-
				cJSON_AddItemToArray(cJSON_GetObjectItem(pkg, "files"), object);
+
				pkg_manifest_add_file(m, path_file, cp);
				break;

			case PLIST_CMD:
				tmp = str_replace(cp, "\%D", prefix);
-
				cJSON_AddItemToArray(cJSON_GetObjectItem(pkg, "exec"), cJSON_CreateString(tmp));
+
				pkg_manifest_add_exec(m, tmp);
				free(tmp);
				break;

			case PLIST_UNEXEC:
				tmp = str_replace(cp, "\%D", prefix);
-
				cJSON_AddItemToArray(cJSON_GetObjectItem(pkg, "unexec"), cJSON_CreateString(tmp));
+
				pkg_manifest_add_unexec(m, tmp);
				free(tmp);
				break;

@@ -177,15 +175,11 @@ pkg_compat_read_plist(cJSON *pkg, char *plist_str)
				tmp = strrchr(dep, '-');
				tmp[0] = '\0';
				tmp++;
-
				object = cJSON_CreateObject();
-
				cJSON_AddStringToObject(object, "name", dep);
-
				cJSON_AddStringToObject(object, "origin", cp);
-
				cJSON_AddStringToObject(object, "version", tmp);
-
				cJSON_AddItemToArray(cJSON_GetObjectItem(pkg, "deps"), object);
+
				pkg_manifest_add_dep(m, dep, cp, tmp);
				break;

			case PLIST_CONFLICTS:
-
				cJSON_AddItemToArray(cJSON_GetObjectItem(pkg, "conflicts"), cJSON_CreateString(cp));
+
				pkg_manifest_add_conflict(m, cp);
				break;

			case PLIST_MTREE:
@@ -205,64 +199,55 @@ pkg_compat_read_plist(cJSON *pkg, char *plist_str)
	}
}

-
cJSON *
+
struct pkg_manifest *
pkg_compat_converter(char *plist_str)
{
+
	struct pkg_manifest *m;
	struct utsname uts;
	char *osrelease;
	char *tmp;

-
	cJSON *rootpkg = cJSON_CreateObject();
+
	m = pkg_manifest_new();
	uname(&uts);
	
-
	cJSON_AddStringToObject(rootpkg, "arch", uts.machine);
+
	pkg_manifest_add_value(m, "arch", uts.machine);

	osrelease = strdup(uts.release);
	tmp = strrchr(osrelease, '-');
	tmp[0] = '\0';

-
	cJSON_AddStringToObject(rootpkg, "osrelease", osrelease);
+
	pkg_manifest_add_value(m, "osrelease", osrelease);
	free(osrelease);

-
	cJSON_AddNumberToObject(rootpkg, "osversion", __FreeBSD_version);
-
	cJSON_AddFalseToObject(rootpkg, "automatic");
-
	cJSON_AddItemToObject(rootpkg, "files", cJSON_CreateArray());
-
	cJSON_AddItemToObject(rootpkg, "exec", cJSON_CreateArray());
-
	cJSON_AddItemToObject(rootpkg, "unexec", cJSON_CreateArray());
-
	cJSON_AddItemToObject(rootpkg, "options", cJSON_CreateArray());
-
	cJSON_AddItemToObject(rootpkg, "conflicts", cJSON_CreateArray());
-
	cJSON_AddItemToObject(rootpkg, "deps", cJSON_CreateArray());
+
	/* TODO
+
	pkg_manifest_add_value(m, "osversion", __FreeBSD_version);
+
	pkg_manifest_add_value(m, "automatic");
+
	*/

-
	pkg_compat_read_plist(rootpkg, plist_str);
+
	pkg_compat_read_plist(m, plist_str);

-
	return (rootpkg);
+
	return (m);
}

-
cJSON *
-
pkg_compat_convert_installed(const char *pkg_dbdir, char *pkgname, char *manifestpath)
+
struct pkg_manifest *
+
pkg_compat_convert_installed(const char *pkg_dbdir, char *pkgname, char *mpath)
{
-
	cJSON *rootpkg;
-
	char *cjson_output;
-
	FILE *fs;
+
	struct pkg_manifest *m;
	char *buffer;
	off_t buffer_len;
	char filepath[MAXPATHLEN];

	snprintf(filepath, sizeof(filepath), "%s/%s/+CONTENTS", pkg_dbdir, pkgname);

-
	rootpkg = cJSON_CreateObject();
-

-
	if ((file_to_buffer(filepath, &buffer)) == -1) {
-
		warn("Unable to read +CONTENTS for %s", pkgname);
-
		return (0);
+
	if ((buffer_len = file_to_buffer(filepath, &buffer)) == -1) {
+
		warnx("can not read %s", filepath);
+
		return (NULL);
	}
-

-
	rootpkg = pkg_compat_converter(buffer);
+
	m = pkg_compat_converter(buffer);
	free(buffer);
-

-
	if (rootpkg == 0) {
+
	if (m == NULL) {
		warnx("%s: Manifest corrupted, skipping", pkgname);
-
		return (0);
+
		return (NULL);
	}

	/* adding comment */
@@ -274,7 +259,7 @@ pkg_compat_convert_installed(const char *pkg_dbdir, char *pkgname, char *manifes
		if (buffer[buffer_len - 1 ] == '\n')
			buffer[buffer_len -1 ] = '\0';

-
		cJSON_AddStringToObject(rootpkg, "comment", buffer);
+
		pkg_manifest_add_value(m, "comment", buffer);
		free(buffer);
	}

@@ -284,25 +269,20 @@ pkg_compat_convert_installed(const char *pkg_dbdir, char *pkgname, char *manifes
	if ((buffer_len = file_to_buffer(filepath, &buffer)) == -1) {
		warn("Unable to read +DESC for %s", pkgname);
	} else {
-
		cJSON_AddStringToObject(rootpkg, "desc", buffer);
+
		pkg_manifest_add_value(m, "desc", buffer);
		free(buffer);
	}

-

	/* adding display */
	snprintf(filepath, sizeof(filepath), "%s/+DISPLAY", dirname(filepath));
	/* ignore if no +DISPLAY */
	if ((buffer_len = file_to_buffer(filepath, &buffer)) != -1) {
-
		cJSON_AddStringToObject(rootpkg, "display", buffer);
+
		pkg_manifest_add_value(m, "display", buffer);
		free(buffer);
	}

	/* write the new manifest */
-
	cjson_output = cJSON_Print(rootpkg);
-
	fs = fopen(manifestpath, "w+");
-
	fprintf(fs, "%s", cjson_output);
-
	free(cjson_output);
-
	fclose(fs);
+
	pkg_manifest_dump_file(m, mpath);

-
	return (rootpkg);
+
	return (m);
}
modified libpkg/pkg_compat.h
@@ -3,7 +3,8 @@

#include <stdbool.h>
#include <stdio.h>
-
#include <cJSON.h>
+

+
#include "pkg_manifest.h"

enum plist_t {
	PLIST_FILE, PLIST_CWD, PLIST_CMD, PLIST_CHMOD,
@@ -30,7 +31,7 @@ struct oldpackage {

};

-
cJSON *pkg_compat_converter(char *);
-
cJSON *pkg_compat_convert_installed(const char *, char *, char *);
+
struct pkg_manifest *pkg_compat_converter(char *);
+
struct pkg_manifest *pkg_compat_convert_installed(const char *, char *, char *);

#endif
modified libpkg/pkg_manifest.c
@@ -8,6 +8,33 @@
#include "pkg.h"
#include "pkg_manifest.h"

+
enum array_type {
+
	ARRAY_FILES,
+
	ARRAY_DEPS,
+
	ARRAY_CONFLICTS,
+
	ARRAY_EXEC,
+
	ARRAY_UNEXEC
+
};
+

+
struct pkg_manifest_array {
+
	json_t *node;
+
	json_t *elm;
+
	unsigned int size;
+
	unsigned int idx;
+
	enum array_type type;
+
};
+

+
struct pkg_manifest {
+
	json_t *json;
+
	struct pkg_manifest_array array;
+
};
+

+
/* Helpers */
+
const char * pkg_manifest_keystr(json_t *, const char *);
+
void pkg_manifest_array_init(struct pkg_manifest *, enum array_type);
+
const char * pkg_manifest_simplenext(struct pkg_manifest *, enum array_type,
+
									 const char *);
+

const char *
pkg_manifest_keystr(json_t *root, const char *key)
{
@@ -29,6 +56,29 @@ pkg_manifest_array_init(struct pkg_manifest *m, enum array_type t)
	m->array.type = t;
}

+
const char *
+
pkg_manifest_simplenext(struct pkg_manifest *m, enum array_type t, const char *key)
+
{
+
	assert(m->array.type == t);
+

+
	/* First call */
+
	if (m->array.node == NULL) {
+
		if ((m->array.node = json_object_get(m->json, key)) == NULL)
+
			return (NULL);
+
		m->array.size = json_array_size(m->array.node);
+
	}
+

+
	if (m->array.idx >= m->array.size)
+
		return (NULL);
+

+
	if ((m->array.elm = json_array_get(m->array.node, m->array.idx)) == NULL)
+
		return (NULL);
+

+
	m->array.idx++;
+

+
	return json_string_value(m->array.elm);
+
}
+

/*
 * Simple accesser for string value at the root of the JSON node
 */
@@ -169,6 +219,18 @@ pkg_manifest_dep_version(struct pkg_manifest *m)
}

void
+
pkg_manifest_conflict_init(struct pkg_manifest *m)
+
{
+
	pkg_manifest_array_init(m, ARRAY_CONFLICTS);
+
}
+

+
const char *
+
pkg_manifest_conflict_next(struct pkg_manifest *m)
+
{
+
	return pkg_manifest_simplenext(m, ARRAY_CONFLICTS, "conflicts");
+
}
+

+
void
pkg_manifest_exec_init(struct pkg_manifest *m)
{
	pkg_manifest_array_init(m, ARRAY_EXEC);
@@ -177,24 +239,7 @@ pkg_manifest_exec_init(struct pkg_manifest *m)
const char *
pkg_manifest_exec_next(struct pkg_manifest *m)
{
-
	assert(m->array.type == ARRAY_EXEC);
-

-
	/* First call */
-
	if (m->array.node == NULL) {
-
		if ((m->array.node = json_object_get(m->json, "exec")) == NULL)
-
			return (NULL);
-
		m->array.size = json_array_size(m->array.node);
-
	}
-

-
	if (m->array.idx >= m->array.size)
-
		return (NULL);
-

-
	if ((m->array.elm = json_array_get(m->array.node, m->array.idx)) == NULL)
-
		return (NULL);
-

-
	m->array.idx++;
-

-
	return json_string_value(m->array.elm);
+
	return pkg_manifest_simplenext(m, ARRAY_EXEC, "exec");
}

void
@@ -206,24 +251,7 @@ pkg_manifest_unexec_init(struct pkg_manifest *m)
const char *
pkg_manifest_unexec_next(struct pkg_manifest *m)
{
-
	assert(m->array.type == ARRAY_UNEXEC);
-

-
	/* First call */
-
	if (m->array.node == NULL) {
-
		if ((m->array.node = json_object_get(m->json, "unexec")) == NULL)
-
			return (NULL);
-
		m->array.size = json_array_size(m->array.node);
-
	}
-

-
	if (m->array.idx >= m->array.size)
-
		return (NULL);
-

-
	if ((m->array.elm = json_array_get(m->array.node, m->array.idx)) == NULL)
-
		return (NULL);
-

-
	m->array.idx++;
-

-
	return json_string_value(m->array.elm);
+
	return pkg_manifest_simplenext(m, ARRAY_UNEXEC, "unexec");
}

/* Setters */
@@ -273,6 +301,19 @@ pkg_manifest_add_dep(struct pkg_manifest *m, const char *name, const char *origi
}

void
+
pkg_manifest_add_conflict(struct pkg_manifest *m, const char *value)
+
{
+
	json_t *array;
+

+
	if ((array = json_object_get(m->json, "conflicts")) == NULL) {
+
		array = json_array();
+
		json_object_set_new(m->json, "conflicts", array);
+
	}
+

+
	json_array_append_new(array, json_string(value));
+
}
+

+
void
pkg_manifest_add_exec(struct pkg_manifest *m, const char *value)
{
	json_t *array;
@@ -298,40 +339,63 @@ pkg_manifest_add_unexec(struct pkg_manifest *m, const char *value)
	json_array_append_new(array, json_string(value));
}

-
int
-
pkg_manifest_loadb(struct pkg_manifest *m, const char *buffer)
+
struct pkg_manifest *
+
pkg_manifest_new(void)
+
{
+
	struct pkg_manifest *m;
+

+
	if ((m = malloc(sizeof(struct pkg_manifest))) == NULL)
+
		err(EXIT_FAILURE, "malloc()");
+

+
	m->json = json_object();
+

+
	return (m);
+
}
+

+
struct pkg_manifest *
+
pkg_manifest_load_buffer(const char *buffer)
{
+
	struct pkg_manifest *m;
	json_error_t error;

+
	if ((m = malloc(sizeof(struct pkg_manifest))) == NULL)
+
		err(EXIT_FAILURE, "malloc()");
+

	if ((m->json = json_loads(buffer, &error)) == NULL) {
		warnx("Can not parse buffer as JSON: %s", error.text);
-
		return (-1);
+
		free(m);
+
		return (NULL);
	}

-
	return (0);
+
	return (m);
}

-
int
-
pkg_manifest_loadp(struct pkg_manifest *m, const char *path)
+
struct pkg_manifest *
+
pkg_manifest_load_file(const char *path)
{
+
	struct pkg_manifest *m;
	json_error_t error;

+
	if ((m = malloc(sizeof(struct pkg_manifest))) == NULL)
+
		err(EXIT_FAILURE, "malloc()");
+

	if ((m->json = json_load_file(path, &error)) == NULL) {
		warnx("Can not parse %s: %s", path, error.text);
-
		return (-1);
+
		free(m);
+
		return (NULL);
	}

-
	return (0);
+
	return (m);
}

char *
-
pkg_manifest_dumpb(struct pkg_manifest *m)
+
pkg_manifest_dump_buffer(struct pkg_manifest *m)
{
	return json_dumps(m->json, JSON_COMPACT);
}

int
-
pkg_manifest_dumpp(struct pkg_manifest *m, const char *path)
+
pkg_manifest_dump_file(struct pkg_manifest *m, const char *path)
{
	return json_dump_file(m->json, path, JSON_INDENT(2));
}
modified libpkg/pkg_manifest.h
@@ -3,33 +3,15 @@

#include <stdbool.h>

-
#include <jansson.h>
-

-
enum array_type {
-
	ARRAY_FILES,
-
	ARRAY_DEPS,
-
	ARRAY_EXEC,
-
	ARRAY_UNEXEC
-
};
-

-
struct pkg_manifest_array {
-
	json_t *node;
-
	json_t *elm;
-
	unsigned int size;
-
	unsigned int idx;
-
	enum array_type type;
-
};
-

-
struct pkg_manifest {
-
	json_t *json;
-
	struct pkg_manifest_array array;
-
};
+
/* Opaque struct */
+
struct pkg_manifest;

/* Parser/Emitter */
-
int pkg_manifest_loadb(struct pkg_manifest *, const char *);
-
int pkg_manifest_loadp(struct pkg_manifest *, const char *);
-
char * pkg_manifest_dumpb(struct pkg_manifest *);
-
int pkg_manifest_dumpp(struct pkg_manifest *, const char *);
+
struct pkg_manifest * pkg_manifest_new(void);
+
struct pkg_manifest * pkg_manifest_load_buffer(const char *);
+
struct pkg_manifest * pkg_manifest_load_file(const char *);
+
char * pkg_manifest_dump_buffer(struct pkg_manifest *);
+
int pkg_manifest_dump_file(struct pkg_manifest *, const char *);
void pkg_manifest_free(struct pkg_manifest *);

/* Getter */
@@ -47,6 +29,9 @@ const char * pkg_manifest_dep_name(struct pkg_manifest *);
const char * pkg_manifest_dep_origin(struct pkg_manifest *);
const char * pkg_manifest_dep_version(struct pkg_manifest *);

+
void pkg_manifest_conflict_init(struct pkg_manifest *);
+
const char * pkg_manifest_conflict_next(struct pkg_manifest *);
+

void pkg_manifest_exec_init(struct pkg_manifest *);
const char * pkg_manifest_exec_next(struct pkg_manifest *);

@@ -57,10 +42,8 @@ const char * pkg_manifest_unexec_next(struct pkg_manifest *);
void pkg_manifest_add_value(struct pkg_manifest *, const char *, const char *);
void pkg_manifest_add_file(struct pkg_manifest *, const char *, const char *);
void pkg_manifest_add_dep(struct pkg_manifest *, const char *, const char *, const char *);
+
void pkg_manifest_add_conflict(struct pkg_manifest *, const char *);
void pkg_manifest_add_exec(struct pkg_manifest *, const char *);
void pkg_manifest_add_unexec(struct pkg_manifest *, const char *);

-
/* Helper */
-
const char * pkg_manifest_keystr(json_t *, const char *);
-
void pkg_manifest_array_init(struct pkg_manifest *, enum array_type);
#endif
modified libpkg/pkgdb.c
@@ -15,9 +15,8 @@

/* theses functions request on local database (cdb) */
static int pkg_db_open(struct pkgdb *);
-
static void pkg_db_init(struct pkg *);
+
static void pkg_reset(struct pkg *);
static const void *pkg_db_query(struct cdb *, const char *, ...);
-
static const char *pkg_db_namever(struct pkg *);
static const char *pkg_db_getattr(struct pkg *, const char *);
static int pkg_db_dep(struct pkg *, struct pkg *);

@@ -25,7 +24,7 @@ const char *
pkg_namever(struct pkg *pkg)
{
	if (pkg->namever == NULL)
-
		pkg->namever = pkg_db_namever(pkg);
+
		pkg->namever = pkg_db_getattr(pkg, PKGDB_NAMEVER);
	return (pkg->namever);
}

@@ -76,7 +75,7 @@ pkg_dep(struct pkg *pkg, struct pkg *dep)
}

static void
-
pkg_db_init(struct pkg *pkg)
+
pkg_reset(struct pkg *pkg)
{
	pkg->namever = NULL;
	pkg->name = NULL;
@@ -90,14 +89,13 @@ pkg_db_init(struct pkg *pkg)
	pkg->db = NULL;
}

-

static int
pkg_db_dep(struct pkg *pkg, struct pkg *dep)
{
	const size_t *idx;
	int ret = -1;

-
	pkg_db_init(dep);
+
	pkg_reset(dep);

	if ((dep->namever = pkg_db_query(pkg->db, PKGDB_DEPS, pkg->idx, pkg->idep)) != NULL &&
			(idx = pkg_db_query(pkg->db, "%s", dep->namever)) != NULL) {
@@ -138,15 +136,6 @@ pkg_db_query(struct cdb *db, const char *fmt, ...)
}

static const char *
-
pkg_db_namever(struct pkg *pkg)
-
{
-
	pkg->namever = NULL;
-
	if (cdb_find(pkg->db, &pkg->idx, sizeof(pkg->idx)) > 0)
-
		db_get(pkg->namever, pkg->db);
-
	return (pkg->namever);
-
}
-

-
static const char *
pkg_db_getattr(struct pkg *pkg, const char *attr)
{
	return (pkg_db_query(pkg->db, attr, pkg->idx));
@@ -276,31 +265,23 @@ pkgdb_match(struct pkgdb *db, const char *pattern)
	return (matched);
}

-

-

int
pkgdb_query(struct pkgdb *db, struct pkg *pkg)
{
-
	int ret = -1;
-

-
	pkg_db_init(pkg);
-

+
	pkg_reset(pkg);
	pkgdb_lock(db, 0);

-
	while (cdb_find(&db->db, &db->i, sizeof(db->i)) > 0) {
-
		db_get(pkg->namever, &db->db);
-

+
	while ((pkg->namever = pkg_db_query(&db->db, PKGDB_NAMEVER, db->i)) != NULL) {
		if (pkg->namever != NULL && pkgdb_match(db, pkg->namever) == 0) {
			pkg->idx = db->i++;
			pkg->db = &db->db;
-
			ret = 0;
-
			break;
+
			return (0);
		}

		db->i++;
	}
	pkgdb_unlock(db);

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

modified libpkg/pkgdb.h
@@ -4,6 +4,7 @@

#define PKG_DBDIR "/var/db/pkg"
#define PKGDB_LOCK "lock"
+
#define PKGDB_NAMEVER "%zunv"
#define PKGDB_NAME    "%zun"
#define PKGDB_VERSION "%zuv"
#define PKGDB_COMMENT "%zuc"
modified libpkg/pkgdb_cache.c
@@ -9,11 +9,11 @@
#include <unistd.h>

#include <cdb.h>
-
#include <cJSON.h>

#include "util.h"
#include "pkgdb.h"
#include "pkg_compat.h"
+
#include "pkg_manifest.h"
#include "pkgdb_cache.h"

/* add record formated string */
@@ -67,68 +67,25 @@ pkgdb_add_string(struct cdb_make *db, const char *val, const char *fmt, ...)
	return (ret);
}

-
static char*cJSON_GetString(cJSON*j,const char *k){/*cJSON style*/cJSON*n;if((n=cJSON_GetObjectItem(j,k)))return n->valuestring;return NULL;}
-

-
static struct pkg *
-
pkg_from_manifest(const char *pkg_dbdir, char *pkgname)
+
static int
+
pkgdb_add_int(struct cdb_make *db, const char *key, size_t val)
{
-
	cJSON *manifest;
-
	char manifestpath[MAXPATHLEN];
-
	char *buffer;
-
	struct pkg *pkg;
-

-
	snprintf(manifestpath, sizeof(manifestpath), "%s/%s/+MANIFEST", pkg_dbdir, pkgname);
-

-
	if ((file_to_buffer(manifestpath, &buffer)) == -1) {
-

-
		warnx("An error occured while trying to read "
-
				"+MANIFEST for %s, falling back to old "
-
				"+CONTENTS format", pkgname);
-

-
		manifest = pkg_compat_convert_installed( pkg_dbdir, pkgname,
-
				manifestpath);
-
	}
-
	else {
-
		manifest = cJSON_Parse(buffer);
-
		free(buffer);
-
	}
-

-
	if (manifest == NULL) {
-
		warnx("%s: Manifest corrputed, skipping", pkgname);
-
		return NULL;
-
	}
-

-
	pkg = calloc(1, sizeof(*pkg));
-
	pkg->name = cJSON_GetString(manifest, "name");
-
	pkg->version = cJSON_GetString(manifest, "version");
-
	pkg->comment = cJSON_GetString(manifest, "comment");
-
	pkg->origin = cJSON_GetString(manifest, "origin");
-

-
	if (pkg->name == NULL || pkg->version == NULL ||
-
			pkg->comment == NULL || pkg->origin == NULL) {
-
		free(pkg);
-
		pkg = NULL;
-
		cJSON_Delete(manifest);
-
	}
-
	else {
-
		pkg->desc = cJSON_GetString(manifest, "desc");
-
		pkg->manifest = manifest;
-
	}
-
	return (pkg);
+
	return cdb_make_add(db, key, strlen(key), &val, sizeof(size_t));
}

-

static void
pkgdb_cache_rebuild(const char *pkg_dbdir, const char *cache_path)
{
	int fd;
-
	char tmppath[MAXPATHLEN], namever[FILENAME_MAX];
-
	struct cdb_make cdb_make;
+
	char tmppath[MAXPATHLEN];
+
	char mpath[MAXPATHLEN];
+
	char namever[FILENAME_MAX];
+
	struct cdb_make cdb;
	DIR *dir;
	struct dirent *portsdir;
-
	struct pkg *pkg;
-
	size_t idx = 0, idep, array_size;
-
	cJSON *node, *array;
+
	size_t idx;
+
	size_t idep;
+
	struct pkg_manifest *m;

	snprintf(tmppath, sizeof(tmppath), "%s/pkgdb.cache-XXXXX", pkg_dbdir);

@@ -137,10 +94,10 @@ pkgdb_cache_rebuild(const char *pkg_dbdir, const char *cache_path)

	warnx("Rebuilding cache...");

-
	cdb_make_start(&cdb_make, fd);
+
	cdb_make_start(&cdb, fd);

	/* Now go through pkg_dbdir rebuild the cache */
-

+
	idx = 0;
	if ((dir = opendir(pkg_dbdir)) != NULL) {
		while ((portsdir = readdir(dir)) != NULL) {
			if (strcmp(portsdir->d_name, ".") != 0 &&
@@ -149,41 +106,41 @@ pkgdb_cache_rebuild(const char *pkg_dbdir, const char *cache_path)
				if (portsdir->d_type != DT_DIR)
					continue;

-
				pkg = pkg_from_manifest(pkg_dbdir, portsdir->d_name);
-

-
				if (pkg == NULL)
-
					continue;
-

-
				snprintf(namever, sizeof(namever), "%s-%s", pkg->name, pkg->version);
-
				/* index -> namever */
-
				cdb_make_add(&cdb_make, &idx, sizeof(idx), namever, strlen(namever)+1);
-
				/* namever -> index */
-
				cdb_make_add(&cdb_make, namever, strlen(namever), &idx, sizeof(idx));
-
				/* name -> index */
-
				cdb_make_add(&cdb_make, pkg->name, strlen(pkg->name), &idx, sizeof(idx));
-
				pkgdb_add_string(&cdb_make, pkg->name, PKGDB_NAME, idx);
-
				pkgdb_add_string(&cdb_make, pkg->version, PKGDB_VERSION, idx);
-
				pkgdb_add_string(&cdb_make, pkg->comment, PKGDB_COMMENT, idx);
-
				pkgdb_add_string(&cdb_make, pkg->origin, PKGDB_ORIGIN, idx);
-
				pkgdb_add_string(&cdb_make, pkg->desc, PKGDB_DESC, idx);
-

-
				array = cJSON_GetObjectItem(pkg->manifest, "deps");
-

-
				if (array && (array_size = cJSON_GetArraySize(array)) > 0) {
-
					for (idep = 0; idep < array_size; idep++) {
-
						if ((node = cJSON_GetArrayItem(array, idep)) != NULL) {
-
							pkg->name = cJSON_GetString(node, "name");
-
							pkg->version = cJSON_GetString(node, "version");
-
							if (pkg->name != NULL && pkg->version != NULL) {
-
								snprintf(namever, sizeof(namever), "%s-%s", pkg->name, pkg->version);
-
								pkgdb_add_string(&cdb_make, namever, PKGDB_DEPS, idx, idep);
-
							}
-
						}
+
				snprintf(mpath, sizeof(mpath), "%s/%s/+MANIFEST", pkg_dbdir,
+
					 	 portsdir->d_name);
+
				if ((m = pkg_manifest_load_file(mpath)) == NULL) {
+
					warnx("%s not found, converting old +CONTENTS file", mpath);
+
					if ((m = pkg_compat_convert_installed(pkg_dbdir, portsdir->d_name, mpath))
+
						== NULL) {
+
						warnx("error while converting, skipping");
+
						continue;
					}
+
warnx("CONVERTED!!!");
+
				}
+

+
				snprintf(namever, sizeof(namever), "%s-%s", pkg_manifest_value(m, "name"),
+
						 pkg_manifest_value(m, "version"));
+

+
				pkgdb_add_int(&cdb, namever, idx);
+
				pkgdb_add_int(&cdb, pkg_manifest_value(m, "name"), idx);
+

+
				pkgdb_add_string(&cdb, namever, PKGDB_NAMEVER, idx);
+
				pkgdb_add_string(&cdb, pkg_manifest_value(m, "name"), PKGDB_NAME, idx);
+
				pkgdb_add_string(&cdb, pkg_manifest_value(m, "version"), PKGDB_VERSION, idx);
+
				pkgdb_add_string(&cdb, pkg_manifest_value(m, "comment"), PKGDB_COMMENT, idx);
+
				pkgdb_add_string(&cdb, pkg_manifest_value(m, "origin"), PKGDB_ORIGIN, idx);
+
				pkgdb_add_string(&cdb, pkg_manifest_value(m, "desc"), PKGDB_DESC, idx);
+

+
				idep = 0;
+
				pkg_manifest_dep_init(m);
+
				while (pkg_manifest_dep_next(m) == 0) {
+
					snprintf(namever, sizeof(namever), "%s-%s", pkg_manifest_dep_name(m),
+
							 pkg_manifest_dep_version(m));
+
					pkgdb_add_string(&cdb, namever, PKGDB_DEPS, idx, idep);
+
					idep++;
				}

-
				cJSON_Delete(pkg->manifest);
-
				free(pkg);
+
				pkg_manifest_free(m);
				idx++;
			}
		}
@@ -191,8 +148,8 @@ pkgdb_cache_rebuild(const char *pkg_dbdir, const char *cache_path)
	}

	/* record packages len */
-
	cdb_make_add(&cdb_make, PKGDB_COUNT, strlen(PKGDB_COUNT), &idx, sizeof(idx));
-
	cdb_make_finish(&cdb_make);
+
	cdb_make_add(&cdb, PKGDB_COUNT, strlen(PKGDB_COUNT), &idx, sizeof(idx));
+
	cdb_make_finish(&cdb);
	close(fd);
	rename(tmppath, cache_path);
	chmod(cache_path, 0644);