aboutgitcodelistschat:MatrixIRC
path: root/cooker/call.c
diff options
context:
space:
mode:
authorAlice Frosi <afrosi@redhat.com>2023-08-29 11:50:00 +0200
committerAlice Frosi <afrosi@redhat.com>2023-08-30 10:48:59 +0200
commitd3917582873df723aa2a3ddbb6116950292e114c (patch)
tree778089680e396cf9bf86c201476952f0870e93de /cooker/call.c
parent0e8806838763655f5f35822e19a20cb21e8d4747 (diff)
downloadseitan-d3917582873df723aa2a3ddbb6116950292e114c.tar
seitan-d3917582873df723aa2a3ddbb6116950292e114c.tar.gz
seitan-d3917582873df723aa2a3ddbb6116950292e114c.tar.bz2
seitan-d3917582873df723aa2a3ddbb6116950292e114c.tar.lz
seitan-d3917582873df723aa2a3ddbb6116950292e114c.tar.xz
seitan-d3917582873df723aa2a3ddbb6116950292e114c.tar.zst
seitan-d3917582873df723aa2a3ddbb6116950292e114c.zip
cooker: simplify tag and add caller metadata
Group the metadata information: - simplify the json by removing the 'tag' and only using 'get' and 'set' keys - get uid and gid at runtime for the target ('caller'). This can be useful when the the UID and GID of the target are only known at runtime and they need to be used for setting the permissions of files - updated example demo/mknod.hjson Signed-off-by: Alice Frosi <afrosi@redhat.com>
Diffstat (limited to 'cooker/call.c')
-rw-r--r--cooker/call.c129
1 files changed, 73 insertions, 56 deletions
diff --git a/cooker/call.c b/cooker/call.c
index 6dbfd29..173bdb4 100644
--- a/cooker/call.c
+++ b/cooker/call.c
@@ -16,6 +16,70 @@
#include "parse.h"
#include "util.h"
+/* TODO: refactor and simplify this horrible function */
+static union value parse_metadata(struct gluten_ctx *g, struct field *f,
+ struct gluten_offset **base_offset,
+ struct gluten_offset offset,
+ JSON_Object *metadata, bool dry_run, bool add)
+{
+ const char *tag;
+ size_t count = 0;
+ union value v = { .v_num = 0 };
+
+ if ((tag = json_object_get_string(metadata, "caller"))) {
+ debug(" args reference value at runtime '%s' with metadata %s", tag, tag);
+ (*base_offset)->type = OFFSET_METADATA;
+ if (strcmp(tag, "uid") == 0) {
+ (*base_offset)->offset = UID_TARGET;
+ } else if (strcmp(tag, "gid") == 0) {
+ (*base_offset)->offset = GID_TARGET;
+ } else {
+ die(" unrecognized metadata tag: %s", tag);
+ }
+ return v;
+ }
+
+ if ((tag = json_object_get_string(metadata, "set"))) {
+ count++;
+ debug(" setting tag reference (post) '%s'", tag);
+
+ if (!dry_run)
+ gluten_add_tag_post(g, tag, offset);
+
+ if (f->flags & RBUF)
+ return v;
+ }
+
+ if ((tag = json_object_get_string(metadata, "get"))) {
+ struct gluten_offset tag_offset;
+
+ count++;
+ debug(" getting tag reference '%s'", tag);
+
+ /* TODO: Check type */
+ tag_offset = gluten_get_tag(g, tag);
+ if (tag_offset.type == OFFSET_NULL)
+ die(" tag not found");
+
+ if ((*base_offset)->type == OFFSET_NULL) {
+ **base_offset = tag_offset;
+ } else if (f->flags & MASK || add) {
+ emit_bitwise(g, f->type, BITWISE_OR, offset, offset,
+ tag_offset);
+ } else {
+ emit_copy_field(g, f, offset, tag_offset);
+ }
+ }
+
+ if (json_object_get_count(metadata) > count)
+ die("stray object in tag reference");
+
+ if (!count)
+ die("invalid tag specification");
+
+ return v;
+}
+
/**
struct syscall_desc {
@@ -78,7 +142,7 @@ static union value parse_field(struct gluten_ctx *g, struct arg *args,
{
struct gluten_offset offset = *base_offset;
union value v = { .v_num = 0 };
- JSON_Object *tmp1, *tmp2;
+ JSON_Object *tmp1;
struct field *f_inner;
JSON_Value *sel;
@@ -89,58 +153,11 @@ static union value parse_field(struct gluten_ctx *g, struct arg *args,
offset.offset += f->offset;
if (json_value_get_type(jvalue) == JSONObject &&
- (tmp1 = json_value_get_object(jvalue)) &&
- (tmp2 = json_object_get_object(tmp1, "tag"))) {
- const char *tag_set, *tag_get;
- size_t count = 0;
-
- if ((tag_set = json_object_get_string(tmp2, "set"))) {
- count++;
- debug(" setting tag reference (post) '%s'", tag_set);
-
- if (!dry_run)
- gluten_add_tag_post(g, tag_set, offset);
-
- if (f->flags & RBUF)
- return v;
- }
-
- if ((tag_get = json_object_get_string(tmp2, "get"))) {
- struct gluten_offset tag_offset;
-
- count++;
- debug(" getting tag reference '%s'", tag_get);
-
- /* TODO: Check type */
- tag_offset = gluten_get_tag(g, tag_get);
- if (tag_offset.type == OFFSET_NULL)
- die(" tag not found");
-
- if (base_offset->type == OFFSET_NULL) {
- *base_offset = tag_offset;
- } else if (f->flags & MASK || add) {
- emit_bitwise(g, f->type, BITWISE_OR, offset,
- offset, tag_offset);
- } else {
- emit_copy_field(g, f, offset, tag_offset);
- }
- }
-
- if (json_object_get_count(tmp2) > count)
- die("stray object in tag reference");
-
- if (!count)
- die("invalid tag specification");
-
- jvalue = json_object_get_value(tmp1, "value");
-
- if (tag_get) {
- if (jvalue)
- die("stray value with \"get\" tag");
-
- return v;
- }
- }
+ (tmp1 = json_value_get_object(jvalue)))
+ v = parse_metadata(g, f, &base_offset, offset, tmp1, dry_run,
+ add);
+ if (v.v_num == 0)
+ return v;
if (!jvalue && !(f->flags & SIZE))
return v;
@@ -205,7 +222,8 @@ static union value parse_field(struct gluten_ctx *g, struct arg *args,
if (dry_run)
break;
- v.v_str = json_value_get_string(jvalue);
+ if ((v.v_str = json_value_get_string(jvalue)) == NULL)
+ die(" failed parsing string for %s", json_serialize_to_string(jvalue));
if (strlen(v.v_str) + 1 > f->size)
die(" string %s too long for field", v.v_str);
@@ -247,8 +265,7 @@ bool arg_needs_temp(struct field *f, int pos, JSON_Value *jvalue,
return false;
if (json_value_get_type(jvalue) == JSONObject &&
- (tmp = json_value_get_object(jvalue)) &&
- (tmp = json_object_get_object(tmp, "tag"))) {
+ (tmp = json_value_get_object(jvalue))) {
if (json_object_get_string(tmp, "set"))
return true;