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
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
|
Ninep: module
{
PATH: con "/dis/lib/ninep.dis";
VERSION: con "9P2000";
MAXWELEM: con 16;
NOTAG: con 16rFFFF;
NOFID: con int ~0; # 32 bits in this version of 9P
BIT8SZ: con 1;
BIT16SZ: con 2;
BIT32SZ: con 4;
BIT64SZ: con 8;
QIDSZ: con BIT8SZ+BIT32SZ+BIT64SZ;
STATFIXLEN: con BIT16SZ+QIDSZ+5*BIT16SZ+4*BIT32SZ+BIT64SZ; # amount of fixed length data in a stat buffer
IOHDRSZ: con 24; # room for Twrite/Rread header
DEFIOUNIT: con 8192; # `reasonable' iounit
DEFMSIZE: con IOHDRSZ+DEFIOUNIT; # usable default for fversion and iounit
Tversion, # 100
Rversion,
Tauth, # 102
Rauth,
Tattach, # 104
Rattach,
Terror, # 106, illegal
Rerror,
Tflush, #108
Rflush,
Twalk, # 110
Rwalk,
Topen, # 112
Ropen,
Tcreate, # 114
Rcreate,
Tread, # 116
Rread,
Twrite, # 118
Rwrite,
Tclunk, # 120
Rclunk,
Tremove, # 122
Rremove,
Tstat, # 124
Rstat,
Twstat, #126
Rwstat,
Tmax: con 100+iota;
ERRMAX: con 128;
OREAD: con 0; # open for read
OWRITE: con 1; # write
ORDWR: con 2; # read and write
OEXEC: con 3; # execute, == read but check execute permission
OTRUNC: con 16; # or'ed in (except for exec), truncate file first
ORCLOSE: con 64; # or'ed in, remove on close
# mode bits in Dir.mode used by the protocol
DMDIR: con int 1<<31; # mode bit for directory
DMAPPEND: con int 1<<30; # mode bit for append-only files
DMEXCL: con int 1<<29; # mode bit for exclusive use files
DMAUTH: con int 1<<27; # mode bit for authentication files
# Qid.qtype
QTDIR: con 16r80;
QTAPPEND: con 16r40;
QTEXCL: con 16r20;
QTAUTH: con 16r08;
QTFILE: con 16r00;
Tmsg: adt {
tag: int;
pick {
Readerror =>
error: string; # tag is unused in this case
Version =>
msize: int;
version: string;
Auth =>
afid: int;
uname, aname: string;
Attach =>
fid, afid: int;
uname, aname: string;
Flush =>
oldtag: int;
Walk =>
fid, newfid: int;
names: array of string;
Open =>
fid, mode: int;
Create =>
fid: int;
name: string;
perm, mode: int;
Read =>
fid: int;
offset: big;
count: int;
Write =>
fid: int;
offset: big;
data: array of byte;
Clunk or
Stat or
Remove =>
fid: int;
Wstat =>
fid: int;
stat: Sys->Dir;
}
read: fn(fd: ref Sys->FD, msize: int): ref Tmsg;
unpack: fn(a: array of byte): (int, ref Tmsg);
pack: fn(nil: self ref Tmsg): array of byte;
packedsize: fn(nil: self ref Tmsg): int;
text: fn(nil: self ref Tmsg): string;
mtype: fn(nil: self ref Tmsg): int;
};
Rmsg: adt {
tag: int;
pick {
Readerror =>
error: string; # tag is unused in this case
Version =>
msize: int;
version: string;
Auth =>
aqid: Sys->Qid;
Attach =>
qid: Sys->Qid;
Flush =>
Error =>
ename: string;
Clunk or
Remove or
Wstat =>
Walk =>
qids: array of Sys->Qid;
Create or
Open =>
qid: Sys->Qid;
iounit: int;
Read =>
data: array of byte;
Write =>
count: int;
Stat =>
stat: Sys->Dir;
}
read: fn(fd: ref Sys->FD, msize: int): ref Rmsg;
unpack: fn(a: array of byte): (int, ref Rmsg);
pack: fn(nil: self ref Rmsg): array of byte;
packedsize: fn(nil: self ref Rmsg): int;
text: fn(nil: self ref Rmsg): string;
mtype: fn(nil: self ref Rmsg): int;
};
init: fn();
readmsg: fn(fd: ref Sys->FD, msize: int): (array of byte, string);
istmsg: fn(f: array of byte): int;
compatible: fn(t: ref Tmsg.Version, msize: int, version: string): (int, string);
packdirsize: fn(d: Sys->Dir): int;
packdir: fn(d: Sys->Dir): array of byte;
unpackdir: fn(f: array of byte): (int, Sys->Dir);
dir2text: fn(d: Sys->Dir): string;
qid2text: fn(q: Sys->Qid): string;
utflen: fn(s: string): int;
};
|