230 lines
		
	
	
		
			5.1 KiB
		
	
	
	
		
			Go
		
	
	
			
		
		
	
	
			230 lines
		
	
	
		
			5.1 KiB
		
	
	
	
		
			Go
		
	
	
// Copyright 2009 The Go9p Authors.  All rights reserved.
 | 
						|
// Use of this source code is governed by a BSD-style
 | 
						|
// license that can be found in the LICENSE file.
 | 
						|
 | 
						|
package go9p
 | 
						|
 | 
						|
import "fmt"
 | 
						|
 | 
						|
// Create a Rversion message in the specified Fcall.
 | 
						|
func PackRversion(fc *Fcall, msize uint32, version string) error {
 | 
						|
	size := 4 + 2 + len(version) /* msize[4] version[s] */
 | 
						|
	p, err := packCommon(fc, size, Rversion)
 | 
						|
	if err != nil {
 | 
						|
		return err
 | 
						|
	}
 | 
						|
 | 
						|
	fc.Msize = msize
 | 
						|
	fc.Version = version
 | 
						|
	p = pint32(msize, p)
 | 
						|
	p = pstr(version, p)
 | 
						|
 | 
						|
	return nil
 | 
						|
}
 | 
						|
 | 
						|
// Create a Rauth message in the specified Fcall.
 | 
						|
func PackRauth(fc *Fcall, aqid *Qid) error {
 | 
						|
	size := 13 /* aqid[13] */
 | 
						|
	p, err := packCommon(fc, size, Rauth)
 | 
						|
	if err != nil {
 | 
						|
		return err
 | 
						|
	}
 | 
						|
 | 
						|
	fc.Qid = *aqid
 | 
						|
	p = pqid(aqid, p)
 | 
						|
	return nil
 | 
						|
}
 | 
						|
 | 
						|
// Create a Rerror message in the specified Fcall. If dotu is true,
 | 
						|
// the function will create a 9P2000.u message. If false, errornum is
 | 
						|
// ignored.
 | 
						|
// The Akaros global is hurl-inducing but this whole blob of code
 | 
						|
// needs a redo. dotu is even worse, since it bakes in ONE PARTICULAR
 | 
						|
// EXTENSION ...
 | 
						|
 | 
						|
func PackRerror(fc *Fcall, error string, errornum uint32, dotu bool) error {
 | 
						|
	if *Akaros {
 | 
						|
		error = fmt.Sprintf("%04X %v", errornum, error)
 | 
						|
	}
 | 
						|
 | 
						|
	size := 2 + len(error) /* ename[s] */
 | 
						|
	if dotu {
 | 
						|
		size += 4 /* ecode[4] */
 | 
						|
	}
 | 
						|
 | 
						|
	p, err := packCommon(fc, size, Rerror)
 | 
						|
	if err != nil {
 | 
						|
		return err
 | 
						|
	}
 | 
						|
 | 
						|
	fc.Error = error
 | 
						|
	p = pstr(error, p)
 | 
						|
	if dotu {
 | 
						|
		fc.Errornum = errornum
 | 
						|
		p = pint32(errornum, p)
 | 
						|
	}
 | 
						|
 | 
						|
	return nil
 | 
						|
}
 | 
						|
 | 
						|
// Create a Rflush message in the specified Fcall.
 | 
						|
func PackRflush(fc *Fcall) error {
 | 
						|
	_, err := packCommon(fc, 0, Rflush)
 | 
						|
 | 
						|
	return err
 | 
						|
}
 | 
						|
 | 
						|
// Create a Rattach message in the specified Fcall.
 | 
						|
func PackRattach(fc *Fcall, aqid *Qid) error {
 | 
						|
	size := 13 /* aqid[13] */
 | 
						|
	p, err := packCommon(fc, size, Rattach)
 | 
						|
	if err != nil {
 | 
						|
		return err
 | 
						|
	}
 | 
						|
 | 
						|
	fc.Qid = *aqid
 | 
						|
	p = pqid(aqid, p)
 | 
						|
	return nil
 | 
						|
}
 | 
						|
 | 
						|
// Create a Rwalk message in the specified Fcall.
 | 
						|
func PackRwalk(fc *Fcall, wqids []Qid) error {
 | 
						|
	nwqid := len(wqids)
 | 
						|
	size := 2 + nwqid*13 /* nwqid[2] nwname*wqid[13] */
 | 
						|
	p, err := packCommon(fc, size, Rwalk)
 | 
						|
	if err != nil {
 | 
						|
		return err
 | 
						|
	}
 | 
						|
 | 
						|
	p = pint16(uint16(nwqid), p)
 | 
						|
	fc.Wqid = make([]Qid, nwqid)
 | 
						|
	for i := 0; i < nwqid; i++ {
 | 
						|
		fc.Wqid[i] = wqids[i]
 | 
						|
		p = pqid(&wqids[i], p)
 | 
						|
	}
 | 
						|
 | 
						|
	return nil
 | 
						|
}
 | 
						|
 | 
						|
// Create a Ropen message in the specified Fcall.
 | 
						|
