Radish alpha
H
HardenedBSD Package Manager
Radicle
Git (anonymous pull)
Log in to clone via SSH
Cleanups - Improve backend separation (note that pkg is linked with pkgdb, access cdb througt pkg->pdb->cdb) - Lock has changed, and is now used on each cdb read - Remove use of dirname() in pkg_compat_convert_installed
Philippe Pepiot committed 15 years ago
commit d829bb1a889c9641eaa3ff4ae6f8e96718634f40
parent 3fd24a846fa54a1c653853c5eba9013a2835f9b2
6 files changed +192 -170
modified libpkg/pkg.h
@@ -7,20 +7,6 @@
/* Opaque type */
struct cdb;

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

typedef enum _match_t {
	MATCH_ALL,
	MATCH_EXACT,
@@ -38,9 +24,22 @@ struct pkgdb {
	regex_t re;
};

+
struct pkg {
+
	const char *namever;
+
	const char *name;
+
	const char *version;
+
	const char *origin;
+
	const char *comment;
+
	const char *desc;
+
	size_t idx; /* index on pkgdb */
+
	size_t idep; /* iterator deps */
+
	size_t irdep; /* iterator rdeps */
+
	struct pkgdb *pdb;
+
	void *manifest; /* temp for pkgdb_cache */
+
};
+

+

typedef enum pkg_formats { TAR, TGZ, TBZ, TXZ } pkg_formats;
int pkg_create(char *, pkg_formats, const char *, const char *);

-
void pkg_reset(struct pkg*);
-

#endif
modified libpkg/pkg_compat.c
@@ -233,11 +233,12 @@ struct pkg_manifest *
pkg_compat_convert_installed(const char *pkg_dbdir, char *pkgname, char *mpath)
{
	struct pkg_manifest *m;
-
	char *buffer, *dir;
+
	char *buffer;
	off_t buffer_len;
-
	char filepath[MAXPATHLEN];
+
	char filepath[MAXPATHLEN], pkg_dir[MAXPATHLEN];

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

	if (file_to_buffer(filepath, &buffer) == -1) {
		warnx("can not read %s", filepath);
@@ -251,9 +252,7 @@ pkg_compat_convert_installed(const char *pkg_dbdir, char *pkgname, char *mpath)
	}

	/* adding comment */
-
	dir =  dirname(filepath);
-
	snprintf(filepath, sizeof(filepath), "%s/+COMMENT", dirname(filepath));
-
	free(dir);
+
	snprintf(filepath, sizeof(filepath), "%s/+COMMENT", pkg_dir);

	if ((buffer_len = file_to_buffer(filepath, &buffer)) == -1) {
		warn("Unable to read +COMMENT for %s", pkgname);
@@ -266,7 +265,7 @@ pkg_compat_convert_installed(const char *pkg_dbdir, char *pkgname, char *mpath)
	}

	/* adding description */
-
	snprintf(filepath, sizeof(filepath), "%s/+DESC", dirname(filepath));
+
	snprintf(filepath, sizeof(filepath), "%s/+DESC", pkg_dir);

	if (file_to_buffer(filepath, &buffer) == -1) {
		warn("Unable to read +DESC for %s", pkgname);
@@ -276,7 +275,7 @@ pkg_compat_convert_installed(const char *pkg_dbdir, char *pkgname, char *mpath)
	}

	/* adding display */
-
	snprintf(filepath, sizeof(filepath), "%s/+DISPLAY", dirname(filepath));
+
	snprintf(filepath, sizeof(filepath), "%s/+DISPLAY", pkg_dir);
	/* ignore if no +DISPLAY */
	if (file_to_buffer(filepath, &buffer) != -1) {
		pkg_manifest_add_value(m, "display", buffer);
modified libpkg/pkgdb.c
@@ -3,6 +3,7 @@
#include <sys/file.h>

#include <err.h>
+
#include <assert.h>
#include <fcntl.h>
#include <fnmatch.h>
#include <stdlib.h>
@@ -14,57 +15,59 @@
#include "pkgdb.h"
#include "pkgdb_cache.h"

+

+
#define PKGDB_LOCK "lock"
+
#define PKG_DBDIR "/var/db/pkg"
+

+
static const char *
+
pkg_getattr(struct pkg *pkg, const char **val, const char *attr)
+
{
+
	if (*val == NULL)
+
		*val = pkgdb_cache_getattr(pkg, attr);
+

+
	return (*val);
+
}
+

const char *
pkg_namever(struct pkg *pkg)
{
-
	if (pkg->namever == NULL)
-
		pkg->namever = pkgdb_cache_getattr(pkg, PKGDB_NAMEVER);
-
	return (pkg->namever);
+
	return (pkg_getattr(pkg, &pkg->namever, "namever"));
}

const char *
pkg_name(struct pkg *pkg)
{
-
	if (pkg->name == NULL)
-
		pkg->name = pkgdb_cache_getattr(pkg, PKGDB_NAME);
-
	return (pkg->name);
+
	return (pkg_getattr(pkg, &pkg->name, "name"));
}

const char *
pkg_version(struct pkg *pkg)
{
-
	if (pkg->version == NULL)
-
		pkg->version = pkgdb_cache_getattr(pkg, PKGDB_VERSION);
-
	return (pkg->version);
+
	return (pkg_getattr(pkg, &pkg->version, "version"));
}

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

const char *
pkg_desc(struct pkg *pkg)
{
-
	if (pkg->desc == NULL)
-
		pkg->desc = pkgdb_cache_getattr(pkg, PKGDB_DESC);
-
	return (pkg->desc);
+
	return (pkg_getattr(pkg, &pkg->comment, "comment"));
}

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

int
pkg_dep(struct pkg *pkg, struct pkg *dep)
{
+
	/* call backend dep query */
	return (pkgdb_cache_dep(pkg, dep));
}

@@ -80,7 +83,7 @@ pkg_reset(struct pkg *pkg)
	pkg->idx = -1;
	pkg->idep = 0;
	pkg->irdep = 0;
-
	pkg->cdb = NULL;
+
	pkg->pdb = NULL;
}

const char *
@@ -94,48 +97,53 @@ pkgdb_get_dir(void)
	return pkg_dbdir;
}

-
/*
-
 * Acquire a lock to access the database.
-
 * If `writer' is set to 1, an exclusive lock is requested so it wont mess up
-
 * with other writers or readers.
-
 */
+
/* Acquire/Release a lock to access the database. */
void
-
pkgdb_lock(struct pkgdb *db, int writer)
+
pkgdb_lock(struct pkgdb *db, int flags)
{
	char fname[FILENAME_MAX];
-
	int flags;

-
	snprintf(fname, sizeof(fname), "%s/%s", pkgdb_get_dir(), PKGDB_LOCK);
-
	if ((db->lock_fd = open(fname, O_RDONLY | O_CREAT, S_IRUSR | S_IRGRP | S_IROTH)) < 0)
-
		err(EXIT_FAILURE, "open(%s)", fname);
-

-
	if (writer == 1)
-
		flags = LOCK_EX;
-
	else
-
		flags = LOCK_SH;
+
	if (db->lock_fd == -1) {
+
		snprintf(fname, sizeof(fname), "%s/%s", pkgdb_get_dir(), PKGDB_LOCK);
+
		if ((db->lock_fd = open(fname, O_RDONLY | O_CREAT, S_IRUSR | S_IRGRP | S_IROTH)) < 0)
+
			err(EXIT_FAILURE, "open(%s)", fname);
+
	}

	if (flock(db->lock_fd, flags) < 0)
		errx(EXIT_FAILURE, "unable to acquire a lock to the database");
}

-
void
-
pkgdb_unlock(struct pkgdb *db)
+
int
+
pkgdb_match(struct pkgdb *db, const char *pattern)
{
-
	flock(db->lock_fd, LOCK_UN);
-
	close(db->lock_fd);
-
	db->lock_fd = -1;
+
	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;
+
	}
+

+
	return (matched);
}

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

	db->pattern = pattern;
	db->match = match;
	db->i = 0;
