Radish alpha
H
rad:z3QDZAW2FAfuLvihrhiyDC9fAD8G9
HardenedBSD Package Manager
Radicle
Git
Improve cdb queries, put last '\0' on values TODO: sort packages
Philippe Pepiot committed 15 years ago
commit a89521e4c6bc6e51b9cfb8a525cd4fef7ae65979
parent 958f0b9
8 files changed +106 -111
modified db.txt
@@ -9,7 +9,7 @@ Needs:

key			value

-
(char*)"nb_packages"		(int)nb_packages
+
(char*)"count"		(int)nb_packages
[...]
(int)N		(char*) package N name
[...]
modified libpkg/pkg.h
@@ -1,12 +1,23 @@
#ifndef _PKG_H
#define _PKG_H

+
#include <cdb.h>
+
#include <sys/queue.h>
+

struct pkg {
-
	char *name;
-
	char *version;
-
	char *origin;
-
	char *comment;
-
	char *desc;
+
	const char *name;
+
	const char *version;
+
	const char *origin;
+
	const char *comment;
+
	const char *desc;
+
	TAILQ_ENTRY(pkg) entry;
+
	TAILQ_HEAD(, pkg) deps;
+
};
+

+
struct pkgdb {
+
	TAILQ_HEAD(, pkg) pkgs;
+
	size_t count;
+
	struct cdb db;
};

#endif
modified libpkg/pkgdb.c
@@ -1,51 +1,39 @@
#include <stdio.h>
#include <stdlib.h>
+
#include <unistd.h>

#include "pkgdb.h"
#include "pkgdb_cache.h"



-
struct pkg **
-
pkgdb_list_packages(const char *pattern) {
+
void
+
pkgdb_init(struct pkgdb *db, const char *pattern) {
	/* first check if the cache has to be rebuild */
-
	struct pkg **pkgs;
-

	pkgdb_cache_update();
-
	pkgs = pkgdb_cache_list_packages(pattern);
-

-
	return (pkgs);
+
	return (pkgdb_cache_init(db, pattern));
}

void
-
pkgdb_free(struct pkg **pkgs)
+
pkgdb_free(struct pkgdb *db)
{
-
	int i;
-
	struct pkg *p;
-

-
	if (pkgs) {
-
		for (i = 0; pkgs[i] != NULL; i++) {
-
			p = pkgs[i];
-
			if (p->name) free(p->name);
-
			if (p->version) free(p->version);
-
			if (p->comment) free(p->comment);
-
			if (p->desc) free(p->desc);
-
			if (p->origin) free(p->origin);
-
			free(p);
-
		}
-
		free(pkgs);
+
	int fd;
+
	struct pkg *pkg;
+

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

+
	while (!TAILQ_EMPTY(&db->pkgs)) {
+
		pkg = TAILQ_FIRST(&db->pkgs);
+
		TAILQ_REMOVE(&db->pkgs, pkg, entry);
+
		free(pkg);
	}
}

size_t
-
pkgdb_count(struct pkg **pkgs)
+
pkgdb_count(struct pkgdb *db)
{
-
	size_t i;
-

-
	if (!pkgs)
-
		return 0;
-

-
	for (i = 0; pkgs[i] != NULL; i++);
-
	return (i);
+
	return (db->count);
}

modified libpkg/pkgdb.h
@@ -4,9 +4,9 @@

#define PKG_DBDIR "/var/db/pkg"

-
struct pkg **pkgdb_list_packages(const char*pattern);
-
void pkgdb_free(struct pkg **pkgs);
-
size_t pkgdb_count(struct pkg **pkgs);
+
void pkgdb_init(struct pkgdb *db, const char *pattern);
+
void pkgdb_free(struct pkgdb *db);
+
size_t pkgdb_count(struct pkgdb *db);


#endif
modified libpkg/pkgdb_cache.c
@@ -35,22 +35,11 @@ db_open(struct cdb *db, const char *path, int flags)
	return (fd);
}

-
/* close a cdb db */
-
static void
-
db_close(struct cdb *db)
-
{
-
	int fd;
-

-
	fd = cdb_fileno(db);
-
	cdb_free(db);
-
	close(fd);
-
}
-

/* query string -> string */
-
static char *
+
static const char *
db_query(struct cdb *db, const char *fmt, ...)
{
-
	char *string;
+
	const char *string;
	va_list args;
	char key[BUFSIZ];
	size_t len;
@@ -70,10 +59,7 @@ db_query(struct cdb *db, const char *fmt, ...)
	if (cdb_find(db, key, len) < 0)
		return NULL;

-
	len = cdb_datalen(db);
-
	string = malloc(len+1);
-
	cdb_read(db, string, len, cdb_datapos(db));
-
	string[len] = '\0';
+
	db_get(string, db);
	return (string);
}

@@ -89,6 +75,7 @@ db_add(struct cdb_make *db, const char *val, const char *fmt, ...)
		return (-1);

	va_start(args, fmt);
+

	len = vsnprintf(key, sizeof(key), fmt, args);

	if (len != strlen(key)) {
@@ -98,7 +85,10 @@ db_add(struct cdb_make *db, const char *val, const char *fmt, ...)
		return (-1);
	}

-
	return (cdb_make_add(db, key, len, val, strlen(val)));
+
	va_end(args);
+

+
	/* record the last \0 */
+
	return (cdb_make_add(db, key, len, val, strlen(val)+1));
}

