func (c *ClientConn) walk(fc *plan9.Fcall) *plan9.Fcall { fc.Type = plan9.Rwalk fref, has := c.fidRef(fc.Fid) if !has { return c.invalidFidErr(fc) } if _, has := c.fidRef(fc.Newfid); has { return c.fidUsedErr(fc) } current := fref.Path for idx, name := range fc.Wname { var ft FileType if current == 0 { return c.fileNotFoundErr(fc) } if ff, ok := c.explorer.(FileFinder); ok { f, err := ff.FindInDir(current, name) if err != nil { return c.unexpectedErr(fc, err) } current = f.Path } else { childs, err := c.explorer.ListDir(current) if err != nil { return c.unexpectedErr(fc, err) } idx, have := childs.FindExact(name) if !have { return c.fileNotFoundErr(fc) } current = childs[idx].Path } ref, err := c.createFileRef(current, ft, 0) if err != nil { return c.unexpectedErr(fc, err) } fc.Wqid = append(fc.Wqid, ref.Qid) // if the last match isn't a directory, there is no need to find // another part of the path // // so, just break here if ft == FTFILE && idx != len(fc.Wname)-1 { return c.fileNotFoundErr(fc) } } if len(fc.Wqid) == 0 { // newfid and fid will map to the same file if fc.Newfid != fc.Fid { c.bindFid(fc.Newfid, fref.Path) } } else { // make a bind between the last qid and the new fid c.bindFid(fc.Newfid, fc.Wqid[len(fc.Wqid)-1].Path) } return fc }