/* 9p/defs.h - TODO * * Copyright (C) 2024 Luke T. Shumaker * SPDX-Licence-Identifier: AGPL-3.0-or-later */ #ifndef _9P_DEFS_H_ #define _9P_DEFS_H_ #include #define P9_NOTAG ((uint16_t)~0U) #define P9_NOFID ((uint32_t)~0U) enum p9_version { /* P9_VER_9P1, */ P9_VER_9P2000, /*P9_VER_9P2000_u,*/ /*P9_VER_9P2000_L,*/ /*P9_VER_9P2000_e,*/ _P9_VER_CNT, }; struct p9_ctx { enum p9_version version; uint32_t max_msg_size; uint32_t err_num; char err_msg[256]; /* I chose 256 arbitrarily. */ }; /** Write an static error into ctx, return -1. */ int p9_error(struct p9_ctx *ctx, uint32_t linux_errno, char const *msg); /** Write a printf-style error into ctx, return -1. */ int p9_errorf(struct p9_ctx *ctx, uint32_t linux_errno, char const *fmt, ...); /** * Return how much space the message at net_bytes will take when * unmarshaled. This number may be larger than net_bytes due to (1) * struct padding, (2) nul-terminator byes for strings. * * Emits an error (return -1, set ctx->err_num and ctx->err_msg) if * either the message type is unknown or if net_bytes is too short for * that message type. * * @param net_bytes : the complete request, starting with the "size[4]" * @return required size, or -1 on error */ size_t p9_unmarshal_size(struct p9_ctx *ctx, uint8_t *net_bytes); /** * Unmarshal the 9P message `net_bytes` into the C struct `out_body`. * * Emits an error (return 0, set ctx->err_num and ctx->err_msg) if a * string contains invalid UTF-8 or a nul-byte. * * @param net_bytes : the complete message, starting with the "size[4]" * @param out_tag : the message-ID tag * @param out_body : the message body, must be at least p9_unmarshal_size() bytes * @return the message type, or -1 on error */ uint8_t p9_unmarshal(struct p9_ctx *ctx, uint8_t *net_bytes, uint16_t *out_tag, void *out_body); /** * Marshal a `struct p9_msg_{type}` structure into a byte-array. * * @param struct p9_ctx *ctx : a request context * @param uint16_t msgid : the message-ID tag * @param struct p9_msg_{type} msg : the message to encode * * @param uint8_t *out_bytes : the buffer to encode to, must be at be at least ctx->max_msg_size bytes * @return uint32_t : the encoded length, or -1 on error */ #define p9_marshal(ctx, msgid, msg, out_bytes) _p9_marshal(ctx, P9_TYPECODE_FOR_CTYPE(msg), msgid, &(msg), out_bytes) uint32_t _p9_marshal(struct p9_ctx *ctx, uint8_t typ, uint16_t msgid, void *body, uint8_t *out_bytes); #endif /* _9P_DEFS_H_ */