Radish alpha
H
rad:z3QDZAW2FAfuLvihrhiyDC9fAD8G9
HardenedBSD Package Manager
Radicle
Git
Simplify a bit package creation using *at function
Baptiste Daroussin committed 11 years ago
commit b6f7a422ce017cff4c5d62ddffede0a2308212f7
parent 47f0d8e
5 files changed +147 -37
modified libpkg/pkg.c
@@ -394,6 +394,29 @@ pkg_set_mtree(struct pkg *pkg, const char *mtree) {
	return (pkg_set(pkg, PKG_MTREE, mtree));
}

+
int
+
pkg_set_from_fileat(int fd, struct pkg *pkg, pkg_attr attr, const char *path,
+
    bool trimcr)
+
{
+
	char *buf = NULL;
+
	off_t size = 0;
+
	int ret = EPKG_OK;
+

+
	assert(pkg != NULL);
+
	assert(path != NULL);
+

+
	if ((ret = file_to_bufferat(fd, path, &buf, &size)) !=  EPKG_OK)
+
		return (ret);
+

+
	while (trimcr && buf[strlen(buf) - 1] == '\n')
+
		buf[strlen(buf) - 1] = '\0';
+

+
	ret = pkg_set(pkg, attr, buf);
+

+
	free(buf);
+

+
	return (ret);
+
}

int
pkg_set_from_file(struct pkg *pkg, pkg_attr attr, const char *path, bool trimcr)
@@ -839,6 +862,61 @@ pkg_addscript(struct pkg *pkg, const char *data, pkg_script type)
}

int
+
pkg_addscript_fileat(int fd, struct pkg *pkg, const char *filename)
+
{
+
	char *data;
+
	pkg_script type;
+
	int ret = EPKG_OK;
+
	off_t sz = 0;
+

+
	assert(pkg != NULL);
+
	assert(filename != NULL);
+

+
	pkg_debug(1, "Adding script from: '%s'", filename);
+

+
	if ((ret = file_to_bufferat(fd, filename, &data, &sz)) != EPKG_OK)
+
		return (ret);
+

+
	if (strcmp(filename, "pkg-pre-install") == 0 ||
+
			strcmp(filename, "+PRE_INSTALL") == 0) {
+
		type = PKG_SCRIPT_PRE_INSTALL;
+
	} else if (strcmp(filename, "pkg-post-install") == 0 ||
+
			strcmp(filename, "+POST_INSTALL") == 0) {
+
		type = PKG_SCRIPT_POST_INSTALL;
+
	} else if (strcmp(filename, "pkg-install") == 0 ||
+
			strcmp(filename, "+INSTALL") == 0) {
+
		type = PKG_SCRIPT_INSTALL;
+
	} else if (strcmp(filename, "pkg-pre-deinstall") == 0 ||
+
			strcmp(filename, "+PRE_DEINSTALL") == 0) {
+
		type = PKG_SCRIPT_PRE_DEINSTALL;
+
	} else if (strcmp(filename, "pkg-post-deinstall") == 0 ||
+
			strcmp(filename, "+POST_DEINSTALL") == 0) {
+
		type = PKG_SCRIPT_POST_DEINSTALL;
+
	} else if (strcmp(filename, "pkg-deinstall") == 0 ||
+
			strcmp(filename, "+DEINSTALL") == 0) {
+
		type = PKG_SCRIPT_DEINSTALL;
+
	} else if (strcmp(filename, "pkg-pre-upgrade") == 0 ||
+
			strcmp(filename, "+PRE_UPGRADE") == 0) {
+
		type = PKG_SCRIPT_PRE_UPGRADE;
+
	} else if (strcmp(filename, "pkg-post-upgrade") == 0 ||
+
			strcmp(filename, "+POST_UPGRADE") == 0) {
+
		type = PKG_SCRIPT_POST_UPGRADE;
+
	} else if (strcmp(filename, "pkg-upgrade") == 0 ||
+
			strcmp(filename, "+UPGRADE") == 0) {
+
		type = PKG_SCRIPT_UPGRADE;
+
	} else {
+
		pkg_emit_error("unknown script '%s'", filename);
+
		ret = EPKG_FATAL;
+
		goto cleanup;
+
	}
+

+
	ret = pkg_addscript(pkg, data, type);
+
cleanup:
+
	free(data);
+
	return (ret);
+
}
+