/* query a pkg using index */
@@ -106,19 +96,16 @@ static struct pkg *
pkg_idx_query(struct cdb *db, int idx)
{
	struct pkg *pkg;
-
	size_t len;

	if (db == NULL)
		return NULL;

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

	pkg = malloc(sizeof(*pkg));
-
	len = cdb_datalen(db);
-
	pkg->name = malloc(len+1);
-
	cdb_read(db, pkg->name, len, cdb_datapos(db));
-
	pkg->name[len] = '\0';
+
	TAILQ_INIT(&pkg->deps);
+
	db_get(pkg->name, db);

	pkg->version = db_query(db, PKGDB_VERSION, idx);
	pkg->comment = db_query(db, PKGDB_COMMENT, idx);
@@ -132,7 +119,7 @@ pkg_idx_query(struct cdb *db, int idx)
/* static struct pkg *
pkg_query(struct cdb *db, char *name)
{
-
	int idx;
+
	int *idx;

	if (name == NULL || db == NULL)
		return NULL;
@@ -140,9 +127,8 @@ pkg_query(struct cdb *db, char *name)
	if ((cdb_find(db, name, strlen(name))) <= 0)
		return NULL;

-
	cdb_read(db, &idx, sizeof(idx), cdb_datapos(db));
-

-
	return (pkg_idx_query(db, idx));
+
	db_get(idx, db);
+
	return (pkg_idx_query(db, *idx));
}
*/

@@ -229,7 +215,7 @@ pkgdb_cache_rebuild(const char *pkg_dbdir, const char *cache_path)

				/* index -> name */
				cdb_make_add(&cdb_make, &idx, sizeof(idx),
-
						value, strlen(value));
+
						value, strlen(value)+1);
				/* name -> index */
				cdb_make_add(&cdb_make, value, strlen(value), &idx, sizeof(idx));

@@ -253,7 +239,7 @@ pkgdb_cache_rebuild(const char *pkg_dbdir, const char *cache_path)
	}

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

	cdb_make_finish(&cdb_make);

@@ -300,46 +286,48 @@ pkgdb_cache_update()
		pkgdb_cache_rebuild(pkg_dbdir, cache_path);
}