+
	db->lock_fd = -1;

	if (match != MATCH_ALL && pattern == NULL)
		return (-1);
@@ -153,60 +161,30 @@ pkgdb_init(struct pkgdb *db, const char *pattern, match_t match)
		}
	}

-
	return (0);
+
	/* call backend init */
+
	return (pkgdb_cache_init(db));
}

void
pkgdb_free(struct pkgdb *db)
{
-
	if (db->cdb != NULL)
-
		pkgdb_cache_close(db->cdb);
-

	if (db->match == MATCH_REGEX || db->match == MATCH_EREGEX)
		regfree(&db->re);

-
	return;
-
}
+
	if (db->lock_fd != -1)
+
		close(db->lock_fd);

-
static int
-
pkgdb_match(struct pkgdb *db, const char *pattern)
-
{
-
	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;
-
	}
-
	return (matched);
+
	/* call backend free */
+
	pkgdb_cache_free(db);
+

+
	return;
}

int
pkgdb_query(struct pkgdb *db, struct pkg *pkg)
{
	pkg_reset(pkg);
-
	pkgdb_lock(db, 0);
-

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

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

-
	return (-1);
+
	/* call backend query */
+
	return (pkgdb_cache_query(db, pkg));
}

modified libpkg/pkgdb.h
@@ -3,13 +3,7 @@

