summaryrefslogtreecommitdiff
path: root/lib9p/9P2000.txt
blob: 3f1f10a84ca955119405af7c3206c7c4fecd7dd4 (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
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
# 9P2000.txt - Definitions of 9P2000 messages
#
# Copyright (C) 2024  Luke T. Shumaker <lukeshu@lukeshu.com>
# SPDX-Licence-Identifier: AGPL-3.0-or-later

# The format of each message (excluding the "size[4] msg_type[1]
# tag[2]" header) is written here as a sequence of
# "member_name[member_type]" struct members.
#
# The primitive member types types are the following single-character
# mnemonics:
#
#  - 1 = u8
#  - 2 = u16le
#  - 4 = u32le
#  - 8 = u16le

# "9P2000" base protocol
# https://ericvh.github.io/9p-rfc/rfc9p2000.html
# https://github.com/ericvh/9p-rfc/blob/master/9p2000.xml
#
# But due to incompleteness of the draft RFC, the Plan 9 manual
# section-5 and the Plan 9 headers (particularly fcall.h) are a better
# references.
version "9P2000"

# data (u32le `n`, then `n` bytes of data)
d = "len[4] len*(dat[1])"

# string (u16le `n`, then `n` bytes of UTF-8)
s = "len[2] len*(utf8[1])"

bitfield qid_type 8
	7/DIR
	6/APPEND
	5/EXCL
	# QTMOUNT has been around in Plan 9 forever, but is
	# undocumented, and is explicitly excluded from the 9P2000
	# draft RFC.  As I understand it, QTMOUNT indicates that the
	# file is mounted by the kernel as a 9P transport; that the
	# kernel has a lock on doing I/O on it, so userspace can't do
	# I/O on it.
	4/_PLAN9_MOUNT
	3/AUTH
	# Fun historical fact: QTTMP was a relatively late addition to
	# Plan 9, in 2003-12.
	2/TMP
	#1/unused
	FILE=0

# uniQue IDentification - "two files on the same server hierarchy are
# the same if and only if their qids are the same"
#
#  - "path" is a unique uint64_t that does most of the work in the
#    above statement about files being the same if their QIDs are the
#    same; " If a file is deleted and recreated with the same name in
#    the same directory, the old and new path components of the qids
#    should be different"
#
#  - "vers" "is a version number for a file; typically, it is
#    incremented every time the file is modified.
#
#  - "type" indicates "whether the file is a directory, append-only
#    file, etc."; is an instance of the qid_type bitfield.
qid = "type[qid_type] vers[4] path[8]"

# stat (TODO)
stat = "stat_size[2]"
       "kern_type[2]"
       "kern_dev[4]"
       "file_qid[qid]"
       "file_mode[4]"
       "file_atime[4]"
       "file_mtime[4]"
       "file_size[8]"
       "file_name[s]"
       "file_owner_uid[s]"
       "file_owner_gid[s]"
       "file_last_modified_uid[s]"

# In the 9P protocol, each message has a type, and message types come
# in pairs (except "Rerror"); "T" and "R"; "T" messages are
# client->server requests, and "R" messages are server->client
# responses (I do not know what the Plan 9 designers intended "T" and
# "R" to stand for).  The type of a message is represented by a u8 ID.
100/Tversion = "max_msg_size[4] version[s]"
101/Rversion = "max_msg_size[4] version[s]"
102/Tauth    = "afid[4] uname[s] aname[s]"
103/Rauth    = "aqid[qid]"
104/Tattach  = "fid[4] afid[4] uname[s] aname[s]"
105/Rattach  = "qid[qid]"
#106/Terror   = "illegal"
107/Rerror   = "ename[s]"
108/Tflush   = "oldtag[2]"
109/Rflush   = ""
110/Twalk    = "fid[4] newfid[4] nwname[2] nwname*(wname[s])"
111/Rwalk    = "nwqid[2] nwqid*(wqid[qid])"
112/Topen    = "fid[4] mode[1]"
113/Ropen    = "qid[qid] iounit[4]"
114/Tcreate  = "fid[4] name[s] perm[4] mode[1]"
115/Rcreate  = "qid[qid] iounit[4]"
116/Tread    = "fid[4] offset[8] count[4]"
117/Rread    = "data[d]" # for directories data is the sequence "cnt*(entries[stat])"
118/Twrite   = "fid[4] offset[8] data[d]"
119/Rwrite   = "count[4]"
120/Tclunk   = "fid[4]"
121/Rclunk   = ""
122/Tremove  = "fid[4]"
123/Rremove  = ""
124/Tstat    = "fid[4]"
125/Rstat    = "stat[stat]"
126/Twstat   = "fid[4] stat[stat]"
127/Rwstat   = ""