Blob


1 package p9pnew
3 import "fmt"
5 type FcallType uint8
7 const (
8 Tversion FcallType = iota + 100
9 Rversion
10 Tauth
11 Rauth
12 Tattach
13 Rattach
14 Terror
15 Rerror
16 Tflush
17 Rflush
18 Twalk
19 Rwalk
20 Topen
21 Ropen
22 Tcreate
23 Rcreate
24 Tread
25 Rread
26 Twrite
27 Rwrite
28 Tclunk
29 Rclunk
30 Tremove
31 Rremove
32 Tstat
33 Rstat
34 Twstat
35 Rwstat
36 Tmax
37 )
39 func (fct FcallType) String() string {
40 switch fct {
41 case Tversion:
42 return "Tversion"
43 case Rversion:
44 return "Rversion"
45 case Tauth:
46 return "Tauth"
47 case Rauth:
48 return "Rauth"
49 case Tattach:
50 return "Tattach"
51 case Rattach:
52 return "Rattach"
53 case Terror:
54 // invalid.
55 return "Terror"
56 case Rerror:
57 return "Rerror"
58 case Tflush:
59 return "Tflush"
60 case Rflush:
61 return "Rflush"
62 case Twalk:
63 return "Twalk"
64 case Rwalk:
65 return "Rwalk"
66 case Topen:
67 return "Topen"
68 case Ropen:
69 return "Ropen"
70 case Tcreate:
71 return "Tcreate"
72 case Rcreate:
73 return "Rcreate"
74 case Tread:
75 return "Tread"
76 case Rread:
77 return "Rread"
78 case Twrite:
79 return "Twrite"
80 case Rwrite:
81 return "Rwrite"
82 case Tclunk:
83 return "Tclunk"
84 case Rclunk:
85 return "Rclunk"
86 case Tremove:
87 return "Tremote"
88 case Rremove:
89 return "Rremove"
90 case Tstat:
91 return "Tstat"
92 case Rstat:
93 return "Rstat"
94 case Twstat:
95 return "Twstat"
96 case Rwstat:
97 return "Rwstat"
98 default:
99 return "Tunknown"
103 type Fcall struct {
104 Type FcallType
105 Tag Tag
106 Message Message
109 func newFcall(msg Message) *Fcall {
110 var tag Tag
112 switch msg.Type() {
113 case Tversion, Rversion:
114 tag = NOTAG
117 return &Fcall{
118 Type: msg.Type(),
119 Tag: tag,
120 Message: msg,
124 func newErrorFcall(tag Tag, err error) *Fcall {
125 var msg Message
127 switch v := err.(type) {
128 case MessageRerror:
129 msg = v
130 case *MessageRerror:
131 msg = v
132 default:
133 msg = MessageRerror{Ename: v.Error()}
136 return &Fcall{
137 Type: Rerror,
138 Tag: tag,
139 Message: msg,
143 func (fc *Fcall) String() string {
144 return fmt.Sprintf("%v(%v) %v", fc.Type, fc.Tag, string9p(fc.Message))
147 type Message interface {
148 // Type indicates the Fcall type of the message. This must match
149 // Fcall.Type.
150 Type() FcallType
153 // newMessage returns a new instance of the message based on the Fcall type.
154 func newMessage(typ FcallType) (Message, error) {
155 // NOTE(stevvooe): This is a nasty bit of code but makes the transport
156 // fairly simple to implement.
157 switch typ {
158 case Tversion:
159 return &MessageTversion{}, nil
160 case Rversion:
161 return &MessageRversion{}, nil
162 case Tauth:
163 return &MessageTauth{}, nil
164 case Rauth:
165 return &MessageRauth{}, nil
166 case Tattach:
167 return &MessageTattach{}, nil
168 case Rattach:
169 return &MessageRattach{}, nil
170 case Rerror:
171 return &MessageRerror{}, nil
172 case Tflush:
173 return &MessageTflush{}, nil
174 case Rflush:
175 return &MessageRflush{}, nil // No message body for this response.
176 case Twalk:
177 return &MessageTwalk{}, nil
178 case Rwalk:
179 return &MessageRwalk{}, nil
180 case Topen:
181 return &MessageTopen{}, nil
182 case Ropen:
183 return &MessageRopen{}, nil
184 case Tcreate:
185 return &MessageTcreate{}, nil
186 case Rcreate:
187 return &MessageRcreate{}, nil
188 case Tread:
189 return &MessageTread{}, nil
190 case Rread:
191 return &MessageRread{}, nil
192 case Twrite:
193 return &MessageTwrite{}, nil
194 case Rwrite:
195 return &MessageRwrite{}, nil
196 case Tclunk:
197 return &MessageTclunk{}, nil
198 case Rclunk:
199 return &MessageRclunk{}, nil // no response body
200 case Tremove:
202 case Rremove:
204 case Tstat:
206 case Rstat:
207 return &MessageRstat{}, nil
208 case Twstat:
210 case Rwstat:
214 return nil, fmt.Errorf("unknown message type")
217 // MessageVersion encodes the message body for Tversion and Rversion RPC
218 // calls. The body is identical in both directions.
219 type MessageTversion struct {
220 MSize uint32
221 Version string
224 type MessageRversion struct {
225 MSize uint32
226 Version string
229 type MessageTauth struct {
230 Afid Fid
231 Uname string
232 Aname string
235 type MessageRauth struct {
236 Qid Qid
239 type MessageRerror struct {
240 Ename string
243 func (e MessageRerror) Error() string {
244 return fmt.Sprintf("9p: %v", e.Ename)
247 type MessageTflush struct {
248 Oldtag Tag
251 type MessageRflush struct{}
253 type MessageTattach struct {
254 Fid Fid
255 Afid Fid
256 Uname string
257 Aname string
260 type MessageRattach struct {
261 Qid Qid
264 type MessageTwalk struct {
265 Fid Fid
266 Newfid Fid
267 Wnames []string
270 type MessageRwalk struct {
271 Qids []Qid
274 type MessageTopen struct {
275 Fid Fid
276 Mode uint8
279 type MessageRopen struct {
280 Qid Qid
281 IOUnit uint32
284 type MessageTcreate struct {
285 Fid Fid
286 Name string
287 Perm uint32
288 Mode uint8
291 type MessageRcreate struct {
292 Qid Qid
293 IOUnit uint32
296 type MessageTread struct {
297 Fid Fid
298 Offset uint64
299 Count uint32
302 type MessageRread struct {
303 Data []byte
306 type MessageTwrite struct {
307 Fid Fid
308 Offset uint64
309 Data []byte
312 type MessageRwrite struct {
313 Count uint32
316 type MessageTclunk struct {
317 Fid Fid
320 type MessageRclunk struct{}
322 type MessageTremove struct {
323 Fid Fid
326 type MessageRremove struct{}
328 type MessageTstat struct {
329 Fid Fid
332 type MessageRstat struct {
333 Stat Dir
336 type MessageTwstat struct {
337 Fid Fid
338 Stat Dir
341 func (MessageTversion) Type() FcallType { return Tversion }
342 func (MessageRversion) Type() FcallType { return Rversion }
343 func (MessageTauth) Type() FcallType { return Tauth }
344 func (MessageRauth) Type() FcallType { return Rauth }
345 func (MessageTflush) Type() FcallType { return Tflush }
346 func (MessageRflush) Type() FcallType { return Rflush }
347 func (MessageRerror) Type() FcallType { return Rerror }
348 func (MessageTattach) Type() FcallType { return Tattach }
349 func (MessageRattach) Type() FcallType { return Rattach }
350 func (MessageTwalk) Type() FcallType { return Twalk }
351 func (MessageRwalk) Type() FcallType { return Rwalk }
352 func (MessageTopen) Type() FcallType { return Topen }
353 func (MessageRopen) Type() FcallType { return Ropen }
354 func (MessageTcreate) Type() FcallType { return Tcreate }
355 func (MessageRcreate) Type() FcallType { return Rcreate }
356 func (MessageTread) Type() FcallType { return Tread }
357 func (MessageRread) Type() FcallType { return Rread }
358 func (MessageTwrite) Type() FcallType { return Twrite }
359 func (MessageRwrite) Type() FcallType { return Rwrite }
360 func (MessageTclunk) Type() FcallType { return Tclunk }
361 func (MessageRclunk) Type() FcallType { return Rclunk }
362 func (MessageTremove) Type() FcallType { return Tremove }
363 func (MessageRremove) Type() FcallType { return Rremove }
364 func (MessageTstat) Type() FcallType { return Tstat }
365 func (MessageRstat) Type() FcallType { return Rstat }
366 func (MessageTwstat) Type() FcallType { return Twstat }