#include <pkg.h>

-
#define PKG_DBDIR "/var/db/pkg"
-

-
void pkgdb_lock(struct pkgdb *db, int write);
-
void pkgdb_unlock(struct pkgdb *db);
-
const char * pkgdb_get_dir(void);
-

-
/* getter */
+
/* getters */
const char *pkg_namever(struct pkg *);
const char *pkg_name(struct pkg *);
const char *pkg_version(struct pkg *);
@@ -23,4 +17,10 @@ int pkgdb_init(struct pkgdb *, const char *, match_t);
int pkgdb_query(struct pkgdb *, struct pkg *);
void pkgdb_free(struct pkgdb *);

+
/* misc */
+
const char *pkgdb_get_dir(void);
+
int pkgdb_match(struct pkgdb *, const char *);
+
void pkg_reset(struct pkg *);
+
void pkgdb_lock(struct pkgdb *, int);
+

#endif
modified libpkg/pkgdb_cache.c
@@ -18,32 +18,69 @@
#include "pkg_manifest.h"
#include "pkgdb_cache.h"

-
int
-
pkgdb_cache_open(struct pkgdb *db)
+
#define PKGDB_NAMEVER	"%zunv"
+
#define PKGDB_NAME		"%zun"
+
#define PKGDB_VERSION	"%zuv"
+
#define PKGDB_COMMENT	"%zuc"
+
#define PKGDB_DESC		"%zud"
+
#define PKGDB_ORIGIN	"%zuo"
+
#define PKGDB_DEPS		"%zuD%zu"
+
#define PKGDB_COUNT		"count"
+

+
static const void *pkgdb_cache_vget(struct cdb *, const char *, ...);
+
static int pkgdb_cache_vadd(struct cdb_make *, const void *, size_t, const char *, va_list);
+
static int pkgdb_cache_add_string(struct cdb_make *, const char *, const char *, ...);
+
static int pkgdb_cache_add_int(struct cdb_make *, const char *, size_t);
+
static void pkgdb_cache_update(struct pkgdb *);
+

+
const char *
+
pkgdb_cache_getattr(struct pkg *pkg, const char *attr)
{
-
	char path[MAXPATHLEN];
-
	int fd;
+
	size_t i, len;
+
	const char *val;
+
	struct {
+
		const char *attr;
+
		const char *key;
+
	} attr_key_map[] = {
+
		{"namever", PKGDB_NAMEVER},
+
		{"name",	PKGDB_NAME},
+
		{"version",	PKGDB_VERSION},
+
		{"comment", PKGDB_COMMENT},
+
		{"desc",	PKGDB_DESC},
+
		{"origin",	PKGDB_ORIGIN}
+
	};
+

+
	len = sizeof(attr_key_map) / sizeof(attr_key_map[0]);
+

+
	for (i = 0; i < len; i++)
+
		if (strcmp(attr_key_map[i].attr, attr) == 0)
+
			break;
+

+
	pkgdb_lock(pkg->pdb, LOCK_SH);
+
	val = pkgdb_cache_vget(pkg->pdb->cdb, attr_key_map[i].key, pkg->idx);
+
	pkgdb_lock(pkg->pdb, LOCK_UN);
+
	return (val);
+
}

-
	snprintf(path, sizeof(path), "%s/pkgdb.cache", pkgdb_get_dir());

-
	if ((db->cdb = malloc(sizeof(struct cdb))) == NULL)
-
		err(EXIT_FAILURE, "malloc()");
+
int
+
pkgdb_cache_query(struct pkgdb *db, struct pkg *pkg)
+
{
+
	pkgdb_lock(db, LOCK_SH);
+

+
	while ((pkg->namever = pkgdb_cache_vget(db->cdb, PKGDB_NAMEVER, db->i)) != NULL) {
+
		if (pkgdb_match(db, pkg->namever) == 0) {
+
			pkg->idx = db->i++;
+
			pkg->pdb = db;
+
			pkgdb_lock(db, LOCK_UN);
+
			return (0);
+
		}

-
	if ((fd = open(path, O_RDONLY)) != -1)
-
		fd = cdb_init(db->cdb, fd);
-
	else {
-
		/* TODO custom pkgdb error */
+
		db->i++;
	}
+
	pkgdb_lock(db, LOCK_UN);

-
	return (fd);
-
}
-

-
void
-
pkgdb_cache_close(struct cdb *cdb)
-
{
-
	close(cdb_fileno(cdb));
-
	cdb_free(cdb);
-
	free(cdb);
+
	return (-1);
}

/* add record formated string */
@@ -88,7 +125,7 @@ pkgdb_cache_add_int(struct cdb_make *db, const char *key, size_t val)
	return cdb_make_add(db, key, strlen(key), &val, sizeof(size_t));
}

