func (c *ClientConn) attach(fc *plan9.Fcall) *plan9.Fcall { fc.Type = plan9.Rattach fc.Iounit = c.iounit fref, _ := c.createFileRef(c.explorer.Root(), FTDIR, 0) fc.Qid = fref.Qid c.bindFid(fc.Fid, fc.Qid.Path) return fc }
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 }
func (c *ClientConn) read(fc *plan9.Fcall) *plan9.Fcall { fc.Type = plan9.Rread if fref, has := c.fidRef(fc.Fid); has { if fref.IsDir() { return c.readdir(fc, fref) } return c.readfile(fc, fref) } return c.invalidFidErr(fc) }
func (c *ClientConn) clunk(fc *plan9.Fcall) *plan9.Fcall { fc.Type = plan9.Rclunk oldpath, had := c.unbindFid(fc.Fid) if had { err := c.explorer.Close(oldpath) if err != nil { return c.unexpectedErr(fc, err) } } return fc }
func (c *ClientConn) write(fc *plan9.Fcall) *plan9.Fcall { fc.Type = plan9.Rwrite if fref, have := c.fidRef(fc.Fid); have { n, err := c.explorer.Write(fref.Path, fc.Data, fc.Offset) if err != nil { return c.unexpectedErr(fc, err) } fc.Count = uint32(n) return fc } return c.invalidFidErr(fc) }
func (c *ClientConn) open(fc *plan9.Fcall) *plan9.Fcall { fc.Type = plan9.Ropen if fref, has := c.fidRef(fc.Fid); has { err := c.explorer.Open(fref.Path, FileMode(fc.Mode)) if err != nil { return c.unexpectedErr(fc, err) } fc.Iounit = c.iounit fc.Qid = fref.Qid return fc } return c.invalidFidErr(fc) }
func (c *ClientConn) create(fc *plan9.Fcall) *plan9.Fcall { fc.Type = plan9.Rcreate if fref, have := c.fidRef(fc.Fid); have { file := File{Name: fc.Name} file.Type = FileType(fc.Mode) path, err := c.explorer.Create(fref.Path, file, uint32(fc.Perm)) if err != nil { return c.unexpectedErr(fc, err) } cref, err := c.createFileRef(path, file.Type, 0) if err != nil { return c.unexpectedErr(fc, err) } fc.Iounit = c.iounit fc.Qid = cref.Qid c.unbindFid(fc.Fid) c.bindFid(fc.Fid, cref.Path) return fc } return c.invalidFidErr(fc) }
func (c *ClientConn) unexpectedErr(fc *plan9.Fcall, err error) *plan9.Fcall { fc.Type = plan9.Rerror fc.Ename = err.Error() return fc }
func (c *ClientConn) fidUsedErr(fc *plan9.Fcall) *plan9.Fcall { fc.Type = plan9.Rerror fc.Ename = "fid in use" return fc }
func (c *ClientConn) fileNotFoundErr(fc *plan9.Fcall) *plan9.Fcall { fc.Type = plan9.Rerror fc.Ename = "file not found" return fc }
func (c *ClientConn) invalidFidErr(fc *plan9.Fcall) *plan9.Fcall { fc.Type = plan9.Rerror fc.Ename = "fid not found" return fc }
func (c *ClientConn) version(fc *plan9.Fcall) *plan9.Fcall { fc.Type = plan9.Rversion fc.Version = "9P2000" return fc }
func noauth(fc *plan9.Fcall) *plan9.Fcall { fc.Type = plan9.Rerror fc.Ename = "no auth requried" return fc }