Radish alpha
H
HardenedBSD Package Manager
Radicle
Git (anonymous pull)
Log in to clone via SSH
Merge branch 'master' into jansson
jlaffaye committed 15 years ago
commit 0c8729567df6ef638ca8c76b43ef0143f9d48cf2
parent 6fcc033a07d222c656d46337b3329651ce939d30
8 files changed +286 -418
modified docs/sample_manifest.json
@@ -10,11 +10,11 @@
    "comment": "Foo does bar very well!",
    "desc": "Foo is a nice software\n\nWWW:\thttp://www.foo-bar.org",
    "license": "ISC",
-
    "automatic": false,
-
    "options": [
-
        "WITH_FOO": true,
-
        "WITH_BAR": false
-
    ],
+
    "automatic": false, // true if installed to satisfy a dep, only exist in the local manifest
+
    "options": {
+
        "FOO": true,
+
        "BAR": false
+
    },
    "deps": [
        {
            "name": "gettext",
deleted external/jansson/bench.c
@@ -1,23 +0,0 @@
-
#include <stdlib.h>
-
#include <stdio.h>
-
#include "jansson.h"
-

-
int
-
main()
-
{
-
	void *m;
-
	json_t *j;
-
	json_t *n;
-
	json_error_t e;
-
m = malloc(1024);
-
	printf("Reading...");
-
	j = json_load_file("/var/db/pkg/ruby-1.8.7.248_4,1/+MANIFEST", &e);
-
	printf(" done!\n");
-
	if (j == NULL)
-
		printf("%s\n", e.text);	
-
	else {
-
		n = json_object_get(j, "name");
-
		printf("Name=%s\n", json_string_value(n));
-
		json_decref(j);
-
	}	
-
}
modified libpkg/pkg.c
@@ -122,7 +122,7 @@ int
pkg_create(char *pkgname, pkg_formats format, const char *outdir, const char *rootdir)
{
	struct pkgdb db;
-
	struct pkg *pkg;
+
	struct pkg pkg;
	const char *pkg_dbdir;
	char pkgpath[MAXPATHLEN];
	struct archive *pkg_archive;
@@ -150,44 +150,42 @@ pkg_create(char *pkgname, pkg_formats format, const char *outdir, const char *ro

	pkg_dbdir = pkgdb_get_dir();

-
	pkgdb_init(&db, pkgname, MATCH_EXACT, 0);
+
	pkgdb_init(&db, pkgname, MATCH_EXACT);

-
	if (pkgdb_count(&db) == 0) {
+
	if (pkgdb_query(&db, &pkg) != 0) {
		warnx("%s: no such package", pkgname);
		return (-1);
	}

-
	PKGDB_FOREACH(pkg, &db) {
-
		printf("Creating package %s/%s.%s\n", outdir, pkg->name_version, ext);
-
		snprintf(pkgpath, sizeof(pkgpath), "%s/%s/", pkg_dbdir, pkg->name_version);
-
		snprintf(archive_path, sizeof(archive_path), "%s/%s.%s", outdir, pkg->name_version, ext);
-

-
		pkg_archive = archive_write_new();
-

-
		switch (format) {
-
			case TAR:
-
				archive_write_set_compression_none(pkg_archive);
-
				break;
-
			case TGZ:
-
				archive_write_set_compression_gzip(pkg_archive);
-
				break;
-
			case TBZ:
-
				archive_write_set_compression_bzip2(pkg_archive);
-
				break;
-
			case TXZ:
-
				if (archive_write_set_compression_lzma(pkg_archive) != ARCHIVE_OK) {
-
					warnx(archive_error_string(pkg_archive));
-
				}
-
				break;
-
		}
+
	printf("Creating package %s/%s.%s\n", outdir, pkg_namever(&pkg), ext);
+
	snprintf(pkgpath, sizeof(pkgpath), "%s/%s/", pkg_dbdir, pkg_namever(&pkg));
+
	snprintf(archive_path, sizeof(archive_path), "%s/%s.%s", outdir, pkg_namever(&pkg), ext);
+

+
	pkg_archive = archive_write_new();

-
		archive_write_set_format_pax_restricted(pkg_archive);
-
		archive_write_open_filename(pkg_archive, archive_path);
-
		pkg_create_from_dir(pkgpath, rootdir, pkg_archive);
-
		archive_write_close(pkg_archive);
-
		archive_write_finish(pkg_archive);
+
	switch (format) {
+
		case TAR:
+
			archive_write_set_compression_none(pkg_archive);
+
			break;
+
		case TGZ:
+
			archive_write_set_compression_gzip(pkg_archive);
+
			break;
+
		case TBZ:
+
			archive_write_set_compression_bzip2(pkg_archive);
+
			break;
+
		case TXZ:
+
			if (archive_write_set_compression_lzma(pkg_archive) != ARCHIVE_OK) {
+
				warnx(archive_error_string(pkg_archive));
+
			}
+
			break;
	}

+
	archive_write_set_format_pax_restricted(pkg_archive);
+
	archive_write_open_filename(pkg_archive, archive_path);
+
	pkg_create_from_dir(pkgpath, rootdir, pkg_archive);
+
	archive_write_close(pkg_archive);
+
	archive_write_finish(pkg_archive);
+

	pkgdb_free(&db);
	return (0);
}
modified libpkg/pkg.h
@@ -3,40 +3,40 @@

#include <cdb.h>
#include <stdio.h> /* for size_t */
-
#include <sys/time.h> /* for time_t */
-

-
#define PKGERR_NOT_INSTALLED    (1<<0) /* dep not register (partial pkg with only name_version set */
-
#define PKGERR_VERSION_MISMATCH (1<<1) /* dep_version != require version */
+
#include <regex.h> /* regex_t */

struct pkg {
-
	const char *name_version;
+
	const char *namever;
	const char *name;
	const char *version;
	const char *origin;
	const char *comment;
	const char *desc;
-
	struct pkg **deps; /* null-terminated */
-
	struct pkg **rdeps; /* null-terminated */
-
	unsigned char errors; /* PKGERR_* */
	size_t idx; /* index on pkgdb */
-
	void *manifest;
+
	size_t idep; /* iterator deps */
+
	size_t irdep; /* iterator rdeps */
+
	struct cdb *db;
+
	void *manifest; /* temp for pkgdb_cache */
};

-
#define PKGDB_INIT_DEPS (1<<0)
-
#define PKGDB_INIT_RDEPS (1<<1)
+
typedef enum _match_t {
+
	MATCH_ALL,
+
	MATCH_EXACT,
+
	MATCH_GLOB,
+
	MATCH_REGEX,
+
	MATCH_EREGEX
+
} match_t;
+


struct pkgdb {
-
	struct pkg **pkgs; /* null-terminated */
-
	size_t count;
-
	size_t i;
	struct cdb db;
-
	unsigned char flags;
	int lock_fd;
+
	size_t i; /* iterator */
+
	const char *pattern;
+
	match_t match;
+
	regex_t re;
};

-
#define PKGDB_FOREACH(pkg, db) for ((db)->i = 0, (pkg) = (db)->pkgs[0]; \
-
		(pkg) != NULL; (pkg) = (db)->pkgs[++(db)->i])
-

typedef enum pkg_formats { TAR, TGZ, TBZ, TXZ } pkg_formats;
int pkg_create(char *, pkg_formats, const char *, const char *);
#endif
modified libpkg/pkgdb.c
@@ -13,35 +13,105 @@
#include "pkgdb.h"
#include "pkgdb_cache.h"

+
/* theses functions request on local database (cdb) */
+
static int pkg_db_open(struct pkgdb *);
+
static void pkg_db_init(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 *);

const char *
-
pkgdb_get_dir(void)
+
pkg_namever(struct pkg *pkg)
{
-
	const char *pkg_dbdir;
+
	if (pkg->namever == NULL)
+
		pkg->namever = pkg_db_namever(pkg);
+
	return (pkg->namever);
+
}

-
	if ((pkg_dbdir = getenv("PKG_DBDIR")) == NULL)
-
		pkg_dbdir = PKG_DBDIR;
+
const char *
+
pkg_name(struct pkg *pkg)
+
{
+
	if (pkg->name == NULL)
+
		pkg->name = pkg_db_getattr(pkg, PKGDB_NAME);
+
	return (pkg->name);
+
}

-
	return pkg_dbdir;
+
const char *
+
pkg_version(struct pkg *pkg)
+
{
+
	if (pkg->version == NULL)
+
		pkg->version = pkg_db_getattr(pkg, PKGDB_VERSION);
+
	return (pkg->version);
+
}
+

+
const char *
+
pkg_comment(struct pkg *pkg)
+
{
+
	if (pkg->comment == NULL)
+
		pkg->comment = pkg_db_getattr(pkg, PKGDB_COMMENT);
+
	return (pkg->comment);
+
}
+

+
const char *
+
pkg_desc(struct pkg *pkg)
+
{
+
	if (pkg->desc == NULL)
+
		pkg->desc = pkg_db_getattr(pkg, PKGDB_DESC);
+
	return (pkg->desc);
+
}
+

+
const char *
+
pkg_origin(struct pkg *pkg)
+
{
+
	if (pkg->origin == NULL)
+
		pkg->origin = pkg_db_getattr(pkg, PKGDB_ORIGIN);
+
	return (pkg->desc);
}

int
-
pkgdb_open(struct pkgdb *db)
+
pkg_dep(struct pkg *pkg, struct pkg *dep)
{
-
	char path[MAXPATHLEN];
-
	int fd;
+
	return (pkg_db_dep(pkg, dep));
+
}

-
	snprintf(path, sizeof(path), "%s/pkgdb.cache", pkgdb_get_dir());
+
static void
+
pkg_db_init(struct pkg *pkg)
+
{
+
	pkg->namever = NULL;
+
	pkg->name = NULL;
+
	pkg->version = NULL;
+
	pkg->origin = NULL;
+
	pkg->comment = NULL;
+
	pkg->desc = NULL;
+
	pkg->idx = -1;
+
	pkg->idep = 0;
+
	pkg->irdep = 0;
+
	pkg->db = NULL;
+
}

-
	if ((fd = open(path, O_RDONLY)) != -1)
-
		fd = cdb_init(&db->db, fd);

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

+
	pkg_db_init(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) {
+
		dep->idx = *idx;
+
		dep->db = pkg->db;
+
		pkg->idep++;
+
		ret = 0;
+
	}
+
	return (ret);
}

/* query formated using string key */
-
const void *
-
pkgdb_query(struct pkgdb *db, const char *fmt, ...)
+
static const void *
+
pkg_db_query(struct cdb *db, const char *fmt, ...)
{
	va_list args;
	char key[BUFSIZ];
@@ -60,141 +130,54 @@ pkgdb_query(struct pkgdb *db, const char *fmt, ...)

	va_end(args);

-
	if (cdb_find(&db->db, key, len) < 0)
+
	if (cdb_find(db, key, len) <= 0)
		return NULL;

-
	db_get(val, &db->db);
+
	db_get(val, db);
	return (val);
}

-
/* query a pkg from db using index */
-
struct pkg *
-
pkgdb_pkg_query(struct pkgdb *db, size_t idx)
+
static const char *
+
pkg_db_namever(struct pkg *pkg)
{
-
	struct pkg *pkg;
-

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

-
	if (cdb_find(&db->db, &idx, sizeof(idx)) <= 0)
-
		return NULL;
-

-
	pkg = malloc(sizeof(*pkg));
-
	pkg->idx = idx;
-
	db_get(pkg->name_version, &db->db);
-

-
	pkg->name = pkgdb_query(db, PKGDB_NAME, idx);
-
	pkg->version = pkgdb_query(db, PKGDB_VERSION, idx);
-
	pkg->comment = pkgdb_query(db, PKGDB_COMMENT, idx);
-
	pkg->desc = pkgdb_query(db, PKGDB_DESC, idx);
-
	pkg->origin = pkgdb_query(db, PKGDB_ORIGIN, idx);
-

-
	return (pkg);
+
	pkg->namever = NULL;
+
	if (cdb_find(pkg->db, &pkg->idx, sizeof(pkg->idx)) > 0)
+
		db_get(pkg->namever, pkg->db);
+
	return (pkg->namever);
}

-
/* populate deps on pkg */
-
void
-
pkgdb_deps_query(struct pkgdb *db, struct pkg *pkg)
+
static const char *
+
pkg_db_getattr(struct pkg *pkg, const char *attr)
{
-
	struct cdb_find cdbf;
-
	size_t count = 0, j, klen;
-
	char key[BUFSIZ];
-
	struct pkg *dep;
-

-
	if (db == NULL || pkg == NULL)
-
		return;
-

-
	snprintf(key, BUFSIZ, PKGDB_DEPS, pkg->idx);
-
	klen = strlen(key);
-

-
	cdb_findinit(&cdbf, &db->db, key, klen);
-

-
	while (cdb_findnext(&cdbf) > 0)
-
		count++;
-

-
	pkg->deps = calloc(count+1, sizeof(*pkg->deps));
-
	pkg->deps[count] = NULL;
-

-
	cdb_findinit(&cdbf, &db->db, key, klen);
-

-
	j = 0;
-
	while (cdb_findnext(&cdbf) > 0) {
-
		dep = calloc(1, sizeof(*dep));
-
		db_get(dep->name_version, &db->db);
-
		pkg->deps[j++] = dep;
-
	}
+
	return (pkg_db_query(pkg->db, attr, pkg->idx));
}

-
/* populate rdeps on package */
-
static void
-
pkgdb_rdeps_query(struct pkgdb *db, struct pkg *pkg, size_t count)
+
const char *
+
pkgdb_get_dir(void)
{
-
	size_t i, j;
-
	struct pkg *p, **deps;
-

-
	if (db == NULL || pkg == NULL)
-
		return;
-

-
	pkg->rdeps = calloc(count+1, sizeof(struct pkg *));
-

-
	for (i = 0, j = 0; i < count; i++) {
-

-
		if ((p = pkgdb_pkg_query(db, i)) == NULL)
-
			continue;
-

-
		pkgdb_deps_query(db, p);
-

-
		for (deps = p->deps; *deps != NULL; deps++) {
-
			if (!((*deps)->errors & PKGERR_NOT_INSTALLED)
-
					&& strcmp((*deps)->name_version, pkg->name_version) == 0) {
-
				pkg->rdeps[j] = p;
-
				break;
-
			}
-
		}
+
	const char *pkg_dbdir;

-
		/* free deps */
-
		for (deps = p->deps; *deps != NULL; deps++)
-
			free(*deps);
-
		free(p->deps);
+
	if ((pkg_dbdir = getenv("PKG_DBDIR")) == NULL)
+
		pkg_dbdir = PKG_DBDIR;

-
		if (pkg->rdeps[j] == p)
-
			j++;
-
		else
-
			free(p);
-
	}
-
	pkg->rdeps = realloc(pkg->rdeps, (j+1) * sizeof(struct pkg *));
-
	pkg->rdeps[j] = NULL;
-
	return;
+
	return pkg_dbdir;
}

static int
-
pkg_cmp(void const *a, void const *b)
+
pkg_db_open(struct pkgdb *db)
{
-
	struct pkg * const *pa = a;
-
	struct pkg * const *pb = b;
-
	return (strcmp((*pa)->name, (*pb)->name));
-
}
+
	char path[MAXPATHLEN];
+
	int fd;

-
static int
-
pkg_match(struct pkg *pkg, const regex_t *re, const char *pattern, match_t match)
-
{
-
	int matched = 1;
-
	switch (match) {
-
		case MATCH_ALL:
-
			matched = 0;
-
			break;
-
		case MATCH_EXACT:
-
			matched = strcmp(pkg->name_version, pattern);
-
			break;
-
		case MATCH_GLOB:
-
			matched = fnmatch(pattern, pkg->name_version, 0);
-
			break;
-
		case MATCH_REGEX:
-
		case MATCH_EREGEX:
-
			matched = regexec(re, pkg->name_version, 0, NULL, 0);
-
			break;
+
	snprintf(path, sizeof(path), "%s/pkgdb.cache", pkgdb_get_dir());
+

+
	if ((fd = open(path, O_RDONLY)) != -1)
+
		fd = cdb_init(&db->db, fd);
+
	else {
+
		/* TODO custom pkgdb error */
	}
-
	return (matched);
+

+
	return (fd);
}

/*
@@ -229,121 +212,95 @@ pkgdb_unlock(struct pkgdb *db)
	db->lock_fd = -1;
}

-
void
-
pkgdb_init(struct pkgdb *db, const char *pattern, match_t match, unsigned char flags) {
-
	size_t count, i;
-
	struct pkg *pkg;
-
	regex_t re;
-

+
int
+
pkgdb_init(struct pkgdb *db, const char *pattern, match_t match)
+
{
	pkgdb_cache_update(db);
+
	if (pkg_db_open(db) == -1)
+
		return (-1); /* TOTO pkgdb error */

-
	if (pkgdb_open(db) == -1)
-
		return;
-

-
	pkgdb_lock(db, 0);
-

-
	db->count = 0;
-
	db->flags = flags;
+
	db->pattern = pattern;
+
	db->match = match;
+
	db->i = 0;

-
	if (match != MATCH_ALL && pattern == NULL) {
-
		warnx("a pattern is required");
-
		return;
-
	}
-

-
	if (cdb_find(&db->db, PKGDB_COUNT, strlen(PKGDB_COUNT)) <= 0) {
-
		warnx("corrupted database");
-
		return;
-
	}
-

-
	cdb_read(&db->db, &count, sizeof(count), cdb_datapos(&db->db));
-
	db->pkgs = calloc(count+1, sizeof(struct pkg *));
+
	if (match != MATCH_ALL && pattern == NULL)
+
		return (-1);

	/* Regex initialisation */
	if (match == MATCH_REGEX) {
-
		if (regcomp(&re, pattern, REG_BASIC | REG_NOSUB) != 0) {
+
		if (regcomp(&db->re, pattern, REG_BASIC | REG_NOSUB) != 0) {
			warnx("'%s' is not a valid regular expression", pattern);
-
			return;
+
			return (-1);
		}
	} else if (match == MATCH_EREGEX) {
-
		if (regcomp(&re, pattern, REG_EXTENDED | REG_NOSUB) != 0) {
+
		if (regcomp(&db->re, pattern, REG_EXTENDED | REG_NOSUB) != 0) {
			warnx("'%s' is not a valid extended regular expression", pattern);
-
			return;
+
			return (-1);
		}
	}

-
	for (i = 0; i < count; i++) {
-
		/* get package */
-
		if ((pkg = pkgdb_pkg_query(db, i)) == NULL)
-
			continue;
-

-
		if (pkg_match(pkg, &re, pattern, match) == 0) {
-
			if (db->flags & PKGDB_INIT_DEPS)
-
				pkgdb_deps_query(db, pkg);
-
			if (db->flags & PKGDB_INIT_RDEPS)
-
				pkgdb_rdeps_query(db, pkg, count);
-
			db->pkgs[db->count++] = pkg;
-
		}
-
		else
-
			free(pkg);
-
	}
+
	return (0);
+
}

-
	if (match == MATCH_REGEX || match == MATCH_EREGEX)
-
		regfree(&re);
+
void
+
pkgdb_free(struct pkgdb *db)
+
{
+
	close(cdb_fileno(&db->db));
+
	cdb_free(&db->db);

-
	/* sort packages */
-
	db->pkgs = realloc(db->pkgs, (db->count+1) * sizeof(struct pkg *));
-
	db->pkgs[db->count] = NULL;
-
	qsort(db->pkgs, db->count, sizeof(struct pkg *), pkg_cmp);
+
	if (db->match == MATCH_REGEX || db->match == MATCH_EREGEX)
+
		regfree(&db->re);

-
	pkgdb_unlock(db);
	return;
}

-
static void
-
pkg_free(struct pkgdb *db, struct pkg *pkg)
+
static int
+
pkgdb_match(struct pkgdb *db, const char *pattern)
{
-
	struct pkg **deps;
-
	if (db->flags & PKGDB_INIT_DEPS) {
-
		if (!(pkg->errors & PKGERR_NOT_INSTALLED)) {
-
			for (deps = pkg->deps; *deps != NULL; deps++) {
-
				pkg_free(db, *deps);
-
			}
-
		}
+
	int matched = 1;
+
	switch (db->match) {
+
		case MATCH_ALL:
+
			matched = 0;
+
			break;
+
		case MATCH_EXACT:
+
			matched = strcmp(pattern, db->pattern);
+
			break;
+
		case MATCH_GLOB:
+
			matched = fnmatch(db->pattern, pattern, 0);
+
			break;
+
		case MATCH_REGEX:
+
		case MATCH_EREGEX:
+
			matched = regexec(&db->re, pattern, 0, NULL, 0);
+
			break;
	}
-
	free(pkg);
+
	return (matched);
}

-
void
-
pkgdb_free(struct pkgdb *db)
+

+

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

-
	fd = cdb_fileno(&db->db);
-
	cdb_free(&db->db);
-
	close(fd);
+
	pkg_db_init(pkg);

-
	PKGDB_FOREACH(pkg, db) {
-
		if (db->flags & PKGDB_INIT_DEPS) {
-
			for (deps = pkg->deps; *deps != NULL; deps++)
-
				free(*deps);
-
			free(pkg->deps);
-
		}
-
		if (db->flags & PKGDB_INIT_RDEPS) {
-
			for (deps = pkg->rdeps; *deps != NULL; deps++)
-
				free(*deps);
-
			free(pkg->rdeps);
+
	pkgdb_lock(db, 0);
+

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

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

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

-
size_t
-
pkgdb_count(struct pkgdb *db)
-
{
-
	return (db->count);
+
	return (ret);
}

-

modified libpkg/pkgdb.h
@@ -9,7 +9,7 @@
#define PKGDB_COMMENT "%zuc"
#define PKGDB_DESC    "%zud"
#define PKGDB_ORIGIN  "%zuo"
-
#define PKGDB_DEPS    "%zuD"
+
#define PKGDB_DEPS    "%zuD%zu"
#define PKGDB_COUNT   "count"

/* quick cdb_get */
@@ -17,24 +17,23 @@
	(val) = cdb_get((db), cdb_datalen((db)), cdb_datapos((db))); \
	} while (0)

-
typedef enum _match_t {
-
	MATCH_ALL,
-
	MATCH_EXACT,
-
	MATCH_GLOB,
-
	MATCH_REGEX,
-
	MATCH_EREGEX
-
} match_t;
-

void pkgdb_lock(struct pkgdb *db, int write);
void pkgdb_unlock(struct pkgdb *db);
const char * pkgdb_get_dir(void);
-
void pkgdb_init(struct pkgdb *, const char *pattern, match_t match, unsigned char flags);
-
void pkgdb_free(struct pkgdb *db);
-
size_t pkgdb_count(struct pkgdb *db);

-
const void *pkgdb_query(struct pkgdb *db, const char *fmt, ...);
-
struct pkg *pkgdb_pkg_query(struct pkgdb *db, size_t idx);
-
void pkgdb_deps_query(struct pkgdb *db, struct pkg *pkg);
-
int pkgdb_open(struct pkgdb *db);
+
/* getter */
+
const char *pkg_namever(struct pkg *);
+
const char *pkg_name(struct pkg *);
+
const char *pkg_version(struct pkg *);
+
const char *pkg_comment(struct pkg *);
+
const char *pkg_desc(struct pkg *);
+
const char *pkg_origin(struct pkg *);
+
int pkg_dep(struct pkg *, struct pkg *);
+

+
/* query */
+
int pkgdb_init(struct pkgdb *, const char *, match_t);
+
int pkgdb_query(struct pkgdb *, struct pkg *);
+
void pkgdb_free(struct pkgdb *);
+


#endif
modified libpkg/pkgdb_cache.c
@@ -70,74 +70,14 @@ pkgdb_add_string(struct cdb_make *db, const char *val, const char *fmt, ...)
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(cJSON *manifest)
-
{
-
	cJSON *node, *array;
-
	struct pkg *pkg;
-
	char *dep_name;
-
	char *dep_version;
-
	int i, array_size, j;
-

-
	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;
-
	}
-
	else {
-
		pkg->desc = cJSON_GetString(manifest, "desc");
-

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

-
		if (array && (array_size = cJSON_GetArraySize(array)) > 0) {
-

-
			pkg->deps = calloc(array_size+1, sizeof(struct pkg *));
-

-
			for (i = 0, j = 0; i < array_size; i++) {
-
				if ((node = cJSON_GetArrayItem(array, i)) != NULL) {
-
					dep_name = cJSON_GetString(node, "name");
-
					dep_version = cJSON_GetString(node, "version");
-
					if (dep_name != NULL && dep_version != NULL) {
-
						pkg->deps[j] = calloc(1, sizeof(struct pkg));
-
						pkg->deps[j]->name = dep_name;
-
						pkg->deps[j]->version = dep_version;
-
						j++;
-
					}
-
				}
-
			}
-
		}
-
	}
-
	return (pkg);
-
}
-

-
static struct pkg *
-
pkg_from_dir(struct pkgdb *db, time_t cache_mtime, const char *pkg_dbdir, char *pkgname)
+
pkg_from_manifest(const char *pkg_dbdir, char *pkgname)
{
	cJSON *manifest;
	char manifestpath[MAXPATHLEN];
	char *buffer;
-
	struct stat st;
-
	struct pkg *pkg = NULL;
-
	const size_t *idx;
+
	struct pkg *pkg;

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

-
	if (stat(manifestpath, &st) == -1) {
-
		warn("stat(%s):", manifestpath);
-
	}
-
	else if (st.st_mtime >= cache_mtime && /* compare with manifest mtime */
-
			cdb_fileno(&db->db) != -1 &&
-
			(idx = pkgdb_query(db, "%s", pkgname)) != NULL &&
-
			(pkg = pkgdb_pkg_query(db, *idx)) != NULL) { /* jackpot */
-
		pkgdb_deps_query(db, pkg);
-
		return (pkg);
-
	}
+
	snprintf(manifestpath, sizeof(manifestpath), "%s/%s/+MANIFEST", pkg_dbdir, pkgname);

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

@@ -158,22 +98,37 @@ pkg_from_dir(struct pkgdb *db, time_t cache_mtime, const char *pkg_dbdir, char *
		return NULL;
	}

-
	if ((pkg = pkg_from_manifest(manifest)) == NULL)
-
		cJSON_Delete(manifest);
+
	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);
}

+

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

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

@@ -184,9 +139,6 @@ pkgdb_cache_rebuild(struct pkgdb *db, time_t cache_mtime, const char *pkg_dbdir,

	cdb_make_start(&cdb_make, fd);

-
	if (pkgdb_open(db) == -1)
-
		cdb_fileno(&db->db) = -1;
-

	/* Now go through pkg_dbdir rebuild the cache */

	if ((dir = opendir(pkg_dbdir)) != NULL) {
@@ -197,7 +149,7 @@ pkgdb_cache_rebuild(struct pkgdb *db, time_t cache_mtime, const char *pkg_dbdir,
				if (portsdir->d_type != DT_DIR)
					continue;

-
				pkg = pkg_from_dir(db, cache_mtime, pkg_dbdir, portsdir->d_name);
+
				pkg = pkg_from_manifest(pkg_dbdir, portsdir->d_name);

				if (pkg == NULL)
					continue;
@@ -215,13 +167,19 @@ pkgdb_cache_rebuild(struct pkgdb *db, time_t cache_mtime, const char *pkg_dbdir,
				pkgdb_add_string(&cdb_make, pkg->origin, PKGDB_ORIGIN, idx);
				pkgdb_add_string(&cdb_make, pkg->desc, PKGDB_DESC, idx);

-
				if (pkg->deps) {
-
					for (deps = pkg->deps; *deps != NULL; deps++) {
-
						snprintf(namever, sizeof(namever), "%s-%s", (*deps)->name, (*deps)->version);
-
						pkgdb_add_string(&cdb_make, namever, PKGDB_DEPS, idx);
-
						free(*deps);
+
				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);
+
							}
+
						}
					}
-
					free(pkg->deps);
				}

				cJSON_Delete(pkg->manifest);
@@ -232,16 +190,9 @@ pkgdb_cache_rebuild(struct pkgdb *db, time_t cache_mtime, const char *pkg_dbdir,
		closedir(dir);
	}

-
	/* close old db */
-
	if (cdb_fileno(&db->db) != -1) {
-
		close(cdb_fileno(&db->db));
-
		cdb_free(&db->db);
-
	}
-

	/* record packages len */
	cdb_make_add(&cdb_make, PKGDB_COUNT, strlen(PKGDB_COUNT), &idx, sizeof(idx));
	cdb_make_finish(&cdb_make);
-

	close(fd);
	rename(tmppath, cache_path);
	chmod(cache_path, 0644);
@@ -276,7 +227,7 @@ pkgdb_cache_update(struct pkgdb *db)

	if (errno == ENOENT || dir_st.st_mtime > cache_st.st_mtime) {
		pkgdb_lock(db, 1);
-
		pkgdb_cache_rebuild(db, (errno = ENOENT) ? 0 : cache_st.st_mtime, pkg_dbdir, cache_path);
+
		pkgdb_cache_rebuild(pkg_dbdir, cache_path);
		pkgdb_unlock(db);
	}
}
modified pkg/info.c
@@ -24,8 +24,7 @@ int
cmd_info(int argc, char **argv)
{
	struct pkgdb db;
-
	struct pkg *pkg, **deps;
-
	unsigned char flags = 0;
+
	struct pkg pkg, dep;
	unsigned char opt = 0;
	match_t match = MATCH_EXACT;
	char ch;
@@ -43,11 +42,9 @@ cmd_info(int argc, char **argv)
				match = MATCH_EREGEX;
				break;
			case 'd':
-
				flags |= PKGDB_INIT_DEPS;
				opt |= INFO_PRINT_DEP;
				break;
			case 'D':
-
				flags |= PKGDB_INIT_RDEPS;
				opt |= INFO_PRINT_RDEP;
				break;
		}
@@ -58,30 +55,19 @@ cmd_info(int argc, char **argv)
	if (argc == 0)
		match = MATCH_ALL;

-
	pkgdb_init(&db, argv[0], match, flags);
-

-
	PKGDB_FOREACH(pkg, &db) {
+
	pkgdb_init(&db, argv[0], match);

+
	while (pkgdb_query(&db, &pkg) == 0) {
		if (opt & INFO_PRINT_DEP) {
-
			printf("%s depends on:\n", pkg->name_version);
-
			for (deps = pkg->deps; *deps != NULL; deps++)
-
				printf("%s\n", (*deps)->name_version);
-
		}

-
		else if (opt & INFO_PRINT_RDEP) {
-
			printf("%s is required for:\n", pkg->name_version);
-
			for (deps = pkg->rdeps; *deps != NULL; deps++)
-
				printf("%s\n", (*deps)->name_version);
-
		}
+
			printf("%s depends on:\n", pkg_namever(&pkg));

-
		else if (pkgdb_count(&db) == 1) {
-
			printf("Informations for %s\n\n", pkg->name_version);
-
			printf("Comment:\n%s\n\n", pkg->comment);
-
			printf("Description:\n%s\n\n", pkg->desc);
-
		}
+
			while (pkg_dep(&pkg, &dep) == 0) {
+
				printf("%s\n", pkg_namever(&dep));
+
			}

-
		else {
-
			printf("%s: %s\n", pkg->name_version, pkg->comment);
+
		} else {
+
			printf("%s: %s\n", pkg_namever(&pkg), pkg_comment(&pkg));
		}
	}