Radish alpha
H
rad:z3QDZAW2FAfuLvihrhiyDC9fAD8G9
HardenedBSD Package Manager
Radicle
Git
Allow arguments in ucl keywords
Baptiste Daroussin committed 11 years ago
commit 20a3a827278589176a1356810e633bf156888c0f
parent 437faef
3 files changed +86 -26
modified libpkg/pkg_ports.c
@@ -109,20 +109,21 @@ static int pkgdep(struct plist *, char *, struct file_attr *);
static struct action_cmd {
	const char *name;
	int (*perform)(struct plist *, char *, struct file_attr *);
+
	size_t namelen;
} list_actions[] = {
-
	{ "setprefix", setprefix },
-
	{ "dirrm", dirrm },
-
	{ "dirrmtry", dirrmtry },
-
	{ "file", file },
-
	{ "setmode", setmod },
-
	{ "setowner", setowner },
-
	{ "setgroup", setgroup },
-
	{ "comment", comment_key },
-
	{ "ignore_next", ignore_next },
+
	{ "setprefix", setprefix, 9},
+
	{ "dirrm", dirrm, 5 },
+
	{ "dirrmtry", dirrmtry, 7 },
+
	{ "file", file, 4 },
+
	{ "setmode", setmod, 6 },
+
	{ "setowner", setowner, 8 },
+
	{ "setgroup", setgroup, 8 },
+
	{ "comment", comment_key, 7 },
+
	{ "ignore_next", ignore_next, 11 },
	/* compat with old packages */
-
	{ "name", name_key },
-
	{ "pkgdep", pkgdep },
-
	{ NULL, NULL }
+
	{ "name", name_key, 4 },
+
	{ "pkgdep", pkgdep, 6 },
+
	{ NULL, NULL, 0 }
};

static ucl_object_t *
@@ -581,7 +582,8 @@ meta_exec(struct plist *p, char *line, struct file_attr *a, bool unexec)
	regmatch_t pmatch[2];
	int ret;

-
	ret = format_exec_cmd(&cmd, line, p->prefix, p->last_file, NULL);
+
	ret = format_exec_cmd(&cmd, line, p->prefix, p->last_file, NULL, 0,
+
	    NULL);
	if (ret != EPKG_OK)
		return (EPKG_OK);

@@ -730,16 +732,31 @@ keyword_free(struct keyword *k)

static int
parse_actions(const ucl_object_t *o, struct plist *p,
-
    char *line, struct file_attr *a)