-
struct pkg **
-
pkgdb_cache_list_packages(const char *pattern)
+
void
+
pkgdb_cache_init(struct pkgdb *db, const char *pattern)
{
-
	struct cdb db;
-
	int nb_pkg, i, j;
-
	char key[BUFSIZ];
-
	char *val;
-
	struct pkg **pkgs;
-
	size_t len;
+
	int count;
+
	int i;
+
	struct pkg *pkg;
+
	char *name;

-
	if (pkgdb_open(&db, O_RDONLY) == -1)
-
		return NULL;
+
	TAILQ_INIT(&db->pkgs);
+
	db->count = 0;

-
	strcpy(key, "nb_packages");
+
	if (pkgdb_open(&db->db, O_RDONLY) == -1)
+
		return;

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

-
	cdb_read(&db, &nb_pkg, sizeof(nb_pkg), cdb_datapos(&db));
+
	cdb_read(&db->db, &count, sizeof(count), cdb_datapos(&db->db));

-
	pkgs = calloc(nb_pkg+1, sizeof(*pkgs));
+
	for (i = 0; i < count; i++) {
+
		/* get package */
+
		if ((pkg = pkg_idx_query(&db->db, i)) == NULL)
+
			continue;

-
	for (i = 0, j = 0; i < nb_pkg; i++) {
-
		cdb_find(&db, &i, sizeof(i));
-
		len = cdb_datalen(&db);
-
		val = malloc(len+1);
-
		cdb_read(&db, val, len, cdb_datapos(&db));
-
		val[len] = '\0';
+
		if (asprintf(&name, "%s-%s", pkg->name, pkg->version) == -1) {
+
			warn("asprintf(%s-%s):", pkg->name, pkg->version);
+
			free(pkg);
+
			continue;
+
		}

-
		if (!pattern || strncmp(val, pattern, strlen(pattern)) == 0) {
+
		if (!pattern || strncmp(name, pattern, strlen(pattern)) == 0) {
			/* ok we find one pkg matching the pattern */
-
			if ((pkgs[j] = pkg_idx_query(&db, i)) != NULL)
-
				j++;
+
				TAILQ_INSERT_TAIL(&db->pkgs, pkg, entry);
+
				db->count++;
		}
-
	}
-
	pkgs[j] = NULL;
+
		else
+
			free(pkg);

-
	db_close(&db);
+
		free(name);
+
	}

-
	return (pkgs);
+
	return;
}
modified libpkg/pkgdb_cache.h
@@ -6,8 +6,15 @@
#define PKGDB_COMMENT "%dc"
#define PKGDB_DESC    "%dd"
#define PKGDB_ORIGIN  "%do"
+
#define PKGDB_COUNT   "count"
+

+
/* quick db_get */
+
#define db_get(val, db) do { \
+
	(val) = cdb_get((db), cdb_datalen((db)), cdb_datapos((db))); \
+
	} while (0)
+


void pkgdb_cache_update(void);
-
struct pkg **pkgdb_cache_list_packages(const char*pattern);
+
void pkgdb_cache_init(struct pkgdb *db, const char *pattern);

#endif
modified pkg/Makefile
@@ -2,7 +2,7 @@ PROG= pkg
SRCS=	main.c \
		info.c

-
CFLAGS+=	-I${.CURDIR}/../libpkg -I${.CURDIR}/../external
+
CFLAGS+=	-I${.CURDIR}/../libpkg -I${.CURDIR}/../external/tinycdb/
LDADD+=	-L${.CURDIR}/../external -L../libpkg -lpkg
WARNS?=	6
NO_MAN= true
modified pkg/info.c
@@ -8,24 +8,25 @@
int
cmd_info(int argc, char **argv)
{
-
	struct pkg **pkgs;
-
	int i;
+
	struct pkgdb db;
+
	struct pkg *pkg;
	(void)argc;

-
	if ((pkgs = pkgdb_list_packages(argv[1])) == NULL)
-
		return 0;
+
	pkgdb_init(&db, argv[1]);

-
	if (pkgdb_count(pkgs) == 1) {
+
	if (pkgdb_count(&db) == 1) {
		/* one match */
-
		printf("Information for %s-%s\n", pkgs[0]->name, pkgs[0]->version);
-
		printf("Comment:\n%s\n\n", pkgs[0]->comment);
-
		printf("Description:\n%s\n\n", pkgs[0]->desc);
+
		pkg = TAILQ_FIRST(&db.pkgs);
+
		printf("Information for %s-%s\n", pkg->name, pkg->version);
+
		printf("Comment:\n%s\n\n", pkg->comment);
+
		printf("Description:\n%s\n\n", pkg->desc);
	}
-
	else {
-
		for (i = 0; pkgs[i] != NULL; i++)
-
			printf("%s-%s: %s\n", pkgs[i]->name, pkgs[i]->version, pkgs[i]->comment);
+
	else if (pkgdb_count(&db) > 1) {
+
		TAILQ_FOREACH(pkg, &db.pkgs, entry) {
+
			printf("%s-%s: %s\n", pkg->name, pkg->version, pkg->comment);
+
		}
	}

-
	pkgdb_free(pkgs);
+
	pkgdb_free(&db);
	return (0);
}