Radish alpha
H
rad:z3QDZAW2FAfuLvihrhiyDC9fAD8G9
HardenedBSD Package Manager
Radicle
Git
Add "clean" subcommand.
jlaffaye committed 14 years ago
commit 75fa8c4d6a0007309518790a29ad3fb7c94e5449
parent b549486
10 files changed +215 -55
modified libpkg/pkg.h
@@ -41,7 +41,7 @@ typedef enum {
} pkgdb_t;

/**
-
 * Specify how an argument should be used by matching functions.
+
 * Specify how an argument should be used by query functions.
 */
typedef enum {
	/**
@@ -66,6 +66,18 @@ typedef enum {
	MATCH_EREGEX
} match_t;

+
/**
+
 * Specify on which field the pattern will be matched uppon.
+
 */
+

+
typedef enum {
+
	FIELD_NONE,
+
	FIELD_ORIGIN,
+
	FIELD_NAME,
+
	FIELD_NAMEVER,
+
	FIELD_COMMENT,
+
	FIELD_DESC
+
} pkgdb_field;

/**
 * The type of package.
@@ -549,11 +561,6 @@ struct pkgdb_it * pkgdb_query_which(struct pkgdb *db, const char *path);
#define PKG_LOAD_CATEGORIES (1<<9)
#define PKG_LOAD_LICENSES (1<<10)

-
#define REPO_SEARCH_NAME 0
-
#define REPO_SEARCH_COMMENT (1<<0)
-
#define REPO_SEARCH_DESCRIPTION (1<<1)
-

-

/**
 * Get the next pkg.
 * @param pkg An allocated struct pkg or a pointer to a NULL pointer. In the
modified libpkg/pkgdb.c
@@ -408,29 +408,55 @@ pkgdb_it_next(struct pkgdb_it *it, struct pkg **pkg_p, int flags)
			pkg_reset(*pkg_p, it->type);
		pkg = *pkg_p;

-
		pkg->rowid = sqlite3_column_int64(it->stmt, 0);
-
		pkg_set(pkg, PKG_ORIGIN, sqlite3_column_text(it->stmt, 1));
-
		pkg_set(pkg, PKG_NAME, sqlite3_column_text(it->stmt, 2));
-
		pkg_set(pkg, PKG_VERSION, sqlite3_column_text(it->stmt, 3));
-
		pkg_set(pkg, PKG_COMMENT, sqlite3_column_text(it->stmt, 4));
-
		pkg_set(pkg, PKG_DESC, sqlite3_column_text(it->stmt, 5));
-
		pkg_set(pkg, PKG_MESSAGE, sqlite3_column_text(it->stmt, 6));
-
		pkg_set(pkg, PKG_ARCH, sqlite3_column_text(it->stmt, 7));
-
		pkg_set(pkg, PKG_OSVERSION, sqlite3_column_text(it->stmt, 8));
-
		pkg_set(pkg, PKG_MAINTAINER, sqlite3_column_text(it->stmt, 9));
-
		pkg_set(pkg, PKG_WWW, sqlite3_column_text(it->stmt, 10));
-
		pkg_set(pkg, PKG_PREFIX, sqlite3_column_text(it->stmt, 11));
-
		pkg_setflatsize(pkg, sqlite3_column_int64(it->stmt, 12));
-
		if (it->type != PKG_REMOTE && it->type != PKG_UPGRADE)
+
		if (it->type == PKG_INSTALLED) {
+
			pkg->rowid = sqlite3_column_int64(it->stmt, 0);
+
			pkg_set(pkg, PKG_ORIGIN, sqlite3_column_text(it->stmt, 1));
+
			pkg_set(pkg, PKG_NAME, sqlite3_column_text(it->stmt, 2));
+
			pkg_set(pkg, PKG_VERSION, sqlite3_column_text(it->stmt, 3));
+
			pkg_set(pkg, PKG_COMMENT, sqlite3_column_text(it->stmt, 4));
+
			pkg_set(pkg, PKG_DESC, sqlite3_column_text(it->stmt, 5));
+
			pkg_set(pkg, PKG_MESSAGE, sqlite3_column_text(it->stmt, 6));
+
			pkg_set(pkg, PKG_ARCH, sqlite3_column_text(it->stmt, 7));
+
			pkg_set(pkg, PKG_OSVERSION, sqlite3_column_text(it->stmt, 8));
+
			pkg_set(pkg, PKG_MAINTAINER, sqlite3_column_text(it->stmt, 9));
+
			pkg_set(pkg, PKG_WWW, sqlite3_column_text(it->stmt, 10));
+
			pkg_set(pkg, PKG_PREFIX, sqlite3_column_text(it->stmt, 11));
+
			pkg_setflatsize(pkg, sqlite3_column_int64(it->stmt, 12));
			pkg_set_licenselogic(pkg, sqlite3_column_int64(it->stmt, 13));
+
		}

		if (it->type == PKG_REMOTE) {
-
			pkg->type = PKG_REMOTE;
-
			pkg_setnewflatsize(pkg, sqlite3_column_int64(it->stmt, 11));
+
			pkg->rowid = sqlite3_column_int64(it->stmt, 0);
+
			pkg_set(pkg, PKG_ORIGIN, sqlite3_column_text(it->stmt, 1));
+
			pkg_set(pkg, PKG_NAME, sqlite3_column_text(it->stmt, 2));
+
			pkg_set(pkg, PKG_VERSION, sqlite3_column_text(it->stmt, 3));
+
			pkg_set(pkg, PKG_COMMENT, sqlite3_column_text(it->stmt, 4));
+
			pkg_set(pkg, PKG_DESC, sqlite3_column_text(it->stmt, 5));
+
			pkg_set(pkg, PKG_MESSAGE, sqlite3_column_text(it->stmt, 6));
+
			pkg_set(pkg, PKG_ARCH, sqlite3_column_text(it->stmt, 7));
+
			pkg_set(pkg, PKG_OSVERSION, sqlite3_column_text(it->stmt, 8));
+
			pkg_set(pkg, PKG_MAINTAINER, sqlite3_column_text(it->stmt, 9));
+
			pkg_set(pkg, PKG_WWW, sqlite3_column_text(it->stmt, 10));
+
			pkg_setflatsize(pkg, sqlite3_column_int64(it->stmt, 11));
			pkg_setnewpkgsize(pkg, sqlite3_column_int64(it->stmt, 12));
+
			pkg_set(pkg, PKG_CKSUM, sqlite3_column_text(it->stmt, 13));
+
			pkg_set(pkg, PKG_REPOPATH, sqlite3_column_text(it->stmt, 14));
		}
+

		if (it->type == PKG_UPGRADE) {
-
			pkg->type = PKG_UPGRADE;
+
			pkg->rowid = sqlite3_column_int64(it->stmt, 0);
+
			pkg_set(pkg, PKG_ORIGIN, sqlite3_column_text(it->stmt, 1));
+
			pkg_set(pkg, PKG_NAME, sqlite3_column_text(it->stmt, 2));
+
			pkg_set(pkg, PKG_VERSION, sqlite3_column_text(it->stmt, 3));
+
			pkg_set(pkg, PKG_COMMENT, sqlite3_column_text(it->stmt, 4));
+
			pkg_set(pkg, PKG_DESC, sqlite3_column_text(it->stmt, 5));
+
			pkg_set(pkg, PKG_MESSAGE, sqlite3_column_text(it->stmt, 6));
+
			pkg_set(pkg, PKG_ARCH, sqlite3_column_text(it->stmt, 7));
+
			pkg_set(pkg, PKG_OSVERSION, sqlite3_column_text(it->stmt, 8));
+
			pkg_set(pkg, PKG_MAINTAINER, sqlite3_column_text(it->stmt, 9));
+
			pkg_set(pkg, PKG_WWW, sqlite3_column_text(it->stmt, 10));
+
			pkg_set(pkg, PKG_PREFIX, sqlite3_column_text(it->stmt, 11));
+
			pkg_setflatsize(pkg, sqlite3_column_int64(it->stmt, 12));
			pkg_set(pkg, PKG_NEWVERSION, sqlite3_column_text(it->stmt, 13));
			pkg_setnewflatsize(pkg, sqlite3_column_int64(it->stmt, 14));
			pkg_setnewpkgsize(pkg, sqlite3_column_int64(it->stmt, 15));
@@ -1688,10 +1714,12 @@ pkgdb_query_autoremove(struct pkgdb *db)
}

struct pkgdb_it *
-
pkgdb_rquery(struct pkgdb *db, const char *pattern, match_t match, unsigned int field)
+
pkgdb_rquery(struct pkgdb *db, const char *pattern, match_t match, pkgdb_field field)
{
	sqlite3_stmt *stmt = NULL;
	struct sbuf *sql = sbuf_new_auto();
+
	const char *what;
+
	const char *how;

	assert(pattern != NULL && pattern[0] != '\0');

@@ -1702,40 +1730,51 @@ pkgdb_rquery(struct pkgdb *db, const char *pattern, match_t match, unsigned int

	sbuf_cat(sql, "SELECT p.rowid, p.origin, p.name, p.version, p.comment, "
			"p.desc, p.arch, p.arch, p.osversion, p.maintainer, p.www, "
-
			"p.flatsize, p.pkgsize, p.cksum, p.path FROM remote.packages AS p WHERE ");
+
			"p.flatsize, p.pkgsize, p.cksum, p.path FROM remote.packages AS p");

	switch (match) {
		case MATCH_ALL:
+
			how = NULL;
+
			break;
		case MATCH_EXACT:
-
			sbuf_cat(sql, "p.name LIKE ?1 ");
-
			if (field & REPO_SEARCH_COMMENT)
-
				sbuf_cat(sql, "OR p.comment LIKE ?1 ");
-
			else if (field & REPO_SEARCH_DESCRIPTION)
-
				sbuf_cat(sql, "OR p.desc LIKE ?1 ");
+
			how = "%s = ?1";
			break;
		case MATCH_GLOB:
-
			sbuf_cat(sql, "p.name GLOB ?1 ");
-
			if (field & REPO_SEARCH_COMMENT)
-
				sbuf_cat(sql, "OR p.comment GLOB ?1 ");
-
			else if (field & REPO_SEARCH_DESCRIPTION)
-
				sbuf_cat(sql, "OR p.desc GLOB ?1 ");
+
			how = "%s GLOB ?1";
			break;
		case MATCH_REGEX:
-
			sbuf_cat(sql, "p.name REGEXP ?1 ");
-
			if (field & REPO_SEARCH_COMMENT)
-
				sbuf_cat(sql, "OR p.comment REGEXP ?1 ");
-
			else if (field & REPO_SEARCH_DESCRIPTION)
-
				sbuf_cat(sql, "OR p.desc REGEXP ?1 ");
+
			how = "%s REGEXP ?1";
			break;
		case MATCH_EREGEX:
-
			sbuf_cat(sql, "EREGEXP(?1, p.name) ");
-
			if (field & REPO_SEARCH_COMMENT)
-
				sbuf_cat(sql, "OR EREGEXP(?1, p.comment) ");
-
			else if (field & REPO_SEARCH_DESCRIPTION)
-
				sbuf_cat(sql, "OR EREGEXP(?1, p.desc) ");
+
			how = "EREGEXP(?1, %s)";
+
			break;
+
	}
+

+
	switch(field) {
+
		case FIELD_NONE:
+
			what = NULL;
+
			break;
+
		case FIELD_ORIGIN:
+
			what = "p.origin";
+
			break;
+
		case FIELD_NAME:
+
			what = "p.name";
+
			break;
+
		case FIELD_NAMEVER:
+
			what = "p.name || \"-\" || p.version";
+
			break;
+
		case FIELD_COMMENT:
+
			what = "p.comment";
+
			break;
+
		case FIELD_DESC:
+
			what = "p.desc";
			break;
	}

+
	if (what != NULL && how != NULL) {
+
		sbuf_cat(sql, " WHERE ");
+
		sbuf_printf(sql, how, what);
+
	}
	sbuf_cat(sql, ";");
	sbuf_finish(sql);

modified pkg/Makefile
@@ -2,6 +2,7 @@ PROG= pkg
SRCS=		add.c \
		autoremove.c \
		backup.c \
+
		clean.c \
		create.c \
		delete.c \
		event.c \
added pkg/clean.c
@@ -0,0 +1,104 @@
+
#include <sys/types.h>
+
#include <sys/stat.h>
+

+
#include <err.h>
+
#include <fts.h>
+
#include <pkg.h>
+
#include <stdbool.h>
+
#include <string.h>
+
#include <unistd.h>
+

+
#include "clean.h"
+

+
void
+
usage_clean(void)
+
{
+
	fprintf(stderr, "usage: pkg clean [-n]\n");
+
}
+

+
int
+
exec_clean(int argc, char **argv)
+
{
+
	struct pkgdb *db = NULL;
+
	struct pkgdb_it *it = NULL;
+
	struct pkg *pkg = NULL;
+
	struct pkg *p = NULL;
+
	FTS *fts = NULL;
+
	FTSENT *ent = NULL;
+
	char *cachedir[2];
+
	char *repopath;
+
	bool to_delete;
+
	int retcode = 1;
+
	int ret;
+

+
	(void)argc;
+
	(void)argv;
+

+
	cachedir[0] = __DECONST(char*, pkg_config("PKG_CACHEDIR"));
+
	cachedir[1] = NULL;
+

+
	if (pkgdb_open(&db, PKGDB_REMOTE) != EPKG_OK) {
+
		goto cleanup;
+
	}
+

+
	if ((fts = fts_open(cachedir, FTS_PHYSICAL, NULL)) == NULL) {
+
		warn("fts_open(%s)", cachedir[0]);
+
		goto cleanup;
+
	}
+

+
	while ((ent = fts_read(fts)) != NULL) {
+
		if (ent->fts_info != FTS_F)
+
			continue;
+

+
		repopath = ent->fts_path + strlen(cachedir[0]);
+
		if (repopath[0] == '/')
+
			repopath++;
+

+
		if (pkg_open(&pkg, ent->fts_path) != EPKG_OK) {
+
			warnx("skipping %s", ent->fts_path);
+
			continue;
+
		}
+

+
		it = pkgdb_rquery(db, pkg_get(pkg, PKG_ORIGIN), MATCH_EXACT,
+
							FIELD_ORIGIN);
+

+
		if (it == NULL) {
+
			warnx("skipping %s", ent->fts_path);
+
			continue;
+
		}
+

+
		ret = pkgdb_it_next(it, &p, PKG_LOAD_BASIC);
+
		to_delete = false;
+
		if (ret == EPKG_FATAL) {
+
			warnx("skipping %s", ent->fts_path);
+
			continue;
+
		} else if (ret == EPKG_END) {
+
			to_delete = true;
+
			printf("%s does not exist anymore, deleting\n", repopath);
+
		} else if (strcmp(repopath, pkg_get(p, PKG_REPOPATH))) {
+
			printf("%s is out-of-date, deleting\n", repopath);
+
			to_delete = true;
+
		}
+

+
		if (to_delete == true) {
+
			if (unlink(ent->fts_path) != 0)
+
				warn("unlink(%s)", ent->fts_path);
+
		}
+

+
		pkgdb_it_free(it);
+
	}
+

+
	retcode = 0;
+

+
	cleanup:
+
	if (pkg != NULL)
+
		pkg_free(pkg);
+
	if (p != NULL)
+
		pkg_free(p);
+
	if (fts != NULL)
+
		fts_close(fts);
+
	if (db != NULL)
+
		pkgdb_close(db);
+

+
	return (retcode);
+
}
added pkg/clean.h
@@ -0,0 +1,7 @@
+
#ifndef _CLEAN_H
+
#define _CLEAN_H
+

+
int exec_clean(int, char **);
+
void usage_clean(void);
+
#endif
+

modified pkg/event.c
@@ -68,5 +68,6 @@ event_callback(void *data __unused, struct pkg_event *ev)
	default:
		break;
	}
+
	printf("at %s:%d\n", ev->file, ev->line);
	return 0;
}
modified pkg/install.c
@@ -73,7 +73,7 @@ exec_install(int argc, char **argv)
	}

	for (i = 0; i < argc; i++) {
-
		if ((it = pkgdb_rquery(db, argv[i], match, REPO_SEARCH_NAME)) == NULL) {
+
		if ((it = pkgdb_rquery(db, argv[i], match, FIELD_NAME)) == NULL) {
			retcode = EPKG_FATAL;
			goto cleanup;
		}
modified pkg/main.c
@@ -15,6 +15,7 @@
#include "add.h"
#include "autoremove.h"
#include "backup.h"
+
#include "clean.h"
#include "create.h"
#include "delete.h"
#include "event.h"
@@ -40,6 +41,7 @@ static struct commands {
	{ "add", exec_add, usage_add},
	{ "autoremove", exec_autoremove, usage_autoremove},
	{ "backup", exec_backup, usage_backup},
+
	{ "clean", exec_clean, usage_clean},
	{ "create", exec_create, usage_create},
	{ "delete", exec_delete, usage_delete},
	{ "help", exec_help, usage_help},
modified pkg/search.c
@@ -21,7 +21,7 @@ exec_search(int argc, char **argv)
	char *pattern;
	match_t match = MATCH_EXACT;
	int  retcode = EPKG_OK;
-
	unsigned int field = REPO_SEARCH_NAME;
+
	pkgdb_field field = FIELD_NAME;
	int ch;
	char size[7];
	struct pkgdb *db = NULL;
@@ -40,10 +40,10 @@ exec_search(int argc, char **argv)
				match = MATCH_EREGEX;
				break;
			case 'c':
-
				field |= REPO_SEARCH_COMMENT;
+
				field = FIELD_COMMENT;
				break;
			case 'd':
-
				field |= REPO_SEARCH_DESCRIPTION;
+
				field = FIELD_DESC;
				break;
			default:
				usage_search();
modified pkg/upgrade.c
@@ -35,12 +35,6 @@ exec_upgrade(int argc, char **argv)
	char size[7];
	int ch, yes = 0;

-
	(void) argv;
-
	if (argc < 2) {
-
		usage_upgrade();
-
		return (EX_USAGE);
-
	}
-

	if (geteuid() != 0) {
		warnx("upgrading can only be done as root");
		return (EX_NOPERM);
@@ -58,6 +52,11 @@ exec_upgrade(int argc, char **argv)
	argc -= optind;
	argv += optind;

+
	if (argc != 0) {
+
		usage_upgrade();
+
		return (EX_USAGE);
+
	}
+

	if (pkgdb_open(&db, PKGDB_REMOTE) != EPKG_OK) {
		return (EX_IOERR);
	}