Radish alpha
H
rad:z3QDZAW2FAfuLvihrhiyDC9fAD8G9
HardenedBSD Package Manager
Radicle
Git
Implement @include for plist
Baptiste Daroussin committed 5 years ago
commit 01b4ca5abbd57ba80b456b40db879bf640b15a70
parent 1cca123
3 files changed +95 -1
modified libpkg/pkg_ports.c
@@ -60,6 +60,7 @@ static int config(struct plist *, char *, struct file_attr *);
/* compat with old packages */
static int name_key(struct plist *, char *, struct file_attr *);
static int pkgdep(struct plist *, char *, struct file_attr *);
+
static int include_plist(struct plist *, char *, struct file_attr *);

static struct action_cmd {
	const char *name;
@@ -702,6 +703,7 @@ static struct keyact {
	{ "dir", dir },
	{ "dirrm", dirrm },
	{ "dirrmtry", dirrm },
+
	{ "include", include_plist },
	{ "mode", setmod },
	{ "owner", setowner },
	{ "group", setgroup },
@@ -1189,6 +1191,7 @@ plist_new(struct pkg *pkg, const char *stage)
	if (p == NULL)
		return (NULL);

+
	p->plistdirfd = -1;
	p->stagefd = open(stage ? stage : "/", O_DIRECTORY | O_CLOEXEC);
	if (p->stagefd == -1) {
		free(p);
@@ -1223,6 +1226,8 @@ plist_free(struct plist *p)

	if (p->stagefd != -1)
		close(p->stagefd);
+
	if (p->plistdirfd != -1)
+
		close(p->plistdirfd);

	HASH_FREE(p->keywords, keyword_free);

@@ -1261,10 +1266,60 @@ plist_parse(struct plist *pplist, FILE *f)
	return (rc);
}

+
static int
+
open_directory_of(const char *file)
+
{
+
	char path[MAXPATHLEN];
+
	char *walk;
+

+
	if (strchr(file, '/') == NULL) {
+
		if (getcwd(path, MAXPATHLEN) == NULL) {
+
			pkg_emit_error("Unable to determine current location");
+
			return (-1);
+
		}
+
		return (open(path, O_DIRECTORY));
+
	}
+
	strlcpy(path, file, sizeof(path));
+
	walk = strrchr(path, '/');
+
	*walk = '\0';
+
	return (open(path, O_DIRECTORY));
+
}
+

+
int
+
include_plist(struct plist *p, char *name, struct file_attr * __unused)
+
{
+
	FILE *f;
+
	int fd;
+
	int rc;
+

+
	if (p->in_include) {
+
		pkg_emit_error("Inside in @include it is not allowed to reuse @include");
+
		return (EPKG_FATAL);
+
	}
+
	p->in_include = true;
+

+
	fd = openat(p->plistdirfd, name, O_RDONLY);
+
	if (fd == -1) {
+
		pkg_emit_errno("Inpossible to include", name);
+
		return (EPKG_FATAL);
+
	}
+
	f = fdopen(fd, "r");
+
	if (f == NULL) {
+
		pkg_emit_errno("Inpossible to include", name);
+
		close(fd);
+
		return (EPKG_FATAL);
+
	}
+

+
	rc = plist_parse(p, f);
+

+
	fclose(f);
+
	return (rc);
+
}
+

int
ports_parse_plist(struct pkg *pkg, const char *plist, const char *stage)
{
-
	int ret, rc = EPKG_OK;
+
	int rc = EPKG_OK;
	struct plist *pplist;
	FILE *plist_f;

@@ -1274,6 +1329,12 @@ ports_parse_plist(struct pkg *pkg, const char *plist, const char *stage)
	if ((pplist = plist_new(pkg, stage)) == NULL)
		return (EPKG_FATAL);

+
	pplist->plistdirfd = open_directory_of(plist);
+
	if (pplist->plistdirfd == -1) {
+
		pkg_emit_error("impossible to open the directory where the plist is", plist);
+
		plist_free(pplist);
+
		return (EPKG_FATAL);
+
	}
	if ((plist_f = fopen(plist, "r")) == NULL) {
		pkg_emit_error("Unable to open plist file: %s", plist);
		plist_free(pplist);
modified libpkg/private/pkg.h
@@ -613,6 +613,8 @@ struct plist {
	char last_file[MAXPATHLEN];
	const char *stage;
	int stagefd;
+
	bool in_include;
+
	int plistdirfd;
	char prefix[MAXPATHLEN];
	UT_string *pre_install_buf;
	UT_string *post_install_buf;
modified tests/frontend/create.sh
@@ -17,6 +17,7 @@ tests_init \
	create_from_plist_pkg_descr \
	create_from_plist_hash \
	create_from_plist_with_keyword_and_message \
+
	create_from_plist_include \
	create_with_hardlink \
	create_no_clobber \
	time
@@ -506,3 +507,33 @@ create_no_clobber_body()
	after=$(ls -l test-1.txz)
	[ "$before" = "$after" ] || atf_fail "Package was recreated"
}
+

+
create_from_plist_include_body()
+
{
+
	genmanifest
+
	cat << EOF >> test.plist
+
file1
+
@include other-plist
+
file2
+
EOF
+
	cat <<EOF >> other-plist
+
file3
+
EOF
+

+
	touch file1
+
	touch file2
+
	touch file3
+

+
	atf_check \
+
		-s exit:0 \
+
		pkg create -o ${TMPDIR} -m . -p test.plist -r .
+

+
	atf_check -o inline:"/file1\n/file3\n/file2\n" pkg info -ql -F test*.txz
+
	cat << EOF >> other-plist
+
@include test.plist
+
EOF
+
	atf_check \
+
		-e inline:"pkg: Inside in @include it is not allowed to reuse @include\n" \
+
		-s exit:1 \
+
		pkg create -o ${TMPDIR} -m . -p test.plist -r .
+
}