lib9p

Go 9P library.
Log | Files | Refs | LICENSE

fcall.go (32530B)


      1 package lib9p
      2 
      3 import (
      4 	"fmt"
      5 )
      6 
      7 // A MsgType is Message type defined by 9P.
      8 type MsgType uint8
      9 
     10 const (
     11 	Tversion MsgType = 100
     12 	Rversion         = 101
     13 	Tauth            = 102
     14 	Rauth            = 103
     15 	Tattach          = 104
     16 	Rattach          = 105
     17 	Terror           = 106 /* illegal */
     18 	Rerror           = 107
     19 	Tflush           = 108
     20 	Rflush           = 109
     21 	Twalk            = 110
     22 	Rwalk            = 111
     23 	Topen            = 112
     24 	Ropen            = 113
     25 	Tcreate          = 114
     26 	Rcreate          = 115
     27 	Tread            = 116
     28 	Rread            = 117
     29 	Twrite           = 118
     30 	Rwrite           = 119
     31 	Tclunk           = 120
     32 	Rclunk           = 121
     33 	Tremove          = 122
     34 	Rremove          = 123
     35 	Tstat            = 124
     36 	Rstat            = 125
     37 	Twstat           = 126
     38 	Rwstat           = 127
     39 	Tmax             = 128
     40 )
     41 
     42 // IOHDRSZ is the ample room for Twrite/Rread header.
     43 //   - Twrite: size[4] type[1] Tag[2] fid[4] offset[8] count[4] = 23
     44 //   - Rread:  size[4] type[1] Tag[2] count[4] = 11
     45 //
     46 // In Plan9, this const is 24.
     47 const IOHDRSZ = 23
     48 
     49 // The Tag used by version messages.
     50 // The client can use it, when establishing a connection, to
     51 // override Tag matching in version messages.
     52 const NOTAG = ^uint16(0)
     53 
     54 // A Msg represents any kind of message of 9P.
     55 // It defines methods for common fields.
     56 // For each message type <T>, new<T>([]byte) function parses the byte array
     57 // of 9P message into the corresponding message struct.
     58 // For detailed information on each message, consult the documentation
     59 // of 9P protocol.
     60 type Msg interface {
     61 	// Size returns the size field of message.
     62 	// Size field holds the size of the message in bytes
     63 	// including the 4-byte size field itself.
     64 	Size() uint32
     65 	// Type returns the type field of message.
     66 	Type() MsgType
     67 	// GetTag returns the Tag of message.
     68 	// Tag is the identifier of each message.
     69 	// The Get prefix is to avoid name confliction with the each
     70 	// message's Tag field.
     71 	GetTag() uint16
     72 	// SetTag sets the Tag field of the message.
     73 	SetTag(uint16)
     74 	// Marshal convert Msg to byte array to be transmitted.
     75 	marshal() []byte
     76 	String() string
     77 }
     78 
     79 // A bufMsg is Msg with just an array of bytes.
     80 // TODO: rename.
     81 type bufMsg []byte
     82 
     83 func (msg bufMsg) Size() uint32    { return gbit32(msg[0:4]) }
     84 func (msg bufMsg) Type() MsgType   { return MsgType(msg[4]) }
     85 func (msg bufMsg) GetTag() uint16  { return gbit16(msg[5:7]) }
     86 func (msg bufMsg) SetTag(t uint16) { pbit16(msg[5:7], t) }
     87 func (msg bufMsg) marshal() []byte { return []byte(msg)[:msg.Size()] }
     88 func (msg bufMsg) String() string {
     89 	switch msg.Type() {
     90 	case Tversion:
     91 		return newTVersion(msg).String()
     92 	case Rversion:
     93 		return newRVersion(msg).String()
     94 	case Tauth:
     95 		return newTAuth(msg).String()
     96 	case Rauth:
     97 		return newRAuth(msg).String()
     98 	case Tattach:
     99 		return newTAttach(msg).String()
    100 	case Rattach:
    101 		return newRAttach(msg).String()
    102 	case Rerror:
    103 		return newRError(msg).String()
    104 	case Tflush:
    105 		return newTFlush(msg).String()
    106 	case Rflush:
    107 		return newRFlush(msg).String()
    108 	case Twalk:
    109 		return newTWalk(msg).String()
    110 	case Rwalk:
    111 		return newRWalk(msg).String()
    112 	case Topen:
    113 		return newTOpen(msg).String()
    114 	case Ropen:
    115 		return newROpen(msg).String()
    116 	case Tcreate:
    117 		return newTCreate(msg).String()
    118 	case Rcreate:
    119 		return newRCreate(msg).String()
    120 	case Tread:
    121 		return newTRead(msg).String()
    122 	case Rread:
    123 		return newRRead(msg).String()
    124 	case Twrite:
    125 		return newTWrite(msg).String()
    126 	case Rwrite:
    127 		return newRWrite(msg).String()
    128 	case Tclunk:
    129 		return newTClunk(msg).String()
    130 	case Rclunk:
    131 		return newRClunk(msg).String()
    132 	case Tremove:
    133 		return newTRemove(msg).String()
    134 	case Rremove:
    135 		return newRRemove(msg).String()
    136 	case Tstat:
    137 		return newTStat(msg).String()
    138 	case Rstat:
    139 		return newRStat(msg).String()
    140 	case Twstat:
    141 		return newTWstat(msg).String()
    142 	case Rwstat:
    143 		return newRWstat(msg).String()
    144 	default:
    145 		return fmt.Sprint([]byte(msg[:msg.Size()]))
    146 	}
    147 }
    148 
    149 type TVersion struct {
    150 	Tag     uint16
    151 	Msize   uint32
    152 	Version string
    153 }
    154 
    155 func newTVersion(buf []byte) *TVersion {
    156 	msg := new(TVersion)
    157 	msg.Tag = gbit16(buf[5:7])
    158 	msg.Msize = gbit32(buf[7:11])
    159 	vs := gbit16(buf[11:13])
    160 	msg.Version = string(buf[13 : 13+vs])
    161 	return msg
    162 }
    163 func (msg *TVersion) Size() uint32    { return uint32(4 + 1 + 2 + 4 + 2 + len(msg.Version)) }
    164 func (msg *TVersion) Type() MsgType   { return Tversion }
    165 func (msg *TVersion) GetTag() uint16  { return msg.Tag }
    166 func (msg *TVersion) SetTag(t uint16) { msg.Tag = t }
    167 func (msg *TVersion) marshal() []byte {
    168 	m := make([]byte, msg.Size())
    169 	pbit32(m[0:4], msg.Size())
    170 	m[4] = uint8(Tversion)
    171 	pbit16(m[5:7], msg.Tag)
    172 	pbit32(m[7:11], msg.Msize)
    173 	v := msg.Version
    174 	pbit16(m[11:13], uint16(len(v)))
    175 	for i := 0; i < len(v); i++ {
    176 		m[13+i] = v[i]
    177 	}
    178 	return m
    179 }
    180 func (msg *TVersion) String() string {
    181 	return fmt.Sprintf("Tversion Tag %d msize %d version '%s'",
    182 		msg.Tag, msg.Msize, msg.Version)
    183 }
    184 
    185 type RVersion struct {
    186 	Tag     uint16
    187 	Msize   uint32
    188 	Version string
    189 }
    190 
    191 func newRVersion(buf []byte) *RVersion {
    192 	msg := new(RVersion)
    193 	msg.Tag = gbit16(buf[5:7])
    194 	msg.Msize = gbit32(buf[7:11])
    195 	vs := gbit16(buf[11:13])
    196 	msg.Version = string(buf[13 : 13+vs])
    197 	return msg
    198 }
    199 func (msg *RVersion) Size() uint32    { return uint32(4 + 1 + 2 + 4 + 2 + len(msg.Version)) }
    200 func (msg *RVersion) Type() MsgType   { return Rversion }
    201 func (msg *RVersion) GetTag() uint16  { return msg.Tag }
    202 func (msg *RVersion) SetTag(t uint16) { msg.Tag = t }
    203 func (msg *RVersion) marshal() []byte {
    204 	cur := 0
    205 	buf := make([]byte, msg.Size())
    206 	pbit32(buf[cur:cur+4], msg.Size())
    207 	cur += 4
    208 	buf[cur] = uint8(Rversion)
    209 	cur += 1
    210 	pbit16(buf[cur:cur+2], msg.Tag)
    211 	cur += 2
    212 	pbit32(buf[cur:cur+4], msg.Msize)
    213 	cur += 4
    214 	pbit16(buf[cur:cur+2], uint16(len(msg.Version)))
    215 	cur += 2
    216 	for i, b := range []byte(msg.Version) {
    217 		buf[cur+i] = b
    218 	}
    219 	cur += len(msg.Version)
    220 	if cur != len(buf) {
    221 		panic("length of buf and cursor not match")
    222 	}
    223 	return buf
    224 }
    225 func (msg *RVersion) String() string {
    226 	return fmt.Sprintf("Rversion Tag %d msize %d version '%s'",
    227 		msg.Tag, msg.Msize, msg.Version)
    228 }
    229 
    230 type TAuth struct {
    231 	Tag   uint16
    232 	Afid  uint32
    233 	Uname string
    234 	Aname string
    235 }
    236 
    237 func newTAuth(buf []byte) *TAuth {
    238 	cur := 0
    239 	msg := new(TAuth)
    240 	cur += 4
    241 	cur += 1 // message type
    242 	msg.Tag = gbit16(buf[cur : cur+2])
    243 	cur += 2
    244 	msg.Afid = gbit32(buf[cur : cur+4])
    245 	cur += 4
    246 	l := int(gbit16(buf[cur : cur+2]))
    247 	cur += 2
    248 	msg.Uname = string(buf[cur : cur+l])
    249 	cur += l
    250 	l = int(gbit16(buf[cur : cur+2]))
    251 	cur += 2
    252 	msg.Aname = string(buf[cur : cur+l])
    253 	cur += l
    254 	if cur != int(gbit32(buf[0:4])) {
    255 		panic("length of buf and cursor position not match")
    256 	}
    257 	return msg
    258 }
    259 func (msg *TAuth) Size() uint32 {
    260 	return uint32(4 + 1 + 2 + 4 + 2 + len(msg.Uname) + 2 + len(msg.Aname))
    261 }
    262 func (msg *TAuth) Type() MsgType   { return Tauth }
    263 func (msg *TAuth) GetTag() uint16  { return msg.Tag }
    264 func (msg *TAuth) SetTag(t uint16) { msg.Tag = t }
    265 func (msg *TAuth) marshal() []byte {
    266 	cur := 0
    267 	buf := make([]byte, msg.Size())
    268 	pbit32(buf[cur:cur+4], msg.Size())
    269 	cur += 4
    270 	buf[cur] = uint8(Tauth)
    271 	cur += 1
    272 	pbit16(buf[cur:cur+2], msg.Tag)
    273 	cur += 2
    274 	pbit32(buf[cur:cur+4], msg.Afid)
    275 	cur += 4
    276 	pbit16(buf[cur:cur+2], uint16(len(msg.Uname)))
    277 	cur += 2
    278 	for i := 0; i < len(msg.Uname); i++ {
    279 		buf[cur+i] = msg.Uname[i]
    280 	}
    281 	cur += len(msg.Uname)
    282 	pbit16(buf[cur:cur+2], uint16(len(msg.Aname)))
    283 	cur += 2
    284 	for i := 0; i < len(msg.Aname); i++ {
    285 		buf[cur+i] = msg.Aname[i]
    286 	}
    287 	cur += len(msg.Aname)
    288 	if cur != len(buf) {
    289 		panic("length of buf and cursor position don't match")
    290 	}
    291 	return buf
    292 }
    293 func (msg *TAuth) String() string {
    294 	afid := int64(msg.Afid)
    295 	if afid == int64(NOFID) {
    296 		afid = -1
    297 	}
    298 	return fmt.Sprintf("Tauth Tag %d afid %d uname %s aname %s",
    299 		msg.Tag, afid, msg.Uname, msg.Aname)
    300 }
    301 
    302 type RAuth struct {
    303 	Tag  uint16
    304 	Aqid Qid
    305 }
    306 
    307 func newRAuth(buf []byte) *RAuth {
    308 	msg := new(RAuth)
    309 	msg.Tag = gbit16(buf[5:7])
    310 	msg.Aqid = unmarshalQid(buf[7:])
    311 	return msg
    312 }
    313 func (msg *RAuth) Size() uint32    { return 4 + 1 + 2 + 13 }
    314 func (msg *RAuth) Type() MsgType   { return Rauth }
    315 func (msg *RAuth) GetTag() uint16  { return msg.Tag }
    316 func (msg *RAuth) SetTag(t uint16) { msg.Tag = t }
    317 func (msg *RAuth) marshal() []byte {
    318 	cur := 0
    319 	buf := make([]byte, msg.Size())
    320 	pbit32(buf[cur:cur+4], msg.Size())
    321 	cur += 4
    322 	buf[cur] = uint8(Rauth)
    323 	cur += 1
    324 	pbit16(buf[cur:cur+2], msg.Tag)
    325 	cur += 2
    326 	qid := msg.Aqid.marshal()
    327 	for i := 0; i < len(qid); i++ {
    328 		buf[cur+i] = qid[i]
    329 	}
    330 	cur += len(qid)
    331 	if cur != len(buf) {
    332 		panic("length of buf and cursor position don't match")
    333 	}
    334 	return buf
    335 }
    336 func (msg *RAuth) String() string {
    337 	return fmt.Sprintf("Tauth Tag %d aqid %v",
    338 		msg.Tag, msg.Aqid)
    339 }
    340 
    341 type TAttach struct {
    342 	Tag   uint16
    343 	Fid   uint32
    344 	Afid  uint32
    345 	Uname string
    346 	Aname string
    347 }
    348 
    349 func newTAttach(buf []byte) *TAttach {
    350 	cur := 0
    351 	msg := new(TAttach)
    352 	cur += 4
    353 	cur += 1 // message type
    354 	msg.Tag = gbit16(buf[cur : cur+2])
    355 	cur += 2
    356 	msg.Fid = gbit32(buf[cur : cur+4])
    357 	cur += 4
    358 	msg.Afid = gbit32(buf[cur : cur+4])
    359 	cur += 4
    360 	l := int(gbit16(buf[cur : cur+2]))
    361 	cur += 2
    362 	msg.Uname = string(buf[cur : cur+l])
    363 	cur += l
    364 	l = int(gbit16(buf[cur : cur+2]))
    365 	cur += 2
    366 	msg.Aname = string(buf[cur : cur+l])
    367 	cur += l
    368 	if cur != int(gbit32(buf[0:4])) {
    369 		panic("length of buf and cursor position not match")
    370 	}
    371 	return msg
    372 }
    373 func (msg *TAttach) Size() uint32 {
    374 	return uint32(4 + 1 + 2 + 4 + 4 + 2 + len(msg.Uname) + 2 + len(msg.Aname))
    375 }
    376 func (msg *TAttach) Type() MsgType   { return Tattach }
    377 func (msg *TAttach) GetTag() uint16  { return msg.Tag }
    378 func (msg *TAttach) SetTag(t uint16) { msg.Tag = t }
    379 func (msg *TAttach) marshal() []byte {
    380 	cur := 0
    381 	buf := make([]byte, msg.Size())
    382 	pbit32(buf[cur:cur+4], msg.Size())
    383 	cur += 4
    384 	buf[cur] = uint8(msg.Type())
    385 	cur += 1
    386 	pbit16(buf[cur:cur+2], msg.Tag)
    387 	cur += 2
    388 	pbit32(buf[cur:cur+4], msg.Fid)
    389 	cur += 4
    390 	pbit32(buf[cur:cur+4], msg.Afid)
    391 	cur += 4
    392 	pbit16(buf[cur:cur+2], uint16(len(msg.Uname)))
    393 	cur += 2
    394 	for i := 0; i < len(msg.Uname); i++ {
    395 		buf[cur+i] = msg.Uname[i]
    396 	}
    397 	cur += len(msg.Uname)
    398 	pbit16(buf[cur:cur+2], uint16(len(msg.Aname)))
    399 	cur += 2
    400 	for i := 0; i < len(msg.Aname); i++ {
    401 		buf[cur+i] = msg.Aname[i]
    402 	}
    403 	cur += len(msg.Aname)
    404 	if cur != len(buf) {
    405 		panic("length of buf and cursor position don't match")
    406 	}
    407 	return buf
    408 }
    409 func (msg *TAttach) String() string {
    410 	fid := int64(msg.Fid)
    411 	if fid == int64(NOFID) {
    412 		fid = -1
    413 	}
    414 	afid := int64(msg.Afid)
    415 	if afid == int64(NOFID) {
    416 		afid = -1
    417 	}
    418 	return fmt.Sprintf("Tattach Tag %d fid %d afid %d uname %s aname %s",
    419 		msg.Tag, fid, afid, msg.Uname, msg.Aname)
    420 }
    421 
    422 type RAttach struct {
    423 	Tag uint16
    424 	Qid Qid
    425 }
    426 
    427 func newRAttach(buf []byte) *RAttach {
    428 	msg := new(RAttach)
    429 	msg.Tag = gbit16(buf[5:7])
    430 	msg.Qid = unmarshalQid(buf[7:])
    431 	return msg
    432 }
    433 func (msg *RAttach) Size() uint32    { return 4 + 1 + 2 + 13 }
    434 func (msg *RAttach) Type() MsgType   { return Rattach }
    435 func (msg *RAttach) GetTag() uint16  { return msg.Tag }
    436 func (msg *RAttach) SetTag(t uint16) { msg.Tag = t }
    437 func (msg *RAttach) marshal() []byte {
    438 	cur := 0
    439 	buf := make([]byte, msg.Size())
    440 	pbit32(buf[cur:cur+4], msg.Size())
    441 	cur += 4
    442 	buf[cur] = uint8(Rattach)
    443 	cur += 1
    444 	pbit16(buf[cur:cur+2], msg.Tag)
    445 	cur += 2
    446 	qid := msg.Qid.marshal()
    447 	for i := 0; i < len(qid); i++ {
    448 		buf[cur+i] = qid[i]
    449 	}
    450 	cur += len(qid)
    451 	if cur != len(buf) {
    452 		panic("length of buf and cursor position don't match")
    453 	}
    454 	return buf
    455 }
    456 func (msg *RAttach) String() string {
    457 	return fmt.Sprintf("Rattach Tag %d qid %v",
    458 		msg.Tag, msg.Qid)
    459 }
    460 
    461 type RError struct {
    462 	Tag   uint16
    463 	Ename error
    464 }
    465 
    466 func newRError(buf []byte) *RError {
    467 	msg := new(RError)
    468 	msg.Tag = gbit16(buf[5:7])
    469 	es := gbit16(buf[7:9])
    470 	msg.Ename = fmt.Errorf("%s", string(buf[9:9+es]))
    471 	return msg
    472 }
    473 func (msg *RError) Size() uint32    { return uint32(4 + 1 + 2 + 2 + len(msg.Ename.Error())) }
    474 func (msg *RError) Type() MsgType   { return Rerror }
    475 func (msg *RError) GetTag() uint16  { return msg.Tag }
    476 func (msg *RError) SetTag(t uint16) { msg.Tag = t }
    477 func (msg *RError) marshal() []byte {
    478 	cur := 0
    479 	buf := make([]byte, msg.Size())
    480 	pbit32(buf[cur:cur+4], msg.Size())
    481 	cur += 4
    482 	buf[cur] = uint8(Rerror)
    483 	cur += 1
    484 	pbit16(buf[cur:cur+2], msg.Tag)
    485 	cur += 2
    486 	ename := msg.Ename.Error()
    487 	pbit16(buf[cur:cur+2], uint16(len(ename)))
    488 	cur += 2
    489 	for i := 0; i < len(ename); i++ {
    490 		buf[cur+i] = ename[i]
    491 	}
    492 	cur += len(ename)
    493 	if cur != len(buf) {
    494 		panic("length of buf and cursor position don't match")
    495 	}
    496 	return buf
    497 }
    498 
    499 func (msg *RError) String() string {
    500 	return fmt.Sprintf("Rerror Tag %d ename %v", msg.Tag, msg.Ename.Error())
    501 }
    502 
    503 type TFlush struct {
    504 	Tag    uint16
    505 	Oldtag uint16
    506 }
    507 
    508 func newTFlush(buf []byte) *TFlush {
    509 	msg := new(TFlush)
    510 	msg.Tag = gbit16(buf[5:7])
    511 	msg.Oldtag = gbit16(buf[7:9])
    512 	return msg
    513 }
    514 
    515 func (msg *TFlush) Size() uint32    { return 9 }
    516 func (msg *TFlush) Type() MsgType   { return Tflush }
    517 func (msg *TFlush) GetTag() uint16  { return msg.Tag }
    518 func (msg *TFlush) SetTag(t uint16) { msg.Tag = t }
    519 func (msg *TFlush) marshal() []byte {
    520 	buf := make([]byte, msg.Size())
    521 	pbit32(buf[0:4], msg.Size())
    522 	buf[4] = uint8(msg.Type())
    523 	pbit16(buf[5:7], msg.Tag)
    524 	pbit16(buf[7:9], msg.Oldtag)
    525 	return buf
    526 }
    527 func (msg *TFlush) String() string {
    528 	return fmt.Sprintf("Tflush Tag %d oldTag %d", msg.Tag, msg.Oldtag)
    529 }
    530 
    531 type RFlush struct {
    532 	Tag uint16
    533 }
    534 
    535 func newRFlush(buf []byte) *RFlush {
    536 	msg := new(RFlush)
    537 	msg.Tag = gbit16(buf[5:7])
    538 	return msg
    539 }
    540 
    541 func (msg *RFlush) Size() uint32    { return 7 }
    542 func (msg *RFlush) Type() MsgType   { return Rflush }
    543 func (msg *RFlush) GetTag() uint16  { return msg.Tag }
    544 func (msg *RFlush) SetTag(t uint16) { msg.Tag = t }
    545 func (msg *RFlush) marshal() []byte {
    546 	buf := make([]byte, msg.Size())
    547 	pbit32(buf[0:4], msg.Size())
    548 	buf[4] = uint8(msg.Type())
    549 	pbit16(buf[5:7], msg.Tag)
    550 	return buf
    551 }
    552 func (msg *RFlush) String() string {
    553 	return fmt.Sprintf("Rflush Tag %d", msg.Tag)
    554 }
    555 
    556 type TWalk struct {
    557 	Tag    uint16
    558 	Fid    uint32
    559 	Newfid uint32
    560 	Wnames []string
    561 }
    562 
    563 func newTWalk(buf []byte) *TWalk {
    564 	cur := 0
    565 	msg := new(TWalk)
    566 	msize := gbit32(buf[cur : cur+4])
    567 	cur += 4
    568 	cur += 1 // msgType
    569 	msg.Tag = gbit16(buf[cur : cur+2])
    570 	cur += 2
    571 	msg.Fid = gbit32(buf[cur : cur+4])
    572 	cur += 4
    573 	msg.Newfid = gbit32(buf[cur : cur+4])
    574 	cur += 4
    575 	nwname := gbit16(buf[cur : cur+2])
    576 	cur += 2
    577 	msg.Wnames = make([]string, nwname)
    578 	for i := 0; i < int(nwname); i++ {
    579 		size := int(gbit16(buf[cur : cur+2]))
    580 		cur += 2
    581 		msg.Wnames[i] = string(buf[cur : cur+size])
    582 		cur += size
    583 	}
    584 	if cur != int(msize) {
    585 		panic(fmt.Errorf("message size %d != cursor position %d", msize, cur))
    586 	}
    587 	return msg
    588 }
    589 
    590 func (msg *TWalk) Size() uint32 {
    591 	size := uint32(4 + 1 + 2 + 4 + 4 + 2)
    592 	for _, wn := range msg.Wnames {
    593 		size += 2 + uint32(len(wn))
    594 	}
    595 	return size
    596 }
    597 func (msg *TWalk) Type() MsgType   { return Twalk }
    598 func (msg *TWalk) GetTag() uint16  { return msg.Tag }
    599 func (msg *TWalk) SetTag(t uint16) { msg.Tag = t }
    600 func (msg *TWalk) marshal() []byte {
    601 	cur := 0
    602 	buf := make([]byte, msg.Size())
    603 	pbit32(buf[cur:cur+4], msg.Size())
    604 	cur += 4
    605 	buf[cur] = uint8(Twalk)
    606 	cur += 1
    607 	pbit16(buf[cur:cur+2], msg.Tag)
    608 	cur += 2
    609 	pbit32(buf[cur:cur+4], msg.Fid)
    610 	cur += 4
    611 	pbit32(buf[cur:cur+4], msg.Newfid)
    612 	cur += 4
    613 	nwname := uint16(len(msg.Wnames))
    614 	pbit16(buf[cur:cur+2], nwname)
    615 	cur += 2
    616 	for _, wn := range msg.Wnames {
    617 		pbit16(buf[cur:cur+2], uint16(len(wn)))
    618 		cur += 2
    619 		for i := 0; i < len(wn); i++ {
    620 			buf[cur+i] = wn[i]
    621 		}
    622 		cur += len(wn)
    623 	}
    624 	return buf
    625 }
    626 
    627 func (msg *TWalk) String() string {
    628 	s := fmt.Sprintf("Twalk Tag %d fid %d newfid %d nwname %d",
    629 		msg.Tag, msg.Fid, msg.Newfid, len(msg.Wnames))
    630 	for i, wn := range msg.Wnames {
    631 		s += fmt.Sprintf(" %d:%s", i, wn)
    632 	}
    633 	return s
    634 }
    635 
    636 type RWalk struct {
    637 	Tag  uint16
    638 	Qids []Qid
    639 }
    640 
    641 func newRWalk(buf []byte) *RWalk {
    642 	msg := new(RWalk)
    643 	msg.Tag = gbit16(buf[5:7])
    644 	nwqid := int(gbit16(buf[7:9]))
    645 	msg.Qids = make([]Qid, nwqid)
    646 	cur := 9
    647 	for i := 0; i < nwqid; i++ {
    648 		msg.Qids[i] = unmarshalQid(buf[cur : cur+13])
    649 		cur += 13
    650 	}
    651 	if int(msg.Size()) != cur {
    652 		panic("length of buf and cursor position don't match")
    653 	}
    654 	return msg
    655 }
    656 func (msg *RWalk) Size() uint32 {
    657 	return uint32(4 + 1 + 2 + 2 + len(msg.Qids)*13)
    658 }
    659 func (msg *RWalk) Type() MsgType   { return Rwalk }
    660 func (msg *RWalk) GetTag() uint16  { return msg.Tag }
    661 func (msg *RWalk) SetTag(t uint16) { msg.Tag = t }
    662 func (msg *RWalk) marshal() []byte {
    663 	cur := 0
    664 	buf := make([]byte, msg.Size())
    665 	pbit32(buf[cur:cur+4], msg.Size())
    666 	cur += 4
    667 	buf[cur] = uint8(msg.Type())
    668 	cur += 1
    669 	pbit16(buf[cur:cur+2], msg.Tag)
    670 	cur += 2
    671 	pbit16(buf[cur:cur+2], uint16(len(msg.Qids)))
    672 	cur += 2
    673 	for _, qid := range msg.Qids {
    674 		for i, bit := range qid.marshal() {
    675 			buf[cur+i] = bit
    676 		}
    677 		cur += 13
    678 	}
    679 	if cur != len(buf) {
    680 		panic("length of buf and cursor position don't match")
    681 	}
    682 	return buf
    683 }
    684 func (msg *RWalk) String() string {
    685 	s := fmt.Sprintf("Rwalk Tag %d nwqid %d", msg.Tag, len(msg.Qids))
    686 	for i, q := range msg.Qids {
    687 		s += fmt.Sprintf(" %d:%v", i, q)
    688 	}
    689 	return s
    690 }
    691 
    692 type TOpen struct {
    693 	Tag  uint16
    694 	Fid  uint32
    695 	Mode OpenMode
    696 }
    697 
    698 func newTOpen(buf []byte) *TOpen {
    699 	cur := 0
    700 	msg := new(TOpen)
    701 	size := gbit32(buf[cur : cur+4])
    702 	cur += 4
    703 	cur += 1 // type
    704 	msg.Tag = gbit16(buf[cur : cur+2])
    705 	cur += 2
    706 	msg.Fid = gbit32(buf[cur : cur+4])
    707 	cur += 4
    708 	msg.Mode = OpenMode(buf[cur])
    709 	cur += 1
    710 	if cur != int(size) {
    711 		panic("size and cursor position don't match")
    712 	}
    713 	return msg
    714 }
    715 func (msg *TOpen) Size() uint32    { return 4 + 1 + 2 + 4 + 1 }
    716 func (msg *TOpen) Type() MsgType   { return Topen }
    717 func (msg *TOpen) GetTag() uint16  { return msg.Tag }
    718 func (msg *TOpen) SetTag(t uint16) { msg.Tag = t }
    719 func (msg *TOpen) marshal() []byte {
    720 	cur := 0
    721 	buf := make([]byte, msg.Size())
    722 	pbit32(buf[cur:cur+4], msg.Size())
    723 	cur += 4
    724 	buf[cur] = uint8(Topen)
    725 	cur += 1
    726 	pbit16(buf[cur:cur+2], msg.Tag)
    727 	cur += 2
    728 	pbit32(buf[cur:cur+4], msg.Fid)
    729 	cur += 4
    730 	buf[cur] = uint8(msg.Mode)
    731 	cur += 1
    732 	if cur != len(buf) {
    733 		panic("length of buf and cursor position don't match")
    734 	}
    735 	return buf
    736 }
    737 
    738 func (msg *TOpen) String() string {
    739 	return fmt.Sprintf("Topen Tag %d fid %d mode 0x%x",
    740 		msg.Tag, msg.Fid, msg.Mode)
    741 }
    742 
    743 type ROpen struct {
    744 	Tag    uint16
    745 	Qid    Qid
    746 	Iounit uint32
    747 }
    748 
    749 func newROpen(buf []byte) *ROpen {
    750 	msg := new(ROpen)
    751 	msg.Tag = gbit16(buf[5:7])
    752 	msg.Qid = unmarshalQid(buf[7:20])
    753 	msg.Iounit = gbit32(buf[20:24])
    754 	return msg
    755 }
    756 func (msg *ROpen) Size() uint32 {
    757 	return uint32(4 + 1 + 2 + 13 + 4)
    758 }
    759 func (msg *ROpen) Type() MsgType   { return Ropen }
    760 func (msg *ROpen) GetTag() uint16  { return msg.Tag }
    761 func (msg *ROpen) SetTag(t uint16) { msg.Tag = t }
    762 func (msg *ROpen) marshal() []byte {
    763 	cur := 0
    764 	buf := make([]byte, msg.Size())
    765 	pbit32(buf[cur:cur+4], msg.Size())
    766 	cur += 4
    767 	buf[cur] = uint8(msg.Type())
    768 	cur += 1
    769 	pbit16(buf[cur:cur+2], msg.Tag)
    770 	cur += 2
    771 	for i, bit := range msg.Qid.marshal() {
    772 		buf[cur+i] = bit
    773 	}
    774 	cur += 13
    775 	pbit32(buf[cur:cur+4], msg.Iounit)
    776 	cur += 4
    777 	if cur != len(buf) {
    778 		panic("length of buf and cursor position don't match")
    779 	}
    780 	return buf
    781 }
    782 func (msg *ROpen) String() string {
    783 	return fmt.Sprintf("Ropen Tag %d qid %v iounit %d",
    784 		msg.Tag, msg.Qid, msg.Iounit)
    785 }
    786 
    787 type TCreate struct {
    788 	Tag  uint16
    789 	Fid  uint32
    790 	Name string
    791 	Perm FileMode
    792 	Mode OpenMode
    793 }
    794 
    795 func newTCreate(buf []byte) *TCreate {
    796 	msg := new(TCreate)
    797 	cur := 5
    798 	msg.Tag = gbit16(buf[cur : cur+2])
    799 	cur += 2
    800 	msg.Fid = gbit32(buf[cur : cur+4])
    801 	cur += 4
    802 	nameSize := int(gbit16(buf[cur : cur+2]))
    803 	cur += 2
    804 	msg.Name = string(buf[cur : cur+nameSize])
    805 	cur += nameSize
    806 	msg.Perm = FileMode(gbit32(buf[cur : cur+4]))
    807 	cur += 4
    808 	msg.Mode = OpenMode(buf[cur])
    809 	cur += 1
    810 	if cur != len(buf) {
    811 		panic("length and cursor position don't match")
    812 	}
    813 	return msg
    814 }
    815 
    816 func (msg *TCreate) Size() uint32 {
    817 	return uint32(4 + 1 + 2 + 4 + 2 + len(msg.Name) + 4 + 1)
    818 }
    819 func (msg *TCreate) Type() MsgType   { return Tcreate }
    820 func (msg *TCreate) GetTag() uint16  { return msg.Tag }
    821 func (msg *TCreate) SetTag(t uint16) { msg.Tag = t }
    822 func (msg *TCreate) marshal() []byte {
    823 	cur := 0
    824 	buf := make([]byte, msg.Size())
    825 	pbit32(buf[cur:cur+4], msg.Size())
    826 	cur += 4
    827 	buf[cur] = uint8(msg.Type())
    828 	cur += 1
    829 	pbit16(buf[cur:cur+2], msg.Tag)
    830 	cur += 2
    831 	pbit32(buf[cur:cur+4], msg.Fid)
    832 	cur += 4
    833 	nameSize := len(msg.Name)
    834 	pbit16(buf[cur:cur+2], uint16(nameSize))
    835 	cur += 2
    836 	for i := 0; i < nameSize; i++ {
    837 		buf[cur+i] = msg.Name[i]
    838 	}
    839 	cur += nameSize
    840 	pbit32(buf[cur:cur+4], uint32(msg.Perm))
    841 	cur += 4
    842 	buf[cur] = uint8(msg.Mode)
    843 	cur += 1
    844 	if cur != len(buf) {
    845 		panic("length of buf and cursor position don't match")
    846 	}
    847 	return buf
    848 }
    849 
    850 func (msg *TCreate) String() string {
    851 	return fmt.Sprintf("Tcreate Tag %d fid %d name %s perm %v mode 0x%x",
    852 		msg.Tag, msg.Fid, msg.Name, permString(msg.Perm), msg.Mode)
    853 }
    854 
    855 type RCreate struct {
    856 	Tag    uint16
    857 	Qid    Qid
    858 	Iounit uint32
    859 }
    860 
    861 func newRCreate(buf []byte) *RCreate {
    862 	msg := new(RCreate)
    863 	msg.Tag = gbit16(buf[5:7])
    864 	msg.Qid = unmarshalQid(buf[7:20])
    865 	msg.Iounit = gbit32(buf[20:24])
    866 	return msg
    867 }
    868 func (msg *RCreate) Size() uint32 {
    869 	return uint32(4 + 1 + 2 + 13 + 4)
    870 }
    871 func (msg *RCreate) Type() MsgType   { return Rcreate }
    872 func (msg *RCreate) GetTag() uint16  { return msg.Tag }
    873 func (msg *RCreate) SetTag(t uint16) { msg.Tag = t }
    874 func (msg *RCreate) marshal() []byte {
    875 	cur := 0
    876 	buf := make([]byte, msg.Size())
    877 	pbit32(buf[cur:cur+4], msg.Size())
    878 	cur += 4
    879 	buf[cur] = uint8(msg.Type())
    880 	cur += 1
    881 	pbit16(buf[cur:cur+2], msg.Tag)
    882 	cur += 2
    883 	for i, bit := range msg.Qid.marshal() {
    884 		buf[cur+i] = bit
    885 	}
    886 	cur += 13
    887 	pbit32(buf[cur:cur+4], msg.Iounit)
    888 	cur += 4
    889 	if cur != len(buf) {
    890 		panic("length of buf and cursor position don't match")
    891 	}
    892 	return buf
    893 }
    894 func (msg *RCreate) String() string {
    895 	return fmt.Sprintf("Rcreate Tag %d qid %v iounit %d",
    896 		msg.Tag, msg.Qid, msg.Iounit)
    897 }
    898 
    899 type TRead struct {
    900 	Tag    uint16
    901 	Fid    uint32
    902 	Offset uint64
    903 	Count  uint32
    904 }
    905 
    906 func newTRead(buf []byte) *TRead {
    907 	cur := 0
    908 	msg := new(TRead)
    909 	size := gbit32(buf[cur : cur+4])
    910 	cur += 4
    911 	cur += 1 // type
    912 	msg.Tag = gbit16(buf[cur : cur+2])
    913 	cur += 2
    914 	msg.Fid = gbit32(buf[cur : cur+4])
    915 	cur += 4
    916 	msg.Offset = gbit64(buf[cur : cur+8])
    917 	cur += 8
    918 	msg.Count = gbit32(buf[cur : cur+4])
    919 	cur += 4
    920 	if cur != int(size) {
    921 		panic(fmt.Errorf("size %d != cursor position %d", size, cur))
    922 	}
    923 	return msg
    924 }
    925 func (msg *TRead) Size() uint32    { return 4 + 1 + 2 + 4 + 8 + 4 }
    926 func (msg *TRead) Type() MsgType   { return Tread }
    927 func (msg *TRead) GetTag() uint16  { return msg.Tag }
    928 func (msg *TRead) SetTag(t uint16) { msg.Tag = t }
    929 func (msg *TRead) marshal() []byte {
    930 	cur := 0
    931 	buf := make([]byte, msg.Size())
    932 	pbit32(buf[cur:cur+4], msg.Size())
    933 	cur += 4
    934 	buf[cur] = uint8(msg.Type())
    935 	cur += 1
    936 	pbit16(buf[cur:cur+2], msg.Tag)
    937 	cur += 2
    938 	pbit32(buf[cur:cur+4], msg.Fid)
    939 	cur += 4
    940 	pbit64(buf[cur:cur+8], msg.Offset)
    941 	cur += 8
    942 	pbit32(buf[cur:cur+4], msg.Count)
    943 	cur += 4
    944 	if cur != len(buf) {
    945 		panic("length of buf and cursor position don't match")
    946 	}
    947 	return buf
    948 }
    949 func (msg *TRead) String() string {
    950 	return fmt.Sprintf("Tread Tag %d fid %d offset %d count %d",
    951 		msg.Tag, msg.Fid, msg.Offset, msg.Count)
    952 }
    953 
    954 type RRead struct {
    955 	Tag   uint16
    956 	Count uint32
    957 	Data  []byte
    958 }
    959 
    960 func newRRead(buf []byte) *RRead {
    961 	msg := new(RRead)
    962 	msg.Tag = gbit16(buf[5:7])
    963 	msg.Count = gbit32(buf[7:11])
    964 	msg.Data = make([]byte, msg.Count)
    965 	for i := 0; i < int(msg.Count); i++ {
    966 		msg.Data[i] = buf[11+i]
    967 	}
    968 	return msg
    969 }
    970 func (msg *RRead) Size() uint32 {
    971 	return uint32(4 + 1 + 2 + 4 + msg.Count)
    972 }
    973 func (msg *RRead) Type() MsgType   { return Rread }
    974 func (msg *RRead) GetTag() uint16  { return msg.Tag }
    975 func (msg *RRead) SetTag(t uint16) { msg.Tag = t }
    976 func (msg *RRead) marshal() []byte {
    977 	if uint32(len(msg.Data)) != msg.Count {
    978 		panic(fmt.Errorf("data size %d and count %d don't match",
    979 			len(msg.Data), msg.Count))
    980 	}
    981 	cur := 0
    982 	buf := make([]byte, msg.Size())
    983 	pbit32(buf[cur:cur+4], msg.Size())
    984 	cur += 4
    985 	buf[cur] = uint8(msg.Type())
    986 	cur += 1
    987 	pbit16(buf[cur:cur+2], msg.Tag)
    988 	cur += 2
    989 	pbit32(buf[cur:cur+4], msg.Count)
    990 	cur += 4
    991 	for i := 0; i < len(msg.Data); i++ {
    992 		buf[cur+i] = msg.Data[i]
    993 	}
    994 	cur += len(msg.Data)
    995 	if cur != len(buf) {
    996 		panic("length of buf and cursor position don't match")
    997 	}
    998 	return buf
    999 }
   1000 func (msg *RRead) String() string {
   1001 	s := fmt.Sprintf("Rread Tag %d count %d '",
   1002 		msg.Tag, msg.Count)
   1003 	i := 0
   1004 	for ; i+4 < len(msg.Data) && i < 64; i += 4 {
   1005 		s += fmt.Sprintf(" %02x%02x%02x%02x",
   1006 			uint8(msg.Data[i]), uint8(msg.Data[i+1]),
   1007 			uint8(msg.Data[i+2]), uint8(msg.Data[i+3]))
   1008 	}
   1009 	if i != len(msg.Data) && i != 64 {
   1010 		s += " "
   1011 	}
   1012 	for ; i < len(msg.Data) && i < 64; i++ {
   1013 		s += fmt.Sprintf("%02x", uint8(msg.Data[i]))
   1014 	}
   1015 	s += "'"
   1016 	return s
   1017 }
   1018 
   1019 type TWrite struct {
   1020 	Tag    uint16
   1021 	Fid    uint32
   1022 	Offset uint64
   1023 	Count  uint32
   1024 	Data   []byte
   1025 }
   1026 
   1027 func newTWrite(buf []byte) *TWrite {
   1028 	cur := 5
   1029 	msg := new(TWrite)
   1030 	msg.Tag = gbit16(buf[cur : cur+2])
   1031 	cur += 2
   1032 	msg.Fid = gbit32(buf[cur : cur+4])
   1033 	cur += 4
   1034 	msg.Offset = gbit64(buf[cur : cur+8])
   1035 	cur += 8
   1036 	msg.Count = gbit32(buf[cur : cur+4])
   1037 	cur += 4
   1038 	msg.Data = make([]byte, msg.Count)
   1039 	for i := 0; i < int(msg.Count); i++ {
   1040 		msg.Data[i] = buf[cur+i]
   1041 	}
   1042 	cur += int(msg.Count)
   1043 	if cur != len(buf) {
   1044 		panic("length of buf and cursor position don't match")
   1045 	}
   1046 	return msg
   1047 }
   1048 func (msg *TWrite) Size() uint32 {
   1049 	return uint32(4 + 1 + 2 + 4 + 8 + 4 + len(msg.Data))
   1050 }
   1051 func (msg *TWrite) Type() MsgType   { return Twrite }
   1052 func (msg *TWrite) GetTag() uint16  { return msg.Tag }
   1053 func (msg *TWrite) SetTag(t uint16) { msg.Tag = t }
   1054 func (msg *TWrite) marshal() []byte {
   1055 	cur := 0
   1056 	buf := make([]byte, msg.Size())
   1057 	pbit32(buf[cur:cur+4], msg.Size())
   1058 	cur += 4
   1059 	buf[cur] = uint8(msg.Type())
   1060 	cur += 1
   1061 	pbit16(buf[cur:cur+2], msg.Tag)
   1062 	cur += 2
   1063 	pbit32(buf[cur:cur+4], msg.Fid)
   1064 	cur += 4
   1065 	pbit64(buf[cur:cur+8], msg.Offset)
   1066 	cur += 8
   1067 	pbit32(buf[cur:cur+4], msg.Count)
   1068 	cur += 4
   1069 	for i := 0; i < int(msg.Count); i++ {
   1070 		buf[cur+i] = msg.Data[i]
   1071 	}
   1072 	cur += int(msg.Count)
   1073 	if cur != len(buf) {
   1074 		panic("length of buf and cursor position don't match")
   1075 	}
   1076 	return buf
   1077 }
   1078 func (msg *TWrite) String() string {
   1079 	return fmt.Sprintf("Twrite Tag %d fid %d offset %d count %d '%s'",
   1080 		msg.Tag, msg.Fid, msg.Offset, msg.Count, msg.Data)
   1081 }
   1082 
   1083 type RWrite struct {
   1084 	Tag   uint16
   1085 	Count uint32
   1086 }
   1087 
   1088 func newRWrite(buf []byte) *RWrite {
   1089 	msg := new(RWrite)
   1090 	msg.Tag = gbit16(buf[5:7])
   1091 	msg.Count = gbit32(buf[7:11])
   1092 	return msg
   1093 }
   1094 func (msg *RWrite) Size() uint32 {
   1095 	return uint32(4 + 1 + 2 + 4)
   1096 }
   1097 func (msg *RWrite) Type() MsgType   { return Rwrite }
   1098 func (msg *RWrite) GetTag() uint16  { return msg.Tag }
   1099 func (msg *RWrite) SetTag(t uint16) { msg.Tag = t }
   1100 func (msg *RWrite) marshal() []byte {
   1101 	cur := 0
   1102 	buf := make([]byte, msg.Size())
   1103 	pbit32(buf[cur:cur+4], msg.Size())
   1104 	cur += 4
   1105 	buf[cur] = uint8(msg.Type())
   1106 	cur += 1
   1107 	pbit16(buf[cur:cur+2], msg.Tag)
   1108 	cur += 2
   1109 	pbit32(buf[cur:cur+4], msg.Count)
   1110 	cur += 4
   1111 	if cur != len(buf) {
   1112 		panic("length of buf and cursor position don't match")
   1113 	}
   1114 	return buf
   1115 }
   1116 
   1117 func (msg *RWrite) String() string {
   1118 	return fmt.Sprintf("Rwrite Tag %d count %d", msg.Tag, msg.Count)
   1119 }
   1120 
   1121 type TClunk struct {
   1122 	Tag uint16
   1123 	Fid uint32
   1124 }
   1125 
   1126 func newTClunk(buf []byte) *TClunk {
   1127 	msg := new(TClunk)
   1128 	msg.Tag = gbit16(buf[5:7])
   1129 	msg.Fid = gbit32(buf[7:11])
   1130 	return msg
   1131 }
   1132 
   1133 func (msg *TClunk) Size() uint32    { return 4 + 1 + 2 + 4 }
   1134 func (msg *TClunk) Type() MsgType   { return Tclunk }
   1135 func (msg *TClunk) GetTag() uint16  { return msg.Tag }
   1136 func (msg *TClunk) SetTag(t uint16) { msg.Tag = t }
   1137 func (msg *TClunk) marshal() []byte {
   1138 	m := make([]byte, msg.Size())
   1139 	pbit32(m[0:4], msg.Size())
   1140 	m[4] = uint8(Tclunk)
   1141 	pbit16(m[5:7], msg.Tag)
   1142 	pbit32(m[7:11], msg.Fid)
   1143 	return m
   1144 }
   1145 func (msg *TClunk) String() string {
   1146 	return fmt.Sprintf("Tclunk Tag %d fid %d",
   1147 		msg.Tag, msg.Fid)
   1148 }
   1149 
   1150 type RClunk struct {
   1151 	Tag uint16
   1152 }
   1153 
   1154 func newRClunk(buf []byte) *RClunk {
   1155 	msg := new(RClunk)
   1156 	msg.Tag = gbit16(buf[5:7])
   1157 	return msg
   1158 }
   1159 func (msg *RClunk) Size() uint32    { return 7 }
   1160 func (msg *RClunk) Type() MsgType   { return Rclunk }
   1161 func (msg *RClunk) GetTag() uint16  { return msg.Tag }
   1162 func (msg *RClunk) SetTag(t uint16) { msg.Tag = t }
   1163 func (msg *RClunk) marshal() []byte {
   1164 	m := make([]byte, msg.Size())
   1165 	pbit32(m[0:4], msg.Size())
   1166 	m[4] = uint8(Rclunk)
   1167 	pbit16(m[5:7], msg.Tag)
   1168 	return m
   1169 }
   1170 func (msg *RClunk) String() string {
   1171 	return fmt.Sprintf("Rclunk Tag %d", msg.Tag)
   1172 }
   1173 
   1174 type TRemove struct {
   1175 	Tag uint16
   1176 	Fid uint32
   1177 }
   1178 
   1179 func newTRemove(buf []byte) *TRemove {
   1180 	msg := new(TRemove)
   1181 	msg.Tag = gbit16(buf[5:7])
   1182 	msg.Fid = gbit32(buf[7:11])
   1183 	return msg
   1184 }
   1185 
   1186 func (msg *TRemove) Size() uint32    { return 4 + 1 + 2 + 4 }
   1187 func (msg *TRemove) Type() MsgType   { return Tremove }
   1188 func (msg *TRemove) GetTag() uint16  { return msg.Tag }
   1189 func (msg *TRemove) SetTag(t uint16) { msg.Tag = t }
   1190 func (msg *TRemove) marshal() []byte {
   1191 	m := make([]byte, msg.Size())
   1192 	pbit32(m[0:4], msg.Size())
   1193 	m[4] = uint8(msg.Type())
   1194 	pbit16(m[5:7], msg.Tag)
   1195 	pbit32(m[7:11], msg.Fid)
   1196 	return m
   1197 }
   1198 func (msg *TRemove) String() string {
   1199 	return fmt.Sprintf("Tremove Tag %d fid %d", msg.Tag, msg.Fid)
   1200 }
   1201 
   1202 type RRemove struct {
   1203 	Tag uint16
   1204 }
   1205 
   1206 func newRRemove(buf []byte) *RRemove {
   1207 	msg := new(RRemove)
   1208 	msg.Tag = gbit16(buf[5:7])
   1209 	return msg
   1210 }
   1211 func (msg *RRemove) Size() uint32    { return 4 + 1 + 2 }
   1212 func (msg *RRemove) Type() MsgType   { return Rremove }
   1213 func (msg *RRemove) GetTag() uint16  { return msg.Tag }
   1214 func (msg *RRemove) SetTag(t uint16) { msg.Tag = t }
   1215 func (msg *RRemove) marshal() []byte {
   1216 	m := make([]byte, msg.Size())
   1217 	pbit32(m[0:4], msg.Size())
   1218 	m[4] = uint8(msg.Type())
   1219 	pbit16(m[5:7], msg.Tag)
   1220 	return m
   1221 }
   1222 func (msg *RRemove) String() string {
   1223 	return fmt.Sprintf("Rremove Tag %d", msg.Tag)
   1224 }
   1225 
   1226 type TStat struct {
   1227 	Tag uint16
   1228 	Fid uint32
   1229 }
   1230 
   1231 func newTStat(buf []byte) *TStat {
   1232 	msg := new(TStat)
   1233 	msg.Tag = gbit16(buf[5:7])
   1234 	msg.Fid = gbit32(buf[7:11])
   1235 	return msg
   1236 }
   1237 func (msg *TStat) Size() uint32    { return 4 + 1 + 2 + 4 }
   1238 func (msg *TStat) Type() MsgType   { return Tstat }
   1239 func (msg *TStat) GetTag() uint16  { return msg.Tag }
   1240 func (msg *TStat) SetTag(t uint16) { msg.Tag = t }
   1241 func (msg *TStat) marshal() []byte {
   1242 	m := make([]byte, msg.Size())
   1243 	pbit32(m[0:4], msg.Size())
   1244 	m[4] = uint8(Tstat)
   1245 	pbit16(m[5:7], msg.Tag)
   1246 	pbit32(m[7:11], msg.Fid)
   1247 	return m
   1248 }
   1249 func (msg *TStat) String() string {
   1250 	return fmt.Sprintf("Tstat Tag %d fid %d",
   1251 		msg.Tag, msg.Fid)
   1252 }
   1253 
   1254 type RStat struct {
   1255 	Tag  uint16
   1256 	Stat *Stat
   1257 }
   1258 
   1259 func newRStat(buf []byte) *RStat {
   1260 	msg := new(RStat)
   1261 	size := gbit32(buf[:4])
   1262 	msg.Tag = gbit16(buf[5:7])
   1263 	msg.Stat = NewStat(buf[9:size])
   1264 	return msg
   1265 }
   1266 func (msg *RStat) Size() uint32 {
   1267 	return uint32(4 + 1 + 2 + 2 + 2 + msg.Stat.Size())
   1268 }
   1269 func (msg *RStat) Type() MsgType   { return Rstat }
   1270 func (msg *RStat) GetTag() uint16  { return msg.Tag }
   1271 func (msg *RStat) SetTag(t uint16) { msg.Tag = t }
   1272 func (msg *RStat) marshal() []byte {
   1273 	buf := make([]byte, msg.Size())
   1274 	pbit32(buf[0:4], msg.Size())
   1275 	buf[4] = uint8(Rstat)
   1276 	pbit16(buf[5:7], msg.Tag)
   1277 	fiBuf := msg.Stat.marshal()
   1278 	pbit16(buf[7:9], uint16(len(fiBuf)))
   1279 	for i := 0; i < len(fiBuf); i++ {
   1280 		buf[9+i] = fiBuf[i]
   1281 	}
   1282 	return buf
   1283 }
   1284 
   1285 func (msg *RStat) String() string {
   1286 	return fmt.Sprintf("Rstat Tag %d stat %s", msg.Tag, msg.Stat)
   1287 }
   1288 
   1289 type TWstat struct {
   1290 	Tag  uint16
   1291 	Fid  uint32
   1292 	Stat *Stat
   1293 }
   1294 
   1295 func newTWstat(buf []byte) *TWstat {
   1296 	msg := new(TWstat)
   1297 	msg.Tag = gbit16(buf[5:7])
   1298 	msg.Fid = gbit32(buf[7:11])
   1299 	msg.Stat = NewStat(buf[13:])
   1300 	return msg
   1301 }
   1302 func (msg *TWstat) Size() uint32 {
   1303 	return uint32(4 + 1 + 2 + 4 + 2 + 2 + msg.Stat.Size())
   1304 }
   1305 func (msg *TWstat) Type() MsgType   { return Twstat }
   1306 func (msg *TWstat) GetTag() uint16  { return msg.Tag }
   1307 func (msg *TWstat) SetTag(t uint16) { msg.Tag = t }
   1308 func (msg *TWstat) marshal() []byte {
   1309 	buf := make([]byte, msg.Size())
   1310 	pbit32(buf[0:4], msg.Size())
   1311 	buf[4] = uint8(msg.Type())
   1312 	pbit16(buf[5:7], msg.Tag)
   1313 	pbit32(buf[7:11], msg.Fid)
   1314 	fiBuf := msg.Stat.marshal()
   1315 	pbit16(buf[11:13], uint16(len(fiBuf)))
   1316 	for i := 0; i < len(fiBuf); i++ {
   1317 		buf[13+i] = fiBuf[i]
   1318 	}
   1319 	return buf
   1320 }
   1321 
   1322 func (msg *TWstat) String() string {
   1323 	return fmt.Sprintf("Twstat Tag %d fid %d stat %s", msg.Tag, msg.Fid, msg.Stat)
   1324 }
   1325 
   1326 type RWstat struct {
   1327 	Tag uint16
   1328 }
   1329 
   1330 func newRWstat(buf []byte) *RWstat {
   1331 	msg := new(RWstat)
   1332 	msg.Tag = gbit16(buf[5:7])
   1333 	return msg
   1334 }
   1335 func (msg *RWstat) Size() uint32    { return 4 + 1 + 2 }
   1336 func (msg *RWstat) Type() MsgType   { return Rwstat }
   1337 func (msg *RWstat) GetTag() uint16  { return msg.Tag }
   1338 func (msg *RWstat) SetTag(t uint16) { msg.Tag = t }
   1339 func (msg *RWstat) marshal() []byte {
   1340 	m := make([]byte, msg.Size())
   1341 	pbit32(m[0:4], msg.Size())
   1342 	m[4] = uint8(msg.Type())
   1343 	pbit16(m[5:7], msg.Tag)
   1344 	return m
   1345 }
   1346 func (msg *RWstat) String() string {
   1347 	return fmt.Sprintf("Rwstat Tag %d", msg.Tag)
   1348 }