func PackRopen(fc *Fcall, qid *Qid, iounit uint32) error {
 | 
						|
	size := 13 + 4 /* qid[13] iounit[4] */
 | 
						|
	p, err := packCommon(fc, size, Ropen)
 | 
						|
	if err != nil {
 | 
						|
		return err
 | 
						|
	}
 | 
						|
 | 
						|
	fc.Qid = *qid
 | 
						|
	fc.Iounit = iounit
 | 
						|
	p = pqid(qid, p)
 | 
						|
	p = pint32(iounit, p)
 | 
						|
	return nil
 | 
						|
}
 | 
						|
 | 
						|
// Create a Rcreate message in the specified Fcall.
 | 
						|
func PackRcreate(fc *Fcall, qid *Qid, iounit uint32) error {
 | 
						|
	size := 13 + 4 /* qid[13] iounit[4] */
 | 
						|
	p, err := packCommon(fc, size, Rcreate)
 | 
						|
	if err != nil {
 | 
						|
		return err
 | 
						|
	}
 | 
						|
 | 
						|
	fc.Qid = *qid
 | 
						|
	fc.Iounit = iounit
 | 
						|
	p = pqid(qid, p)
 | 
						|
	p = pint32(iounit, p)
 | 
						|
	return nil
 | 
						|
}
 | 
						|
 | 
						|
// Initializes the specified Fcall value to contain Rread message.
 | 
						|
// The user should copy the returned data to the slice pointed by
 | 
						|
// fc.Data and call SetRreadCount to update the data size to the
 | 
						|
// actual value.
 | 
						|
func InitRread(fc *Fcall, count uint32) error {
 | 
						|
	size := int(4 + count) /* count[4] data[count] */
 | 
						|
	p, err := packCommon(fc, size, Rread)
 | 
						|
	if err != nil {
 | 
						|
		return err
 | 
						|
	}
 | 
						|
 | 
						|
	fc.Count = count
 | 
						|
	fc.Data = p[4 : fc.Count+4]
 | 
						|
	p = pint32(count, p)
 | 
						|
	return nil
 | 
						|
}
 | 
						|
 | 
						|
// Updates the size of the data returned by Rread. Expects that
 | 
						|
// the Fcall value is already initialized by InitRread.
 | 
						|
func SetRreadCount(fc *Fcall, count uint32) {
 | 
						|
	/* we need to update both the packet size as well as the data count */
 | 
						|
	size := 4 + 1 + 2 + 4 + count /* size[4] id[1] tag[2] count[4] data[count] */
 | 
						|
	pint32(size, fc.Pkt)
 | 
						|
	pint32(count, fc.Pkt[7:])
 | 
						|
	fc.Size = size
 | 
						|
	fc.Count = count
 | 
						|
	fc.Pkt = fc.Pkt[0:size]
 | 
						|
	fc.Data = fc.Data[0:count]
 | 
						|
	fc.Size = size
 | 
						|
}
 | 
						|
 | 
						|
// Create a Rread message in the specified Fcall.
 | 
						|
func PackRread(fc *Fcall, data []byte) error {
 | 
						|
	count := uint32(len(data))
 | 
						|
	err := InitRread(fc, count)
 | 
						|
	if err != nil {
 | 
						|
		return err
 | 
						|
	}
 | 
						|
 | 
						|
	copy(fc.Data, data)
 | 
						|
	return nil
 | 
						|
}
 | 
						|
 | 
						|
// Create a Rwrite message in the specified Fcall.
 | 
						|
func PackRwrite(fc *Fcall, count uint32) error {
 | 
						|
	p, err := packCommon(fc, 4, Rwrite) /* count[4] */
 | 
						|
	if err != nil {
 | 
						|
		return err
 | 
						|
	}
 | 
						|
 | 
						|
	fc.Count = count
 | 
						|
 | 
						|
	p = pint32(count, p)
 | 
						|
	return nil
 | 
						|
}
 | 
						|
 | 
						|
// Create a Rclunk message in the specified Fcall.
 | 
						|
func PackRclunk(fc *Fcall) error {
 | 
						|
	_, err := packCommon(fc, 0, Rclunk)
 | 
						|
	return err
 | 
						|
}
 | 
						|
 | 
						|
// Create a Rremove message in the specified Fcall.
 | 
						|
func PackRremove(fc *Fcall) error {
 | 
						|
	_, err := packCommon(fc, 0, Rremove)
 | 
						|
	return err
 | 
						|
}
 | 
						|
 | 
						|
// Create a Rstat message in the specified Fcall. If dotu is true, the
 | 
						|
// function will create a 9P2000.u stat representation that includes
 | 
						|
// st.Nuid, st.Ngid, st.Nmuid and st.Ext. Otherwise these values will be
 | 
						|
// ignored.
 | 
						|
func PackRstat(fc *Fcall, d *Dir, dotu bool) error {
 | 
						|
	stsz := statsz(d, dotu)
 | 
						|
	size := 2 + stsz /* stat[n] */
 | 
						|
	p, err := packCommon(fc, size, Rstat)
 | 
						|
	if err != nil {
 | 
						|
		return err
 | 
						|
	}
 | 
						|
 | 
						|
	p = pint16(uint16(stsz), p)
 | 
						|
	p = pstat(d, p, dotu)
 | 
						|
	fc.Dir = *d
 | 
						|
	return nil
 | 
						|
}
 | 
						|
 | 
						|
// Create a Rwstat message in the specified Fcall.
 | 
						|
func PackRwstat(fc *Fcall) error {
 | 
						|
	_, err := packCommon(fc, 0, Rwstat)
 | 
						|
	return err
 | 
						|
}
 |