예제 #1
0
func (t *Lfs) fileAttrs(fpath string, d zx.Dir) {
	dpath := path.Dir(fpath)
	ds, _ := t.dirAttrs(dpath)
	if len(ds) >= 0 {
		xd := ds[d["name"]]
		if xd["name"] == d["name"] {
			ty, m, s := xd["type"], xd["mtime"], xd["size"]
			for k, v := range xd {
				if zx.IsUpper(k) {
					d[k] = v
				}
			}
			if d["type"] == "-" && t.saveattrs &&
				((d["Sum"] == "" && DoSum) || d["type"] != ty ||
					d["mtime"] != m || d["size"] != s) {
				fi, err := os.Stat(fpath)
				if err == nil {
					xd["type"] = "-"
					xd.SetTime("mtime", fi.ModTime())
					xd["size"] = strconv.FormatInt(fi.Size(), 10)
				}
				if DoSum {
					xd["Sum"] = newFileSum(fpath)
					d["Sum"] = xd["Sum"]
				}
				fn := path.Join(dpath, afname)
				appAttrFile(fn, xd.Pack())
			}
			setUids(d)
			return
		}
	}
	setUids(d)
}
예제 #2
0
func saveAttrs(dpath string, d zx.Dir) {
	nd := zx.Dir{"name": d["name"]}
	for k, v := range d {
		if zx.IsUpper(k) {
			nd[k] = v
		}
	}
	if len(nd) == 1 {
		return
	}
	dprintf("wrattr %s/%s %v\n", dpath, d["name"], nd)
	fn := path.Join(dpath, afname)
	fd, err := os.OpenFile(fn, os.O_WRONLY|os.O_APPEND, 0600)
	if err != nil {
		fd, err = os.OpenFile(fn, os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0600)
	}
	if err != nil {
		return
	}
	defer fd.Close()
	fd.Write(nd.Pack())
}
예제 #3
0
func (t *Lfs) writeFileAttrs(fpath string, d zx.Dir) error {
	dpath := path.Dir(fpath)
	ds, _ := t.dirAttrs(dpath)
	nm := path.Base(fpath)
	od := ds[nm]
	if od == nil {
		od = zx.Dir{}
	}
	od["name"] = nm
	if d["type"] != "d" && (d["size"] == "" || d["type"] == "" || d["mtime"] == "") {
		// record type, size, and mtime for files, to know when to recompute Sum
		fi, err := os.Stat(fpath)
		if err == nil && !fi.IsDir() {
			od["type"] = "-"
			od.SetTime("mtime", fi.ModTime())
			od["size"] = strconv.FormatInt(fi.Size(), 10)
		}
	}
	for k, v := range d {
		if zx.IsUpper(k) {
			if v == "" {
				delete(od, k)
			} else {
				od[k] = v
			}
		}
	}
	if len(od) == 0 {
		return nil
	}
	fn := path.Join(dpath, afname)
	if !DoSum {
		delete(od, "Sum")
	}
	return appAttrFile(fn, od.Pack())
}
예제 #4
0
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
}