-
Notifications
You must be signed in to change notification settings - Fork 22
/
clnt_walk.go
103 lines (85 loc) · 1.87 KB
/
clnt_walk.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
// 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
}