-
const void *
+
static const void *
pkgdb_cache_vget(struct cdb *db, const char *fmt, ...)
{
	va_list args;
@@ -111,16 +148,10 @@ pkgdb_cache_vget(struct cdb *db, const char *fmt, ...)
	if (cdb_find(db, key, len) <= 0)
		return NULL;

-
	db_get(val, db);
+
	val = cdb_get(db, cdb_datalen(db), cdb_datapos(db));
	return (val);
}

-
const char *
-
pkgdb_cache_getattr(struct pkg *pkg, const char *attr)
-
{
-
	return (pkgdb_cache_vget(pkg->cdb, attr, pkg->idx));
-
}
-

int
pkgdb_cache_dep(struct pkg *pkg, struct pkg *dep)
{
@@ -129,10 +160,10 @@ pkgdb_cache_dep(struct pkg *pkg, struct pkg *dep)

	pkg_reset(dep);

-
	if ((dep->namever = pkgdb_cache_vget(pkg->cdb, PKGDB_DEPS, pkg->idx, pkg->idep)) != NULL &&
-
		(idx = pkgdb_cache_vget(pkg->cdb, "%s", dep->namever)) != NULL) {
+
	if ((dep->namever = pkgdb_cache_vget(pkg->pdb->cdb, PKGDB_DEPS, pkg->idx, pkg->idep)) != NULL &&
+
		(idx = pkgdb_cache_vget(pkg->pdb->cdb, "%s", dep->namever)) != NULL) {
		dep->idx = *idx;
-
		dep->cdb = pkg->cdb;
+
		dep->pdb = pkg->pdb;
		pkg->idep++;
		ret = 0;
	}
@@ -219,7 +250,7 @@ pkgdb_cache_rebuild(const char *pkg_dbdir, const char *cache_path)
	chmod(cache_path, 0644);
}

-
void
+
static void
pkgdb_cache_update(struct pkgdb *db)
{
	const char *pkg_dbdir;
@@ -247,8 +278,39 @@ pkgdb_cache_update(struct pkgdb *db)
		err(EXIT_FAILURE, "%s:", cache_path);

	if (errno == ENOENT || dir_st.st_mtime > cache_st.st_mtime) {
-
		pkgdb_lock(db, 1);
+
		pkgdb_lock(db, LOCK_EX);
		pkgdb_cache_rebuild(pkg_dbdir, cache_path);
-
		pkgdb_unlock(db);
+
		pkgdb_lock(db, LOCK_UN);
+
	}
+
}
+

+
int
+
pkgdb_cache_init(struct pkgdb *db)
+
{
+
	char path[MAXPATHLEN];
+
	int fd;
+

+
	pkgdb_cache_update(db);
+

+
	if ((db->cdb = malloc(sizeof(struct cdb))) == NULL)
+
		err(EXIT_FAILURE, "malloc()");
+

+
	snprintf(path, sizeof(path), "%s/pkgdb.cache", pkgdb_get_dir());
+

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

+
	return (0);
+
}
+

+
void
+
pkgdb_cache_free(struct pkgdb *db)
+
{
+
	close(cdb_fileno(db->cdb));
+
	cdb_free(db->cdb);
+
	free(db->cdb);
+
	return;
}
modified libpkg/pkgdb_cache.h
@@ -5,29 +5,13 @@

#include "pkgdb.h"

-
#define PKGDB_LOCK		"lock"
-
#define PKGDB_NAMEVER	"%zunv"
-
#define PKGDB_NAME		"%zun"
-
#define PKGDB_VERSION	"%zuv"
-
#define PKGDB_COMMENT	"%zuc"
-
#define PKGDB_DESC		"%zud"
-
#define PKGDB_ORIGIN	"%zuo"
-
#define PKGDB_DEPS		"%zuD%zu"
-
#define PKGDB_COUNT		"count"
-

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

-
int pkgdb_cache_open(struct pkgdb *);
-
void pkgdb_cache_close(struct cdb *);
-

-
const void *pkgdb_cache_vget(struct cdb *, const char *, ...);
+
/* getter */
const char *pkgdb_cache_getattr(struct pkg *, const char *);
-
int pkgdb_cache_dep(struct pkg *, struct pkg *);

-
void pkgdb_cache_update(struct pkgdb *db);
+
/* query */
+
int pkgdb_cache_init(struct pkgdb *);
+
int pkgdb_cache_dep(struct pkg *, struct pkg *);
+
int pkgdb_cache_query(struct pkgdb *, struct pkg *);
+
void pkgdb_cache_free(struct pkgdb *);

#endif