summaryrefslogtreecommitdiff
path: root/lib9p/9p.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib9p/9p.c')
-rw-r--r--lib9p/9p.c47
1 files changed, 47 insertions, 0 deletions
diff --git a/lib9p/9p.c b/lib9p/9p.c
index b1d4c32..832ae82 100644
--- a/lib9p/9p.c
+++ b/lib9p/9p.c
@@ -98,3 +98,50 @@ bool lib9p_marshal(struct lib9p_ctx *ctx, enum lib9p_msg_type typ, void *body,
struct _vtable_msg vtable = _lib9p_vtables[ctx->version].msgs[typ];
return vtable.marshal(&subctx, body);
}
+
+bool lib9p_validate_stat(struct lib9p_ctx *ctx, uint32_t net_size, uint8_t *net_bytes,
+ uint32_t *ret_net_size, ssize_t *ret_host_size) {
+ struct _validate_ctx subctx = {
+ .ctx = ctx,
+ .net_size = net_size,
+ .net_bytes = net_bytes,
+
+ .net_offset = 0,
+ .host_extra = 0,
+ };
+ if (_lib9p_validate_stat(&subctx))
+ return true;
+ if (ret_net_size)
+ *ret_net_size = subctx.net_offset;
+ if (ret_host_size)
+ if (__builtin_add_overflow(sizeof(struct lib9p_stat), subctx.host_extra, ret_host_size))
+ return lib9p_error(ctx, LINUX_EMSGSIZE, "unmarshalled stat object overflows SSIZE_MAX");
+ return false;
+}
+
+uint32_t lib9p_unmarshal_stat(struct lib9p_ctx *ctx, uint8_t *net_bytes,
+ struct lib9p_stat *ret_obj, void *ret_extra) {
+ struct _unmarshal_ctx subctx = {
+ .ctx = ctx,
+ .net_bytes = net_bytes,
+ .net_offset = 0,
+
+ .extra = ret_extra,
+ };
+ _lib9p_unmarshal_stat(&subctx, ret_obj);
+ return subctx.net_offset;
+}
+
+uint32_t lib9p_marshal_stat(struct lib9p_ctx *ctx, uint32_t max_net_size, struct lib9p_stat *obj,
+ uint8_t *ret_bytes) {
+ struct lib9p_ctx _ctx = *ctx;
+ _ctx.max_msg_size = max_net_size;
+ struct _marshal_ctx subctx = {
+ .ctx = &_ctx,
+ .net_bytes = ret_bytes,
+ .net_offset = 0,
+ };
+ if (_lib9p_marshal_stat(&subctx, obj))
+ return 0;
+ return subctx.net_offset;
+}