104 lines
		
	
	
		
			1.9 KiB
		
	
	
	
		
			Go
		
	
	
			
		
		
	
	
			104 lines
		
	
	
		
			1.9 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 (
 | 
						|
	"strings"
 | 
						|
)
 | 
						|
 | 
						|
// 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 *Clnt) Walk(fid *Fid, newfid *Fid, wnames []string) ([]Qid, error) {
 | 
						|
	tc := clnt.NewFcall()
 | 
						|
	err := 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
 | 
						|
}
 | 
						|
 | 
						|
// Walks to a named file. Returns a Fid associated with the file,
 | 
						|
// or an Error.
 | 
						|
func (clnt *Clnt) 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:]
 | 
						|
	}
 | 
						|
 | 
						|
	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 = PackTwalk(tc, fid.Fid, newfid.Fid, wnames[0:n])
 | 
						|
		if err != nil {
 | 
						|
			goto error
 | 
						|
		}
 | 
						|
 | 
						|
		var rc *Fcall
 | 
						|
		rc, err = clnt.Rpc(tc)
 | 
						|
		if err != nil {
 | 
						|
			goto error
 | 
						|
		}
 | 
						|
 | 
						|
		newfid.walked = true
 | 
						|
		if len(rc.Wqid) != n {
 | 
						|
			err = &Error{"file not found", ENOENT}
 | 
						|
			goto error
 | 
						|
		}
 | 
						|
 | 
						|
		if len(rc.Wqid) > 0 {
 | 
						|
			newfid.Qid = rc.Wqid[len(rc.Wqid)-1]
 | 
						|
		} else {
 | 
						|
			newfid.Qid = fid.Qid
 | 
						|
		}
 | 
						|
 | 
						|
		wnames = wnames[n:]
 | 
						|
		fid = newfid
 | 
						|
		if len(wnames) == 0 {
 | 
						|
			break
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	return newfid, nil
 | 
						|
 | 
						|
error:
 | 
						|
	clnt.Clunk(newfid)
 | 
						|
	return nil, err
 | 
						|
}
 |