+
int
pkg_addscript_file(struct pkg *pkg, const char *path)
{
	char *filename;
modified libpkg/pkg.h.in
@@ -1,5 +1,5 @@
/*-
-
 * Copyright (c) 2011-2013 Baptiste Daroussin <bapt@FreeBSD.org>
+
 * Copyright (c) 2011-2014 Baptiste Daroussin <bapt@FreeBSD.org>
 * Copyright (c) 2011-2012 Julien Laffaye <jlaffaye@FreeBSD.org>
 * Copyright (c) 2011 Will Andrews <will@FreeBSD.org>
 * Copyright (c) 2011 Philippe Pepiot <phil@philpep.org>
@@ -684,6 +684,7 @@ int pkgdb_file_set_cksum(struct pkgdb *db, struct pkg_file *file,
 * Read the content of a file into a buffer, then call pkg_set().
 */
int pkg_set_from_file(struct pkg *pkg, pkg_attr attr, const char *file, bool trimcr);
+
int pkg_set_from_fileat(int fd, struct pkg *pkg, pkg_attr attr, const char *file, bool trimcr);

/**
 * Allocate a new struct pkg and add it to the deps of pkg.
@@ -785,6 +786,7 @@ int pkg_addscript(struct pkg *pkg, const char *data, pkg_script type);
 * with the correct type.
 */
int pkg_addscript_file(struct pkg *pkg, const char *path);
+
int pkg_addscript_fileat(int fd, struct pkg *pkg, const char *path);
int pkg_appendscript(struct pkg *pkg, const char *cmd, pkg_script type);

/**
@@ -850,6 +852,7 @@ int pkg_delannotation(struct pkg *pkg, const char *tag);
 */
int pkg_parse_manifest(struct pkg *pkg, char *buf, size_t len, struct pkg_manifest_key *key);
int pkg_parse_manifest_file(struct pkg *pkg, const char *, struct pkg_manifest_key *key);
+
int pkg_parse_manifest_fileat(int fd, struct pkg *pkg, const char *, struct pkg_manifest_key *key);
int pkg_manifest_keys_new(struct pkg_manifest_key **k);
void pkg_manifest_keys_free(struct pkg_manifest_key *k);
int pkg_manifest_parser_new(struct pkg_manifest_parser **p);
modified libpkg/pkg_create.c
@@ -35,6 +35,7 @@
#include <regex.h>
#include <stdlib.h>
#include <string.h>
+
#include <fcntl.h>

#include "pkg.h"
#include "private/event.h"
@@ -283,6 +284,16 @@ cleanup:
	return (ret);
}

+
static void
+
pkg_load_from_file(int fd, struct pkg *pkg, pkg_attr attr, const char *path)
+
{
+

+
	if (faccessat(fd, path, F_OK, 0) == 0) {
+
		pkg_debug(1, "Reading: '%s'", path);
+
		pkg_set_from_fileat(fd, pkg, attr, path, false);
+
	}
+
}
+

int
pkg_create_staged(const char *outdir, pkg_formats format, const char *rootdir,
    const char *md_dir, char *plist, bool old)
