summaryrefslogtreecommitdiff
path: root/9p/defs.h
blob: 20a6411fb71cd07993269a333ad80c9528df6579 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
/* 9p/defs.h - TODO
 *
 * Copyright (C) 2024  Luke T. Shumaker <lukeshu@lukeshu.com>
 * SPDX-Licence-Identifier: AGPL-3.0-or-later
 */

#ifndef _9P_DEFS_H_
#define _9P_DEFS_H_

#include <stdint.h>

#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_ */