diff options
author | Luke T. Shumaker <lukeshu@lukeshu.com> | 2024-09-27 17:25:36 -0600 |
---|---|---|
committer | Luke T. Shumaker <lukeshu@lukeshu.com> | 2024-09-27 17:25:36 -0600 |
commit | e5e15c04bc58c34906e6d7cfcbad68d1a5617563 (patch) | |
tree | 580f5fb0fafc7e974c969fc8aae229205c836195 /lib9p/include | |
parent | 71e1a86a033c380f85dd300d788af63bfef25bab (diff) |
wip
Diffstat (limited to 'lib9p/include')
-rw-r--r-- | lib9p/include/lib9p/9p.h | 72 | ||||
-rw-r--r-- | lib9p/include/lib9p/_types.h | 285 | ||||
-rwxr-xr-x | lib9p/include/lib9p/linux-errno.h.gen | 34 | ||||
-rw-r--r-- | lib9p/include/lib9p/srv.h | 16 |
4 files changed, 407 insertions, 0 deletions
diff --git a/lib9p/include/lib9p/9p.h b/lib9p/include/lib9p/9p.h new file mode 100644 index 0000000..a55f08f --- /dev/null +++ b/lib9p/include/lib9p/9p.h @@ -0,0 +1,72 @@ +/* lib9p/9p.h - Base 9P protocol definitions for both clients and servers + * + * Copyright (C) 2024 Luke T. Shumaker <lukeshu@lukeshu.com> + * SPDX-Licence-Identifier: AGPL-3.0-or-later + */ + +#ifndef _LIB9P_9P_H_ +#define _LIB9P_9P_H_ + +#include <lib9p/linux-errno.h> +#include <lib9p/_types.h> + +#define LIB9P_NOTAG ((uint16_t)~0U) +#define LIB9P_NOFID ((uint32_t)~0U) + +struct lib9p_ctx; +enum lib9p_version lib9p_ctx_version(lib9p_ctx *); +uint32_t lib9p_ctx_max_msg_size(lib9p_ctx *); + +/** Write an static error into ctx, return -1. */ +int lib9p_error(struct lib9p_ctx *ctx, uint32_t linux_errno, char const *msg); +/** Write a printf-style error into ctx, return -1. */ +int lib9p_errorf(struct lib9p_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, or if an invalid string (invalid UTF-8, + * contains a nul-byte) is encountered. + * + * @param net_bytes : the complete request, starting with the "size[4]" + * + * @return required size, or -1 on error + */ +ssize_t lib9p_unmarshal_size(struct lib9p_ctx *ctx, uint8_t *net_bytes); + +/** + * Unmarshal the 9P message `net_bytes` into the C struct `ret_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 ctx : negotiated protocol parameters, where to record errors + * @param net_bytes : the complete message, starting with the "size[4]" + * + * @return ret_typ : the mesage type + * @return ret_tag : the message-ID tag + * @return ret_body : the message body, must be at least lib9p_unmarshal_size() bytes + * @return the message type, or -1 on error + */ +bool lib9p_unmarshal(struct lib9p_ctx *ctx, uint8_t *net_bytes, + enum lib9p_msg_typ *ret_typ, uint16_t *ret_tag, void *ret_body); + +/** + * Marshal a `struct lib9p_msg_{typ}` structure into a byte-array. + * + * @param ctx : negotiated protocol parameters, where to record errors + * @param typ : the message type + * @param tag : the message-ID tag + * @param msg : the message to encode + * + * @return ret_bytes : the buffer to encode to, must be at be at least lib9p_ctx_max_msg_size(ctx) bytes + * @return whether there was an error (false=success, true=error) + */ +bool lib9p_marshal(struct lib9p_ctx *ctx, uint8_t typ, uint16_t tag, void *body, + uint8_t *ret_bytes); + +#endif _LIB9P_9P_H_ diff --git a/lib9p/include/lib9p/_types.h b/lib9p/include/lib9p/_types.h new file mode 100644 index 0000000..348945d --- /dev/null +++ b/lib9p/include/lib9p/_types.h @@ -0,0 +1,285 @@ +/* Generated by `./types.gen 9P2000.txt 9P2000.u.txt 9P2000.e.txt`. DO NOT EDIT! */ + +#ifndef _LIB9P__TYPES_H_ +#define _LIB9P__TYPES_H_ + +#include <stdint.h> + +/* versions *******************************************************************/ + +enum lib9p_version { + LIB9P_VER_UNINITIALIZED = 0, + LIB9P_VER_9P2000, /* "9P2000" */ + LIB9P_VER_9P2000_e, /* "9P2000.e" */ + LIB9P_VER_9P2000_u, /* "9P2000.u" */ + LIB9P_VER_NUM, +}; + +/* non-message structs ********************************************************/ + +struct lib9p_d { + uint32_t len; + uint8_t *dat; +}; + +struct lib9p_s { + uint16_t len; + uint8_t *utf8; +}; + +struct lib9p_qid { + uint8_t type; + uint32_t vers; + uint64_t path; +}; + +struct lib9p_stat { + uint16_t stat_size; + uint16_t kern_type; + uint32_t kern_dev; + struct lib9p_qid file_qid; + uint32_t file_mode; + uint32_t file_atime; + uint32_t file_mtime; + uint64_t file_size; + struct lib9p_s file_name; + struct lib9p_s file_owner_uid; + struct lib9p_s file_owner_gid; + struct lib9p_s file_last_modified_uid; + struct lib9p_s file_extension; /* 9P2000.u */ + uint32_t file_owner_n_uid; /* 9P2000.u */ + uint32_t file_owner_n_gid; /* 9P2000.u */ + uint32_t file_last_modified_n_uid; /* 9P2000.u */ +}; + +/* messages *******************************************************************/ + +enum lib9p_msg_type { /* uint8_t */ + LIB9P_TYP_Tversion = 100, + LIB9P_TYP_Rversion = 101, + LIB9P_TYP_Tauth = 102, + LIB9P_TYP_Rauth = 103, + LIB9P_TYP_Tattach = 104, + LIB9P_TYP_Rattach = 105, + LIB9P_TYP_Rerror = 107, + LIB9P_TYP_Tflush = 108, + LIB9P_TYP_Rflush = 109, + LIB9P_TYP_Twalk = 110, + LIB9P_TYP_Rwalk = 111, + LIB9P_TYP_Topen = 112, + LIB9P_TYP_Ropen = 113, + LIB9P_TYP_Tcreate = 114, + LIB9P_TYP_Rcreate = 115, + LIB9P_TYP_Tread = 116, + LIB9P_TYP_Rread = 117, + LIB9P_TYP_Twrite = 118, + LIB9P_TYP_Rwrite = 119, + LIB9P_TYP_Tclunk = 120, + LIB9P_TYP_Rclunk = 121, + LIB9P_TYP_Tremove = 122, + LIB9P_TYP_Rremove = 123, + LIB9P_TYP_Tstat = 124, + LIB9P_TYP_Rstat = 125, + LIB9P_TYP_Twstat = 126, + LIB9P_TYP_Rwstat = 127, + LIB9P_TYP_Tsession = 150, /* 9P2000.e */ + LIB9P_TYP_Rsession = 151, /* 9P2000.e */ + LIB9P_TYP_Tsread = 152, /* 9P2000.e */ + LIB9P_TYP_Rsread = 153, /* 9P2000.e */ + LIB9P_TYP_Tswrite = 154, /* 9P2000.e */ + LIB9P_TYP_Rswrite = 155, /* 9P2000.e */ +}; + +#define LIB9P_TYPECODE_FOR_CTYPE(msg) _Generic((msg), \ + struct lib9p_msg_Tversion: LIB9P_TYP_Tversion, \ + struct lib9p_msg_Rversion: LIB9P_TYP_Rversion, \ + struct lib9p_msg_Tauth: LIB9P_TYP_Tauth, \ + struct lib9p_msg_Rauth: LIB9P_TYP_Rauth, \ + struct lib9p_msg_Tattach: LIB9P_TYP_Tattach, \ + struct lib9p_msg_Rattach: LIB9P_TYP_Rattach, \ + struct lib9p_msg_Rerror: LIB9P_TYP_Rerror, \ + struct lib9p_msg_Tflush: LIB9P_TYP_Tflush, \ + struct lib9p_msg_Rflush: LIB9P_TYP_Rflush, \ + struct lib9p_msg_Twalk: LIB9P_TYP_Twalk, \ + struct lib9p_msg_Rwalk: LIB9P_TYP_Rwalk, \ + struct lib9p_msg_Topen: LIB9P_TYP_Topen, \ + struct lib9p_msg_Ropen: LIB9P_TYP_Ropen, \ + struct lib9p_msg_Tcreate: LIB9P_TYP_Tcreate, \ + struct lib9p_msg_Rcreate: LIB9P_TYP_Rcreate, \ + struct lib9p_msg_Tread: LIB9P_TYP_Tread, \ + struct lib9p_msg_Rread: LIB9P_TYP_Rread, \ + struct lib9p_msg_Twrite: LIB9P_TYP_Twrite, \ + struct lib9p_msg_Rwrite: LIB9P_TYP_Rwrite, \ + struct lib9p_msg_Tclunk: LIB9P_TYP_Tclunk, \ + struct lib9p_msg_Rclunk: LIB9P_TYP_Rclunk, \ + struct lib9p_msg_Tremove: LIB9P_TYP_Tremove, \ + struct lib9p_msg_Rremove: LIB9P_TYP_Rremove, \ + struct lib9p_msg_Tstat: LIB9P_TYP_Tstat, \ + struct lib9p_msg_Rstat: LIB9P_TYP_Rstat, \ + struct lib9p_msg_Twstat: LIB9P_TYP_Twstat, \ + struct lib9p_msg_Rwstat: LIB9P_TYP_Rwstat, \ + struct lib9p_msg_Tsession: LIB9P_TYP_Tsession, \ + struct lib9p_msg_Rsession: LIB9P_TYP_Rsession, \ + struct lib9p_msg_Tsread: LIB9P_TYP_Tsread, \ + struct lib9p_msg_Rsread: LIB9P_TYP_Rsread, \ + struct lib9p_msg_Tswrite: LIB9P_TYP_Tswrite, \ + struct lib9p_msg_Rswrite: LIB9P_TYP_Rswrite) + +struct lib9p_msg_Tversion { + uint32_t max_msg_size; + struct lib9p_s version; +}; + +struct lib9p_msg_Rversion { + uint32_t max_msg_size; + struct lib9p_s version; +}; + +struct lib9p_msg_Tauth { + uint32_t afid; + struct lib9p_s uname; + struct lib9p_s aname; + uint32_t n_uname; /* 9P2000.u */ +}; + +struct lib9p_msg_Rauth { + struct lib9p_qid aqid; +}; + +struct lib9p_msg_Tattach { + uint32_t fid; + uint32_t afid; + struct lib9p_s uname; + struct lib9p_s aname; +}; + +struct lib9p_msg_Rattach { + struct lib9p_qid qid; +}; + +struct lib9p_msg_Rerror { + struct lib9p_s ename; + uint32_t errno; /* 9P2000.u */ +}; + +struct lib9p_msg_Tflush { + uint16_t oldtag; +}; + +struct lib9p_msg_Rflush {}; + +struct lib9p_msg_Twalk { + uint32_t fid; + uint32_t newfid; + uint16_t nwname; + struct lib9p_s *wname; +}; + +struct lib9p_msg_Rwalk { + uint16_t nwqid; + struct lib9p_qid *wqid; +}; + +struct lib9p_msg_Topen { + uint32_t fid; + uint8_t mode; +}; + +struct lib9p_msg_Ropen { + struct lib9p_qid qid; + uint32_t iounit; +}; + +struct lib9p_msg_Tcreate { + uint32_t fid; + struct lib9p_s name; + uint32_t perm; + uint8_t mode; +}; + +struct lib9p_msg_Rcreate { + struct lib9p_qid qid; + uint32_t iounit; +}; + +struct lib9p_msg_Tread { + uint32_t fid; + uint64_t offset; + uint32_t count; +}; + +struct lib9p_msg_Rread { + struct lib9p_d data; +}; + +struct lib9p_msg_Twrite { + uint32_t fid; + uint64_t offset; + struct lib9p_d data; +}; + +struct lib9p_msg_Rwrite { + uint32_t count; +}; + +struct lib9p_msg_Tclunk { + uint32_t fid; +}; + +struct lib9p_msg_Rclunk {}; + +struct lib9p_msg_Tremove { + uint32_t fid; +}; + +struct lib9p_msg_Rremove {}; + +struct lib9p_msg_Tstat { + uint32_t fid; +}; + +struct lib9p_msg_Rstat { + struct lib9p_stat stat; +}; + +struct lib9p_msg_Twstat { + uint32_t fid; + struct lib9p_stat stat; +}; + +struct lib9p_msg_Rwstat {}; + +/* 9P2000.e */ +struct lib9p_msg_Tsession { + uint64_t key; +}; + +/* 9P2000.e */ +struct lib9p_msg_Rsession {}; + +/* 9P2000.e */ +struct lib9p_msg_Tsread { + uint32_t fid; + uint16_t nwname; + struct lib9p_s *wname; +}; + +/* 9P2000.e */ +struct lib9p_msg_Rsread { + struct lib9p_d data; +}; + +/* 9P2000.e */ +struct lib9p_msg_Tswrite { + uint32_t fid; + uint16_t nwname; + struct lib9p_s *wname; + struct lib9p_d data; +}; + +/* 9P2000.e */ +struct lib9p_msg_Rswrite { + uint32_t count; +}; + +#endif /* _LIB9P__TYPES_H_ */ diff --git a/lib9p/include/lib9p/linux-errno.h.gen b/lib9p/include/lib9p/linux-errno.h.gen new file mode 100755 index 0000000..b896384 --- /dev/null +++ b/lib9p/include/lib9p/linux-errno.h.gen @@ -0,0 +1,34 @@ +#!/usr/bin/env python + + +def print_errnos(txtlists: list[str]) -> None: + print( + f"/* 9p/linux-errno.h - Generated by `./9p/linux-errno.h.gen {' '.join(txtlists)}`. DO NOT EDIT! */" + ) + errnos: dict[str, tuple[int, str]] = {} + for txtlist in sys.argv[1:]: + with open(txtlist, "r") as fh: + for line in fh: + if line.startswith("#"): + print(f"/* {line[1:].strip()} */") + continue + _num, name, desc = line.split(maxsplit=2) + num = int(_num) + desc = desc.strip() + errnos[name] = (num, desc) + print() + print("#ifndef _9P_LINUX_ERRNO_H_") + print("#define _9P_LINUX_ERRNO_H_") + print() + namelen = max(len(name) for name in errnos.keys()) + numlen = max(len(str(num)) for (num, desc) in errnos.values()) + for name in errnos: + print(f"#define LINUX_{name.ljust(namelen)} {str(errnos[name][0]).rjust(numlen)} /* {errnos[name][1]} */") + print() + print("#endif /* _9P_LINUX_ERRNO_H_ */") + + +if __name__ == "__main__": + import sys + + print_errnos(sys.argv[1:]) diff --git a/lib9p/include/lib9p/srv.h b/lib9p/include/lib9p/srv.h new file mode 100644 index 0000000..3b8b21e --- /dev/null +++ b/lib9p/include/lib9p/srv.h @@ -0,0 +1,16 @@ +#ifndef _LIB9P_SRV_H_ +#define _LIB9P_SRV_H_ + +#include <libcr/coroutine.h> + +struct lib9p_srvreq; + +struct lib9p_srv { + int sockfd; + cr_chan_t(lib9p_srvreq *) reqch; +}; + +COROUTINE lib9p_srv_read_cr(void *_srv); +COROUTINE lib9p_srv_write_cr(void *_srv); + +#endif /* _LIB9P_SRV_H_ */ |