Radish alpha
H
HardenedBSD Package Manager
Radicle
Git (anonymous pull)
Log in to clone via SSH
new command repo this commands scans for packages within a repository and create a sqlite database for this packages.
Baptiste Daroussin committed 15 years ago
commit 7a371e5883b38fb5efc3658e4183cc46d7bb4960
parent 2708e572153713554952b7c951c7407a3dd7bbe3
13 files changed +262 -6
modified libpkg/Makefile
@@ -17,6 +17,7 @@ SRCS= pkg.c \
		pkg_manifest.c \
		pkg_option.c \
		pkg_ports.c \
+
		pkg_repo.c \
		pkg_version.c \
		util.c

modified libpkg/pkg.c
@@ -266,6 +266,7 @@ pkg_open(const char *path, struct pkg **pkg_p, int query_flags)

		pkg_file_new(&file);
		strlcpy(file->path, archive_entry_pathname(ae), sizeof(file->path));
+
		file->size = archive_entry_size(ae);
		array_append(&pkg->files, file);
	}

@@ -273,7 +274,7 @@ pkg_open(const char *path, struct pkg **pkg_p, int query_flags)
		goto error;

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

error:
	archive_read_finish(a);
@@ -504,7 +505,7 @@ pkg_adddep(struct pkg *pkg, const char *name, const char *origin, const char *ve
}

int
-
pkg_addfile(struct pkg *pkg, const char *path, const char *sha256)
+
pkg_addfile(struct pkg *pkg, const char *path, const char *sha256, size_t sz)
{
	struct pkg_file *file;
	if (path == NULL || path[0] == '\0')
@@ -517,6 +518,8 @@ pkg_addfile(struct pkg *pkg, const char *path, const char *sha256)
	if (sha256 != NULL)
		strlcpy(file->sha256, sha256, sizeof(file->sha256));

+
	file->size = sz;
+

	array_init(&pkg->files, 10);
	array_append(&pkg->files, file);

modified libpkg/pkg.h
@@ -1,6 +1,8 @@
#ifndef _PKG_H
#define _PKG_H

+
#include <sys/types.h>
+

struct pkg;
struct pkg_file;
struct pkg_conflict;
@@ -88,7 +90,7 @@ int pkg_extract(const char *filename);
int pkg_set(struct pkg *, pkg_attr, const char *);
int pkg_set_from_file(struct pkg *, pkg_attr, const char *);
int pkg_adddep(struct pkg *, const char *, const char *, const char *);
-
int pkg_addfile(struct pkg *, const char *, const char *);
+
int pkg_addfile(struct pkg *, const char *, const char *, size_t);
int pkg_addconflict(struct pkg *, const char *);
int pkg_addexec(struct pkg *, const char *, pkg_exec_t);
int pkg_addscript(struct pkg *, const char *);
@@ -104,6 +106,7 @@ void pkg_file_reset(struct pkg_file *);
void pkg_file_free(struct pkg_file *);
const char * pkg_file_path(struct pkg_file *);
const char * pkg_file_sha256(struct pkg_file *);
+
size_t pkg_file_size(struct pkg_file *);

/* pkg_conflict */
int pkg_conflict_new(struct pkg_conflict **);
@@ -131,6 +134,9 @@ void pkg_option_free(struct pkg_option *);
const char *pkg_option_opt(struct pkg_option *);
const char *pkg_option_value(struct pkg_option *);

+
/* pkg_repo */
+
int pkg_create_repo(const char *, void (*)(struct pkg *, void *), void *);
+

/* pkgdb */
int pkgdb_open(struct pkgdb **);
void pkgdb_close(struct pkgdb *);
modified libpkg/pkg_file.c
@@ -15,11 +15,19 @@ pkg_file_sha256(struct pkg_file *file)
	return (file->sha256);
}

+
size_t
+
pkg_file_size(struct pkg_file *file)
+
{
+
	return (file->size);
+
}
+

int
pkg_file_new(struct pkg_file **file)
{
	if ((*file = calloc(1, sizeof(struct pkg_file))))
		return (-1);
+

+
	(*file)->size = -1;
	return (0);
}

