Example #1
0
// Starting from the file associated with fid, walks all wnames in
// sequence and associates the resulting file with newfid. If no wnames
// were walked successfully, an Error is returned. Otherwise a slice with a
// Qid for each walked name is returned.
func (clnt *Client) Walk(fid *Fid, newfid *Fid, wnames []string) ([]g9p.Qid, error) {
	tc := clnt.newFcall()
	err := g9p.PackTwalk(tc, fid.Fid, newfid.Fid, wnames)
	if err != nil {
		return nil, err
	}

	rc, err := clnt.rpc(tc)
	if err != nil {
		return nil, err
	}

	newfid.walked = true
	return rc.Wqid, nil
}
Example #2
0
// Walks to a named file. Returns a Fid associated with the file,
// or an Error.
func (clnt *Client) FWalk(path string) (*Fid, error) {
	var err error = nil

	var i, m int
	for i = 0; i < len(path); i++ {
		if path[i] != '/' {
			break
		}
	}

	if i > 0 {
		path = path[i:len(path)]
	}

	wnames := strings.Split(path, "/")
	newfid := clnt.fidAlloc()
	fid := clnt.root
	newfid.User = fid.User

	/* get rid of the empty names */
	for i, m = 0, 0; i < len(wnames); i++ {
		if wnames[i] != "" {
			wnames[m] = wnames[i]
			m++
		}
	}

	wnames = wnames[0:m]
	for {
		n := len(wnames)
		if n > 16 {
			n = 16
		}

		tc := clnt.newFcall()
		err = g9p.PackTwalk(tc, fid.Fid, newfid.Fid, wnames[0:n])
		if err != nil {
			goto error
		}

		var rc *g9p.Fcall
		rc, err = clnt.rpc(tc)
		if err != nil {
			goto error
		}
		if rc.Type == g9p.Rerror {
			err = &g9p.Error{rc.Error, int(rc.Errornum)}
			goto error
		}

		newfid.walked = true
		if len(rc.Wqid) != n {
			err = &g9p.Error{"file not found", syscall.ENOENT}
			goto error
		}

		if len(rc.Wqid) > 0 {
			newfid.Qid = rc.Wqid[len(rc.Wqid)-1]
		} else {
			newfid.Qid = fid.Qid
		}

		wnames = wnames[n:len(wnames)]
		fid = newfid
		if len(wnames) == 0 {
			break
		}
	}

	return newfid, nil

error:
	clnt.Clunk(newfid)
	return nil, err
}