+
    char *line, struct file_attr *a, int argc, char **argv)
{
	const ucl_object_t *cur;
+
	const char *actname;
	ucl_object_iter_t it = NULL;
-
	int i;
+
	int i, j = 0;

	while ((cur = ucl_iterate_object(o, &it, true))) {
+
		actname = ucl_object_tostring(cur);
		for (i = 0; list_actions[i].name != NULL; i++) {
-
			if (!strcasecmp(ucl_object_tostring(cur), list_actions[i].name)) {
-
				list_actions[i].perform(p, line, a);
+
			if (!strncasecmp(actname, list_actions[i].name,
+
			    list_actions[i].namelen) &&
+
			    (actname[list_actions[i].namelen ] == '\0' ||
+
			     actname[list_actions[i].namelen ] == '(' )) {
+
				actname += list_actions[i].namelen;
+
				if (*actname == '(') {
+
					j = strtol(actname+1, NULL, 10);
+
					if (j > argc) {
+
						pkg_emit_error(
+
						    "Invalid argument requested %d"
+
						    " available: %d", j, argc);
+
						return (EPKG_FATAL);
+
					}
+
				}
+
				list_actions[i].perform(p, j > 0 ? argv[j - 1] : line, a);
				break;
			}
		}
@@ -793,48 +810,71 @@ apply_keyword_file(ucl_object_t *obj, struct plist *p, char *line, struct file_a
{
	const ucl_object_t *o;
	char *cmd;
+
	char **args = NULL;
+
	char *buf, *tofree;
+
	int spaces, argc = 0, i;
+

+
	if ((o = ucl_object_find_key(obj,  "arguments")) && ucl_object_toboolean(o)) {
+
		spaces = pkg_utils_count_spaces(line);
+
		args = malloc((spaces + 1)* sizeof(char *));
+
		tofree = buf = strdup(line);
+
		while (buf != NULL) {
+
			args[argc++] = pkg_utils_tokenize(&buf);
+
		}
+
	}

	if ((o = ucl_object_find_key(obj,  "attributes")))
		parse_attributes(o, &attr);

	if ((o = ucl_object_find_key(obj, "pre-install"))) {
-
		format_exec_cmd(&cmd, ucl_object_tostring(o), p->prefix, p->last_file, line);
+
		format_exec_cmd(&cmd, ucl_object_tostring(o), p->prefix,
+
		    p->last_file, line, argc, args);
		sbuf_printf(p->pre_install_buf, "%s\n", cmd);
		free(cmd);
	}

	if ((o = ucl_object_find_key(obj, "post-install"))) {
-
		format_exec_cmd(&cmd, ucl_object_tostring(o), p->prefix, p->last_file, line);
+
		format_exec_cmd(&cmd, ucl_object_tostring(o), p->prefix,
+
		    p->last_file, line, argc, args);
		sbuf_printf(p->post_install_buf, "%s\n", cmd);
		free(cmd);
	}

	if ((o = ucl_object_find_key(obj, "pre-deinstall"))) {
-
		format_exec_cmd(&cmd, ucl_object_tostring(o), p->prefix, p->last_file, line);
+
		format_exec_cmd(&cmd, ucl_object_tostring(o), p->prefix,
+
		    p->last_file, line, argc, args);
		sbuf_printf(p->pre_deinstall_buf, "%s\n", cmd);
		free(cmd);
	}

	if ((o = ucl_object_find_key(obj, "post-deinstall"))) {
-
		format_exec_cmd(&cmd, ucl_object_tostring(o), p->prefix, p->last_file, line);
+
		format_exec_cmd(&cmd, ucl_object_tostring(o), p->prefix,
+
		    p->last_file, line, argc, args);
		sbuf_printf(p->post_deinstall_buf, "%s\n", cmd);
		free(cmd);
	}

	if ((o = ucl_object_find_key(obj, "pre-upgrade"))) {
-
		format_exec_cmd(&cmd, ucl_object_tostring(o), p->prefix, p->last_file, line);
+
		format_exec_cmd(&cmd, ucl_object_tostring(o), p->prefix,
+
		    p->last_file, line, argc, args);
		sbuf_printf(p->pre_deinstall_buf, "%s\n", cmd);
		free(cmd);
	}

	if ((o = ucl_object_find_key(obj, "post-upgrade"))) {
-
		format_exec_cmd(&cmd, ucl_object_tostring(o), p->prefix, p->last_file, line);
+
		format_exec_cmd(&cmd, ucl_object_tostring(o), p->prefix,
+
		    p->last_file, line, argc, args);
		sbuf_printf(p->post_deinstall_buf, "%s\n", cmd);
		free(cmd);
	}

	if ((o = ucl_object_find_key(obj,  "actions")))
-
		parse_actions(o, p, line, attr);
+
		parse_actions(o, p, line, attr, argc, args);
+

+
	for (i = 0; i < argc; i++)
+
		free(args[i]);
+
	free(args);
+
	free(tofree);

	return (EPKG_OK);
}
modified libpkg/private/utils.h
@@ -90,7 +90,8 @@ ssize_t sbuf_size(struct sbuf *);
int mkdirs(const char *path);
int file_to_buffer(const char *, char **, off_t *);
int file_to_bufferat(int, const char *, char **, off_t *);
-
int format_exec_cmd(char **, const char *, const char *, const char *, char *);
+
int format_exec_cmd(char **, const char *, const char *, const char *, char *,
+
    int argc, char **argv);
int is_dir(const char *);
int is_conf_file(const char *path, char *newpath, size_t len);

modified libpkg/utils.c
@@ -246,11 +246,12 @@ file_to_buffer(const char *path, char **buffer, off_t *sz)

int
format_exec_cmd(char **dest, const char *in, const char *prefix,
-
    const char *plist_file, char *line)
+
    const char *plist_file, char *line, int argc, char **argv)
{
	struct sbuf *buf = sbuf_new_auto();
	char path[MAXPATHLEN];
	char *cp;
+
	size_t sz;

	while (in[0] != '\0') {
		if (in[0] != '%') {
@@ -323,7 +324,25 @@ format_exec_cmd(char **dest, const char *in, const char *prefix,
			 * given (default exec) %@ does not
			 * exists
			 */
+
		case '#':
+
			sbuf_putc(buf, argc);
+
			break;
		default:
+
			if ((sz = strspn(in, "0123456789")) > 0) {
+
				int pos = strtol(in, NULL, 10);
+
				if (pos > argc) {
+
					pkg_emit_error("Requesting argument "
+
					    "%%%d while only %d arguments are"
+
					    " available", pos, argc);
+
					sbuf_finish(buf);
+
					sbuf_free(buf);
+

+
					return (EPKG_FATAL);
+
				}
+
				sbuf_cat(buf, argv[pos -1]);
+
				in += sz -1;
+
				break;
+
			}
			sbuf_putc(buf, '%');
			sbuf_putc(buf, in[0]);
			break;