@@ -28,6 +36,7 @@ pkg_file_reset(struct pkg_file *file)
{
	file->path[0] = '\0';
	file->sha256[0] = '\0';
+
	file->size = -1;
}

void
modified libpkg/pkg_ports.c
@@ -86,7 +86,7 @@ ports_parse_plist(struct pkg *pkg, char *plist, const char *prefix)
				p = NULL;
			}

-
			ret += pkg_addfile(pkg, path, p);
+
			ret += pkg_addfile(pkg, path, p, -1);
		}

		plist_p += next + 1;
modified libpkg/pkg_private.h
@@ -47,6 +47,7 @@ struct pkg_exec {
struct pkg_file {
	char path[MAXPATHLEN];
	char sha256[65];
+
	size_t size;
};

struct pkg_option {
added libpkg/pkg_repo.c
@@ -0,0 +1,170 @@
+
#include <sys/types.h>
+
#include <sys/stat.h>
+
#include <fnmatch.h>
+
#include <sqlite3.h>
+
#include <fts.h>
+
#include <unistd.h>
+
#include <stdio.h>
+
#include <string.h>
+

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

+

+
int
+
pkg_create_repo(const char *path, void (progress)(struct pkg *pkg, void *data), void *data)
+
{
+
	FTS	*fts;
+
	FTSENT	*ent;
+

+
	struct stat st;
+
	struct pkg *pkg, **deps;
+
	struct pkg_file **files;
+
	char *ext = NULL;
+
	sqlite3 *sqlite;
+
	sqlite3_stmt *stmt_files;
+
	sqlite3_stmt *stmt_deps;
+
	sqlite3_stmt *stmt_pkg;
+

+
	int i;
+

+
	char *repopath[2], repodb[MAXPATHLEN];
+

+
	const char initsql[] = ""
+
		"CREATE TABLE packages ("
+
			"origin TEXT PRIMARY KEY,"
+
			"name TEXT,"
+
			"version TEXT,"
+
			"comment TEXT,"
+
			"desc TEXT,"
+
			"arch TEXT,"
+
			"osversion TEXT,"
+
			"maintainer TEXT,"
+
			"www TEXT,"
+
			"pkg_format_version INTEGER,"
+
			"size INTEGER"
+
		");"
+
		"CREATE TABLE deps ("
+
			"origin TEXT,"
+
			"name TEXT,"
+
			"version TEXT,"
+
			"package_id TEXT REFERENCES packages(origin),"
+
			"PRIMARY KEY (package_id, origin)"
+
		");"
+
		"CREATE INDEX deps_origin ON deps (origin);"
+
		"CREATE INDEX deps_package ON deps (package_id);"
+
		"CREATE TABLE files ("
+
			"path TEXT,"
+
			"size INTEGER,"
+
			"package_id TEXT REFERENCES packages(origin),"
+
			"PRIMARY KEY (package_id, path)"
+
		");"
+
		"CREATE INDEX files_packages ON files (package_id);"
+
		"CREATE INDEX files_path ON files (path);"
+
		;
+

+

+
	if (!is_dir(path))
+
		return (EPKG_FATAL);
+

+
	repopath[0] = (char *)path;
+
	repopath[1] = NULL;
+

+
	snprintf(repodb, MAXPATHLEN, "%s/repo.db", path);
+

+
	if (stat(repodb, &st) != -1)
+
		if (unlink(repodb) != 0)
+
			return (EPKG_FATAL);
+

+
	if (sqlite3_open(repodb, &sqlite) != SQLITE_OK)
+
		return (EPKG_FATAL);
+

+

+
	if (sqlite3_exec(sqlite, initsql, NULL, NULL, NULL) != SQLITE_OK)
+
		return (EPKG_FATAL);
+

+
	sqlite3_exec(sqlite, "BEGIN TRANSACTION;", NULL, NULL, NULL);
+

+
	sqlite3_prepare(sqlite, "INSERT INTO packages (origin, name, version, comment, desc, arch, osversion, maintainer, www, pkg_format_version, size) "
+
			"values (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11);",
+
			-1, &stmt_pkg, NULL);
+
	sqlite3_prepare(sqlite, "INSERT INTO deps (origin, name, version, package_id) "
+
			"values (?1, ?2, ?3, ?4);",
+
			-1, &stmt_deps, NULL);
+
	sqlite3_prepare(sqlite, "INSERT INTO files (path, size, package_id) "
+
			"values (?1, ?2, ?3);",
+
			-1, &stmt_files, NULL);
+

+
	fts = fts_open(repopath, FTS_PHYSICAL, NULL);
+

+
	while ((ent = fts_read(fts)) != NULL) {
+
		/* skip everything that is not a file */
+
		if (ent->fts_info != FTS_F)
+
			continue;
+

+
		ext = strrchr(ent->fts_name, '.');
+
		if (strcmp(ext, ".tgz") != 0 &&
+
				strcmp(ext, ".tbz") != 0 &&
+
				strcmp(ext, ".txz") != 0 &&
+
				strcmp(ext, ".tar") != 0)
+
			continue;
+

+
		if (pkg_open(ent->fts_path, &pkg, 0) != EPKG_OK)
+
			continue;
+

+
		if (progress != NULL)
+
			progress(pkg, data);
+
		sqlite3_bind_text(stmt_pkg, 1, pkg_get(pkg, PKG_ORIGIN), -1, SQLITE_TRANSIENT);
+
		sqlite3_bind_text(stmt_pkg, 2, pkg_get(pkg, PKG_NAME), -1, SQLITE_TRANSIENT);
+
		sqlite3_bind_text(stmt_pkg, 3, pkg_get(pkg, PKG_VERSION), -1, SQLITE_TRANSIENT);
+
		sqlite3_bind_text(stmt_pkg, 4, pkg_get(pkg, PKG_COMMENT), -1, SQLITE_TRANSIENT);
+
		sqlite3_bind_text(stmt_pkg, 5, pkg_get(pkg, PKG_DESC), -1, SQLITE_TRANSIENT);
+
		sqlite3_bind_text(stmt_pkg, 6, pkg_get(pkg, PKG_ARCH), -1, SQLITE_TRANSIENT);
+
		sqlite3_bind_text(stmt_pkg, 7, pkg_get(pkg, PKG_OSVERSION), -1, SQLITE_TRANSIENT);
+
		sqlite3_bind_text(stmt_pkg, 8, pkg_get(pkg, PKG_MAINTAINER), -1, SQLITE_TRANSIENT);
+
		sqlite3_bind_text(stmt_pkg, 9, pkg_get(pkg, PKG_WWW), -1, SQLITE_TRANSIENT);
+
		sqlite3_bind_int(stmt_pkg, 11, ent->fts_statp->st_size);
+

+
		sqlite3_step(stmt_pkg);
+
		sqlite3_reset(stmt_pkg);
+

+
		if ((deps = pkg_deps(pkg)) != NULL) {
+
			for (i = 0; deps[i] != NULL; i++) {
+
				sqlite3_bind_text(stmt_deps, 1, pkg_get(deps[i], PKG_ORIGIN), -1, SQLITE_TRANSIENT);
+
				sqlite3_bind_text(stmt_deps, 2, pkg_get(deps[i], PKG_NAME), -1, SQLITE_TRANSIENT);
+
				sqlite3_bind_text(stmt_deps, 3, pkg_get(deps[i], PKG_VERSION), -1, SQLITE_TRANSIENT);
+
				sqlite3_bind_text(stmt_deps, 4, pkg_get(pkg, PKG_ORIGIN), -1, SQLITE_TRANSIENT);
+

+
				sqlite3_step(stmt_deps);
+
				sqlite3_reset(stmt_deps);
+
			}
+
		}
+

+
		if ((files = pkg_files(pkg)) != NULL) {
+
			for (i = 0; files[i] != NULL; i++) {
+
				sqlite3_bind_text(stmt_files, 1, pkg_file_path(files[i]), -1, SQLITE_TRANSIENT);
+
				sqlite3_bind_int(stmt_files, 2, pkg_file_size(files[i]));
+
				sqlite3_bind_text(stmt_files, 3, pkg_get(pkg, PKG_ORIGIN), -1, SQLITE_TRANSIENT);
+

+
				sqlite3_step(stmt_files);
+
				sqlite3_reset(stmt_files);
+
			}
+
		}
+

+
		pkg_free(pkg);
+
	}
+

+
	sqlite3_finalize(stmt_pkg);
+
	sqlite3_finalize(stmt_files);
+
	sqlite3_finalize(stmt_deps);
+

+
	sqlite3_exec(sqlite, "COMMIT;", NULL, NULL, NULL);
+

+
	sqlite3_close(sqlite);
+

+
	if (progress != NULL)
+
		progress(NULL, data);
+

+
	return (EPKG_OK);
+
}
modified libpkg/util.c
@@ -293,3 +293,10 @@ file_fetch(const char *url, const char *dest)

	return (0);
}
+

+
int
+
is_dir(const char *path) {
+
	struct stat st;
+

+
	return (stat(path, &st) == 0 && S_ISDIR(st.st_mode));
+
}
modified libpkg/util.h
@@ -26,5 +26,6 @@ off_t file_to_buffer(const char *path, char **buffer);
int format_exec_cmd(char **, const char *, const char *, const char *);
int split_chr(char *, char);
int file_fetch(const char *, const char *);
+
int is_dir(const char *path);

#endif
modified pkg/Makefile
@@ -6,7 +6,8 @@ SRCS= main.c \
	register.c \
	version.c \
	add.c \
-
	create.c
+
	create.c \
+
	repo.c

CFLAGS+=	-I${.CURDIR}/../libpkg
LDADD+=	-L${.CURDIR}/../external -L../libpkg -lpkg -lutil
modified pkg/main.c
@@ -12,6 +12,7 @@
#include "add.h"
#include "version.h"
#include "register.h"
+
#include "repo.h"

static void usage(void);
static void usage_help(void);
@@ -28,7 +29,7 @@ static struct commands {
	{ "help", exec_help, usage_help},
	{ "info", exec_info, usage_info},
	{ "register", exec_register, usage_register},
-
	{ "repo", NULL, NULL},
+
	{ "repo", exec_repo, usage_repo},
	{ "update", NULL, NULL},
	{ "upgrade", NULL, NULL},
	{ "version", exec_version, usage_version},
added pkg/repo.c
@@ -0,0 +1,49 @@
+
#include <sysexits.h>
+
#include <stdio.h>
+
#include <string.h>
+

+
#include <pkg.h>
+

+
#include "repo.h"
+

+
void
+
usage_repo(void)
+
{
+
	fprintf(stderr, "repo ...");
+
}
+

+
static void
+
progress(struct pkg *pkg, void *data) {
+

+
	char buf[BUFSIZ], pattern[BUFSIZ];
+
	int *len = (int *)data;
+
	int newlen;
+

+
	if (pkg != NULL) {
+
		snprintf(buf, BUFSIZ, "%s->%s", pkg_get(pkg, PKG_NAME), pkg_get(pkg, PKG_VERSION));
+
		newlen = strlen(buf);
+

+
		if (newlen > *len) {
+
			*len = newlen;
+
		}
+

+
		snprintf(pattern, BUFSIZ, "\rAdding: %%-%ds", *len);
+

+
		printf(pattern, buf);
+
	} else {
+
		snprintf(pattern, BUFSIZ, "\rdone: %%-%ds", *len);
+
		printf(pattern, "");
+
	}
+
}
+

+
int
+
exec_repo(int argc, char **argv)
+
{
+
	int len=0;
+
	if (argc != 2) {
+
		usage_repo();
+
		return (EX_USAGE);
+
	}
+

+
	return (pkg_create_repo(argv[1], progress, &len));
+
}
added pkg/repo.h
@@ -0,0 +1,7 @@
+
#ifndef _REPO_H
+
#define _REPO_H
+

+
int exec_repo(int, char **);
+
void usage_repo(void);
+

+
#endif