func (t *Lfs) stat(rid string) (zx.Dir, error) { rid, err := zx.AbsPath(rid) if err != nil { return nil, err } if rid == "/Ctl" { d := ctldir.Dup() d["tpath"] = t.path return d, nil } path := zx.Path(t.path, rid) st, err := os.Stat(path) if err != nil { return nil, err } nd := 0 sum := "" if st.IsDir() { nd, sum = dirsz(path) if rid == "/" { nd++ } } d := zx.NewDir(st, nd) if t.readattrs { t.fileAttrs(path, d) } if sum != "" { d["Sum"] = sum } d["tpath"] = t.path d["path"] = rid d["spath"] = rid d["proto"] = "lfs" if rid == "/" { d["name"] = "/" } if d["Uid"] == "" { d["Uid"] = dbg.Usr } if d["Gid"] == "" { d["Gid"] = dbg.Usr } if d["Wuid"] == "" { d["Wuid"] = dbg.Usr } return d, nil }
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 }