Radish alpha
H
rad:z3QDZAW2FAfuLvihrhiyDC9fAD8G9
HardenedBSD Package Manager
Radicle
Git
Real support for dirrmtry
Baptiste Daroussin committed 14 years ago
commit efacaf51ff6871d93435a933c9fd95a7040db389
parent e8eae19
9 files changed +103 -22
modified libpkg/db_upgrades.h
@@ -109,6 +109,10 @@ static struct db_upgrades {
		"UNIQUE(package_id, group_id)"
	");"
	},
+
	{6,
+
	"ALTER TABLE pkg_directories ADD try INTEGER;"
+
	"UPDATE pkg_directories SET try = 1;"
+
	},

	/* Mark the end of the array */
	{ -1, NULL },
modified libpkg/pkg.c
@@ -595,12 +595,12 @@ pkg_addcategory(struct pkg *pkg, const char *name)
}

int
-
pkg_adddir(struct pkg *pkg, const char *path)
+
pkg_adddir(struct pkg *pkg, const char *path, int try)
{
-
	return(pkg_adddir_attr(pkg, path, NULL, NULL, 0));
+
	return(pkg_adddir_attr(pkg, path, NULL, NULL, 0, try));
}
int
-
pkg_adddir_attr(struct pkg *pkg, const char *path, const char *uname, const char *gname, mode_t perm)
+
pkg_adddir_attr(struct pkg *pkg, const char *path, const char *uname, const char *gname, mode_t perm, int try)
{
	struct pkg_dir *d = NULL;

@@ -626,6 +626,8 @@ pkg_adddir_attr(struct pkg *pkg, const char *path, const char *uname, const char
	if (perm != 0)
		d->perm = perm;

+
	d->try = try;
+

	STAILQ_INSERT_TAIL(&pkg->dirs, d, next);

	return (EPKG_OK);
modified libpkg/pkg.h
@@ -410,7 +410,7 @@ int pkg_addfile_attr(struct pkg *pkg, const char *path, const char *sha256, cons
 * Add a path
 * @return An error code.
 */
-
int pkg_adddir(struct pkg *pkg, const char *path);
+
int pkg_adddir(struct pkg *pkg, const char *path, int try);

/**
 * Allocate a new struct pkg_file and add it to the files of pkg;
@@ -420,7 +420,7 @@ int pkg_adddir(struct pkg *pkg, const char *path);
 * @param perm the permission
 * @return An error code.
 */
-
int pkg_adddir_attr(struct pkg *pkg, const char *path, const char *uname, const char *gname, mode_t perm);
+
int pkg_adddir_attr(struct pkg *pkg, const char *path, const char *uname, const char *gname, mode_t perm, int try);

/**
 * Add a category
@@ -498,6 +498,7 @@ const char *pkg_file_path(struct pkg_file *);
const char *pkg_file_sha256(struct pkg_file *);

const char *pkg_dir_path(struct pkg_dir *);
+
int pkg_dir_try(struct pkg_dir *);

const char *pkg_category_name(struct pkg_category *);

modified libpkg/pkg_attributes.c
@@ -85,6 +85,7 @@ pkg_dir_new(struct pkg_dir **d)
		return (EPKG_FATAL);

	(*d)->perm = 0;
+
	(*d)->try = 0;

	return (EPKG_OK);
}
@@ -102,6 +103,12 @@ pkg_dir_path(struct pkg_dir *d)
}

int
+
pkg_dir_try(struct pkg_dir *d)
+
{
+
	return (d->try);
+
}
+

+
int
pkg_category_new(struct pkg_category **c)
{
	if (( *c = calloc(1, sizeof(struct pkg_category))) == NULL)
modified libpkg/pkg_delete.c
@@ -130,8 +130,13 @@ pkg_delete_dirs(struct pkgdb *db, struct pkg *pkg, int force)
		if (nbpackage > 1)
			continue;

-
		if (rmdir(pkg_dir_path(dir)) == -1 && errno != ENOTEMPTY && force != 1)
-
			pkg_emit_errno("rmdir", pkg_dir_path(dir));
+
		if (pkg_dir_try(dir)) {
+
			if (rmdir(pkg_dir_path(dir)) == -1 && errno != ENOTEMPTY && force != 1)
+
				pkg_emit_errno("rmdir", pkg_dir_path(dir));
+
		} else {
+
			if (rmdir(pkg_dir_path(dir)) == -1 && force != 1)
+
				pkg_emit_errno("rmdir", pkg_dir_path(dir));
+
		}
	}

	return (EPKG_OK);
modified libpkg/pkg_manifest.c
@@ -30,6 +30,7 @@
#define PKG_OPTIONS -11
#define PKG_USERS -12
#define PKG_GROUPS -13
+
#define PKG_DIRECTORIES -14

static int pkg_set_from_node(struct pkg *, yaml_node_t *, yaml_document_t *, int);
static int pkg_set_flatsize_from_node(struct pkg *, yaml_node_t *, yaml_document_t *, int);
@@ -59,6 +60,7 @@ static struct manifest_key {
	{ "conflicts", PKG_CONFLICTS, YAML_SEQUENCE_NODE, parse_sequence},
	{ "files", PKG_FILES, YAML_MAPPING_NODE, parse_mapping},
	{ "dirs", PKG_DIRS, YAML_SEQUENCE_NODE, parse_sequence},
+
	{ "directories", PKG_DIRECTORIES, YAML_MAPPING_NODE, parse_mapping},
	{ "flatsize", -1, YAML_SCALAR_NODE, pkg_set_flatsize_from_node},
	{ "licenselogic", -1, YAML_SCALAR_NODE, pkg_set_licenselogic_from_node},
	{ "licenses", PKG_LICENSES, YAML_SEQUENCE_NODE, parse_sequence},
@@ -239,7 +241,7 @@ parse_sequence(struct pkg * pkg, yaml_node_t *node, yaml_document_t *doc, int at
				break;
			case PKG_DIRS:
				if (val->type == YAML_SCALAR_NODE && val->data.scalar.length > 0)
-
					pkg_adddir(pkg, val->data.scalar.value);
+
					pkg_adddir(pkg, val->data.scalar.value, 1);
				else if (val->type == YAML_MAPPING_NODE)
					parse_mapping(pkg, val, doc, attr);
				else
@@ -285,6 +287,18 @@ parse_mapping(struct pkg *pkg, yaml_node_t *item, yaml_document_t *doc, int attr
				else
					pkg_set_dirs_from_node(pkg, val, doc, key->data.scalar.value);
				break;
+
			case PKG_DIRECTORIES:
+
				if (val->type == YAML_SCALAR_NODE && val->data.scalar.length > 0) {
+
					if (val->data.scalar.value[0] == 'y')
+
						pkg_adddir(pkg, key->data.scalar.value, 1);
+
					else
+
						pkg_adddir(pkg, key->data.scalar.value, 0);
+
				} else if (val->type == YAML_MAPPING_NODE) {
+
					pkg_set_dirs_from_node(pkg, val, doc, key->data.scalar.value);
+
				} else {
+
					pkg_emit_error("Skipping malformed directories %s",
+
								   key->data.scalar.value);
+
				}
			case PKG_FILES:
				if (val->type == YAML_SCALAR_NODE && val->data.scalar.length > 0) {
					urldecode(key->data.scalar.value, &tmp);
@@ -400,6 +414,7 @@ pkg_set_dirs_from_node(struct pkg *pkg, yaml_node_t *item, yaml_document_t *doc,
	const char *gname = NULL;
	void *set;
	mode_t perm = 0;
+
	int try = 1;

	pair = item->data.mapping.pairs.start;
	while (pair < item->data.mapping.pairs.top) {
@@ -426,6 +441,11 @@ pkg_set_dirs_from_node(struct pkg *pkg, yaml_node_t *item, yaml_document_t *doc,
				pkg_emit_error("Not a valide mode: %s", val->data.scalar.value);
			else
				perm = getmode(set, 0);
+
		} else if (!strcasecmp(key->data.scalar.value, "try")) {
+
			if (val->data.scalar.value[0] == 'n' || val->data.scalar.value[0] == 'y')
+
				try = val->data.scalar.value[0];
+
			else
+
				pkg_emit_error("Wrong value for try: %s, expected 'y' or 'n'");
		} else {
			pkg_emit_error("Skipping unknown key for dir(%s): %s", dirname,
						   key->data.scalar.value);
@@ -434,7 +454,7 @@ pkg_set_dirs_from_node(struct pkg *pkg, yaml_node_t *item, yaml_document_t *doc,
		++pair;
	}

-
	pkg_adddir_attr(pkg, dirname, uname, gname, perm);
+
	pkg_adddir_attr(pkg, dirname, uname, gname, perm, try);

	return (EPKG_OK);
}
@@ -607,6 +627,7 @@ pkg_emit_manifest(struct pkg *pkg, char **dest)
	int depsmap = -1;
	int depkv;
	int files = -1;
+
	int dirs = -1;
	int options = -1;
	int scripts = -1;
	const char *script_types = NULL;
@@ -712,8 +733,15 @@ pkg_emit_manifest(struct pkg *pkg, char **dest)
	}

	seq = -1;
-
	while (pkg_dirs(pkg, &dir) == EPKG_OK)
-
		manifest_append_seqval(&doc, mapping, &seq, "dirs", pkg_dir_path(dir));
+
	while (pkg_dirs(pkg, &dir) == EPKG_OK) {
+
		if (dirs == -1) {
+
			dirs = yaml_document_add_mapping(&doc, NULL, YAML_BLOCK_MAPPING_STYLE);
+
			yaml_document_append_mapping_pair(&doc, mapping,
+
					yaml_document_add_scalar(&doc, NULL, __DECONST(yaml_char_t*, "directories"), 11, YAML_PLAIN_SCALAR_STYLE),
+
					dirs);
+
		}
+
		manifest_append_kv(dirs, pkg_dir_path(dir), pkg_dir_try(dir) ? "y" : "n");
+
	}

	while (pkg_scripts(pkg, &script) == EPKG_OK) {
		if (scripts == -1) {
modified libpkg/pkg_ports.c
@@ -158,7 +158,7 @@ ports_parse_plist(struct pkg *pkg, char *plist)
								buf+=pmatch[1].rm_eo;
								if (!strcmp(path, "/dev/null"))
									continue;
-
								ret += pkg_adddir_attr(pkg, path, uname, gname, perm);
+
								ret += pkg_adddir_attr(pkg, path, uname, gname, perm, 1);
							}
						} else {
							while (regexec(&preg2, buf, 2, pmatch, 0) == 0) {
@@ -166,7 +166,7 @@ ports_parse_plist(struct pkg *pkg, char *plist)
								buf+=pmatch[1].rm_eo;
								if (!strcmp(path, "/dev/null"))
									continue;
-
								ret += pkg_adddir_attr(pkg, path, uname, gname, perm);
+
								ret += pkg_adddir_attr(pkg, path, uname, gname, perm, 1);
							}
						}

@@ -179,7 +179,7 @@ ports_parse_plist(struct pkg *pkg, char *plist)

				free(cmd);

-
			} else if (STARTS_WITH(plist_p, "@dirrm ")) {
+
			} else if (STARTS_WITH(plist_p, "@dirrm ") || STARTS_WITH(plist_p, "@dirrmtry ")) {

				buf = plist_p;

@@ -201,9 +201,15 @@ ports_parse_plist(struct pkg *pkg, char *plist)

				if (sbuf_len(unexec_scripts) == 0)
					sbuf_cat(unexec_scripts, "#@unexec\n"); /* to be able to regenerate the @unexec in pkg2legacy */
-
				sbuf_printf(unexec_scripts, "#@dirrm %s\n", path);

-
				ret += pkg_adddir_attr(pkg, path, uname, gname, perm);
+
				if (plist_p[6] == 't') {
+
					sbuf_printf(unexec_scripts, "#@unexec /bin/rmdir \"%s\" || true\n", path);
+
					ret += pkg_adddir_attr(pkg, path, uname, gname, perm, 1);
+
				} else {
+
					sbuf_printf(unexec_scripts, "#@dirrm %s\n", path);
+
					ret += pkg_adddir_attr(pkg, path, uname, gname, perm, 0);
+
				}
+


			} else if (STARTS_WITH(plist_p, "@mode")) {
				buf = plist_p;
modified libpkg/pkg_private.h
@@ -73,6 +73,7 @@ struct pkg_dir {
	char uname[MAXLOGNAME +1];
	char gname[MAXLOGNAME +1];
	mode_t perm;
+
	int try;
	STAILQ_ENTRY(pkg_dir) next;
};

modified libpkg/pkgdb.c
@@ -18,7 +18,7 @@
#include "pkg_util.h"

#include "db_upgrades.h"
-
#define DBVERSION 5
+
#define DBVERSION 6

static struct pkgdb_it * pkgdb_it_new(struct pkgdb *, sqlite3_stmt *, int);
static void pkgdb_regex(sqlite3_context *, int, sqlite3_value **, int);
@@ -362,6 +362,7 @@ pkgdb_init(sqlite3 *sdb)
			" ON UPDATE CASCADE,"
		"directory_id INTEGER REFERENCES directories(id) ON DELETE RESTRICT"
			" ON UPDATE RESTRICT,"
+
		"try INTEGER,"
		"PRIMARY KEY (package_id, directory_id)"
	");"
	"CREATE TABLE categories ("
@@ -408,7 +409,7 @@ pkgdb_init(sqlite3 *sdb)
			" ON UPDATE RESTRICT,"
		"UNIQUE(package_id, group_id)"
	");"
-
	"PRAGMA user_version = 5;"
+
	"PRAGMA user_version = 6;"
	"COMMIT;"
	;

@@ -874,15 +875,40 @@ int
pkgdb_loaddirs(struct pkgdb *db, struct pkg *pkg)
{
	const char sql[] = ""
-
		"SELECT path "
+
		"SELECT path, try "
		"FROM pkg_directories, directories "
		"WHERE package_id = ?1 "
		"AND directory_id = directories.id "
		"ORDER by path DESC";
+
	sqlite3_stmt *stmt;
+
	int ret;

	assert(db != NULL && pkg != NULL);

-
	return (loadval(db->sqlite, pkg, sql, PKG_LOAD_DIRS, pkg_adddir, PKG_DIRS));
+
	if (pkg->flags & PKG_LOAD_DIRS)
+
		return (EPKG_OK);
+

+
	if (sqlite3_prepare_v2(db->sqlite, sql, -1, &stmt, NULL) != SQLITE_OK) {
+
		ERROR_SQLITE(db->sqlite);
+
		return (EPKG_FATAL);
+
	}
+

+
	sqlite3_bind_int64(stmt, 1, pkg->rowid);
+

+
	while (( ret = sqlite3_step(stmt)) == SQLITE_ROW) {
+
		pkg_adddir(pkg, sqlite3_column_text(stmt, 0), sqlite3_column_int(stmt, 1));
+
	}
+

+
	sqlite3_finalize(stmt);
+
	if (ret != SQLITE_DONE) {
+
		pkg_list_free(pkg, PKG_DIRS);
+
		ERROR_SQLITE(db->sqlite);
+
		return (EPKG_FATAL);
+
	}
+

+
	pkg->flags |= PKG_LOAD_DIRS;
+

+
	return (EPKG_OK);
}

int
@@ -1155,9 +1181,9 @@ pkgdb_register_pkg(struct pkgdb *db, struct pkg *pkg)
		"INSERT OR ROLLBACK INTO options (option, value, package_id) "
		"VALUES (?1, ?2, ?3);";
	const char sql_dir[] = ""
-
		"INSERT OR ROLLBACK INTO pkg_directories(package_id, directory_id) "
+
		"INSERT OR ROLLBACK INTO pkg_directories(package_id, directory_id, try) "
		"VALUES (?1, "
-
		"(SELECT id FROM directories WHERE path = ?2));";
+
		"(SELECT id FROM directories WHERE path = ?2), ?3);";
	const char sql_cat[] = "INSERT OR IGNORE INTO categories(name) VALUES(?1);";
	const char sql_category[] = ""
		"INSERT OR ROLLBACK INTO pkg_categories(package_id, category_id) "
@@ -1315,6 +1341,7 @@ pkgdb_register_pkg(struct pkgdb *db, struct pkg *pkg)
		sqlite3_bind_text(stmt_dirs, 1, pkg_dir_path(dir), -1, SQLITE_STATIC);
		sqlite3_bind_int64(stmt_dir, 1, package_id);
		sqlite3_bind_text(stmt_dir, 2, pkg_dir_path(dir), -1, SQLITE_STATIC);
+
		sqlite3_bind_int64(stmt_dir, 1, pkg_dir_try(dir));
			
		if ((ret = sqlite3_step(stmt_dirs)) != SQLITE_DONE) {
			ERROR_SQLITE(s);