@@ -292,22 +303,24 @@ pkg_create_staged(const char *outdir, pkg_formats format, const char *rootdir,
	struct pkg_dir	*dir = NULL;
	struct packing	*pkg_archive = NULL;
	char		*manifest = NULL;
-
	char		 path[MAXPATHLEN];
	char		 arch[BUFSIZ];
	int		 ret = ENOMEM;
	char		*buf;
-
	int		 i;
+
	int		 i, mfd;
	regex_t		 preg;
	regmatch_t	 pmatch[2];
	size_t		 size;
	char		*www = NULL;
	struct pkg_manifest_key *keys = NULL;

+
	mfd = -1;
+

	pkg_debug(1, "Creating package from stage directory: '%s'", rootdir);

-
	/* Load the manifest from the metadata directory */
-
	if (snprintf(path, sizeof(path), "%s/+MANIFEST", md_dir) == -1)
+
	if ((mfd = open(md_dir, O_DIRECTORY)) == -1) {
+
		pkg_emit_errno("open", md_dir);
		goto cleanup;
+
	}

	if(pkg_new(&pkg, old ? PKG_OLD_FILE : PKG_FILE) != EPKG_OK) {
		ret = EPKG_FATAL;
@@ -315,34 +328,22 @@ pkg_create_staged(const char *outdir, pkg_formats format, const char *rootdir,
	}

	pkg_manifest_keys_new(&keys);
-
	if ((ret = pkg_parse_manifest_file(pkg, path, keys)) != EPKG_OK) {
+
	/* Load the manifest from the metadata directory */
+
	if ((ret = pkg_parse_manifest_fileat(mfd, pkg, "+MANIFEST", keys))
+
	    != EPKG_OK) {
		ret = EPKG_FATAL;
		goto cleanup;
	}

	/* if no descriptions provided then try to get it from a file */
-

	pkg_get(pkg, PKG_DESC, &buf);
-
	if (buf == NULL) {
-
		if (snprintf(path, sizeof(path), "%s/+DESC", md_dir) == -1)
-
			goto cleanup;
-
		if (access(path, F_OK) == 0) {
-
			pkg_debug(1, "Taking description from: '%s'", path);
-
			pkg_set_from_file(pkg, PKG_DESC, path, false);
-
		}
-
	}
+
	if (buf == NULL)
+
		pkg_load_from_file(mfd, pkg, PKG_DESC, "+DESC");

	/* if no message try to get it from a file */
	pkg_get(pkg, PKG_MESSAGE, &buf);
-
	if (buf == NULL) {
-
		ret = snprintf(path, sizeof(path), "%s/+DISPLAY", md_dir);
-
		if (ret == -1)
-
			goto cleanup;
-
		if (access(path, F_OK) == 0) {
-
			pkg_debug(1, "Taking message from: '%s'", path);
-
			pkg_set_from_file(pkg, PKG_MESSAGE, path, false);
-
		}
-
	}
+
	if (buf == NULL)
+
		pkg_load_from_file(mfd, pkg, PKG_MESSAGE, "+DISPLAY");

	/* if no arch autodetermine it */
	pkg_get(pkg, PKG_ARCH, &buf);
@@ -353,20 +354,12 @@ pkg_create_staged(const char *outdir, pkg_formats format, const char *rootdir,

	/* if no mtree try to get it from a file */
	pkg_get(pkg, PKG_MTREE, &buf);
-
	if (buf == NULL) {
-
		ret = snprintf(path, sizeof(path), "%s/+MTREE_DIRS", md_dir);
-
		if (ret == -1)
-
			goto cleanup;
-
		if (access(path, F_OK) == 0) {
-
			pkg_debug(1, "Taking mtree definition from: '%s'", path);
-
			pkg_set_from_file(pkg, PKG_MTREE, path, false);
-
		}
-
	}
+
	if (buf == NULL)
+
		pkg_load_from_file(mfd, pkg, PKG_MTREE, "+MTREE_DIRS");

	for (i = 0; scripts[i] != NULL; i++) {
-
		snprintf(path, sizeof(path), "%s/%s", md_dir, scripts[i]);
-
		if (access(path, F_OK) == 0)
-
			pkg_addscript_file(pkg, path);
+
		if (faccessat(mfd, scripts[i], F_OK, 0) == 0)
+
			pkg_addscript_fileat(mfd, pkg, scripts[i]);
	}

	if (plist != NULL &&
modified libpkg/pkg_manifest.c
@@ -738,6 +738,42 @@ pkg_parse_manifest(struct pkg *pkg, char *buf, size_t len, struct pkg_manifest_k
}

int
+
pkg_parse_manifest_fileat(int dfd, struct pkg *pkg, const char *file,
+
    struct pkg_manifest_key *keys)
+
{
+
	struct ucl_parser *p = NULL;
+
	ucl_object_t *obj = NULL;
+
	int rc;
+
	char *data;
+
	size_t sz = 0;
+

+
	assert(pkg != NULL);
+
	assert(file != NULL);
+

+
	pkg_debug(1, "Parsing manifest from '%s'", file);
+

+
	errno = 0;
+

+
	if ((rc = file_to_bufferat(dfd, file, &data, &sz)) != EPKG_OK)
+
		return (EPKG_FATAL);
+

+
	p = ucl_parser_new(0);
+
	if (!ucl_parser_add_string(p, data, sz)) {
+
		ucl_parser_free(p);
+
		return (EPKG_FATAL);
+
	}
+

+
	obj = ucl_parser_get_object(p);
+
	rc = parse_manifest(pkg, keys, obj);
+

+
	ucl_parser_free(p);
+
	ucl_object_unref(obj);
+
	free(data);
+

+
	return (rc);
+
}
+

+
int
pkg_parse_manifest_file(struct pkg *pkg, const char *file, struct pkg_manifest_key *keys)
{
	struct ucl_parser *p = NULL;
modified libpkg/utils.c
@@ -158,7 +158,7 @@ file_to_bufferat(int dfd, const char *path, char **buffer, off_t *sz)
	assert(sz != NULL);

	if ((fd = openat(dfd, path, O_RDONLY)) == -1) {
-
		pkg_emit_errno("open", path);
+
		pkg_emit_errno("openat", path);
		retcode = EPKG_FATAL;
		goto cleanup;
	}