func (t *Fs) get(rid string, off, count int64, dc chan<- []byte, cs *zx.CallStat) error { rid, err := zx.AbsPath(rid) if err != nil { return err } if rid == "/Ctl" { return t.getCtl(off, count, dc, cs) } f, _, err := t.walk(rid, nil) if err == nil && !t.NoPermCheck { f.mlk.Lock() if !f.d.CanRead(t.ai) { err = dbg.ErrPerm } f.mlk.Unlock() } if err != nil { return err } f.mlk.Lock() if f.d["type"] == "d" { f.mlk.Unlock() return f.getDir(off, count, dc, cs) } f.mlk.Unlock() cs.Sending() n, nm, err := f.data.SendTo(off, count, dc) cs.Sends(int64(nm), n) return err }
func (t *Lfs) get(rid string, off, count int64, dc chan<- []byte, cs *zx.CallStat) (int64, error) { rid, err := zx.AbsPath(rid) if err != nil { return 0, err } if rid == "/Ctl" { return t.getCtl(off, count, dc, cs) } path := zx.Path(t.path, rid) fd, err := os.Open(path) if err==nil && t.ai!=nil && !t.NoPermCheck { _, _, err = t.canWalkTo(rid, 0444) } if err != nil { return 0, err } defer fd.Close() st, err := fd.Stat() if err != nil { return 0, err } if off!=0 && !st.IsDir() { if _, err := fd.Seek(off, 0); err != nil { return 0, err } } if st.IsDir() { ds, err := ioutil.ReadDir(path) nd := 0 tot := 0 ctlsent := false var xds map[string]zx.Dir if t.readattrs { xds, _ = t.dirAttrs(path) } Dloop: for i := 0; i < len(ds); { if off > 0 { off-- if !ctlsent && rid=="/" { ctlsent = true } else { i++ } continue } switch count { case zx.All: break case 0: break Dloop default: count-- } if !ctlsent && rid=="/" { ctlsent = true nd++ d := ctldir n, _ := d.Send(dc) nd++ // but not i++ tot += n continue } fi := ds[i] if fi.Name() == afname { if i == len(ds)-1 { break } ds = append(ds[:i], ds[i+1:]...) fi = ds[i] } cpath := zx.Path(path, fi.Name()) n := 0 sum := "" if fi.IsDir() { n, sum = dirsz(cpath) } d := zx.NewDir(fi, n) d["path"] = zx.Path(rid, fi.Name()) d["spath"] = d["path"] d["tpath"] = t.path if t.readattrs { if xd, ok := xds[fi.Name()]; ok { for k, v := range xd { if zx.IsUpper(k) { d[k] = v } } } else { d["Uid"] = dbg.Usr d["Gid"] = dbg.Usr } } if sum != "" { d["Sum"] = sum } cs.Send(0) n, err := d.Send(dc) if err != nil { return int64(tot), err } nd++ i++ tot += n } return int64(tot), err } if count == zx.All { cs.Sending() nm, n, err := nchan.ReadBytesFrom(fd, dc) cs.Sends(nm, n) return n, err } rr := io.LimitReader(fd, count) cs.Sending() nm, n, err := nchan.ReadBytesFrom(rr, dc) cs.Sends(nm, n) return n, err }