func (pf *ProxyFile) Stat() (protocol.Stat, error) { if err := pf.updateInfo(); err != nil { return protocol.Stat{}, err } pf.cache(true) defer pf.cache(false) var err error st := protocol.Stat{} st.Qid, err = pf.Qid() if err != nil { return protocol.Stat{}, err } st.Mode = protocol.FileMode(pf.info.Mode() & 0777) if pf.info.IsDir() { st.Mode |= protocol.DMDIR } st.Atime = uint32(pf.info.ModTime().Unix()) st.Mtime = st.Mtime st.Length = uint64(pf.info.Size()) st.Name = filepath.Base(pf.path) st.UID = pf.user st.GID = pf.user st.MUID = pf.user return st, nil }
func (c *Client) Create(name string, directory bool) error { dir := path.Dir(name) file := path.Base(name) fid, _, err := c.walkTo(dir) if err != nil { return err } defer c.clunk(fid) perms := protocol.FileMode(0755) if directory { perms |= protocol.DMDIR } creq := &protocol.CreateRequest{ Tag: c.c.NextTag(), Fid: fid, Name: file, Permissions: perms, Mode: protocol.OREAD, } _, err = c.c.Create(creq) if err != nil { return err } return nil }
func setStat(user string, e File, parent Dir, nstat protocol.Stat) error { ostat, err := e.Stat() if err != nil { return err } needWrite := false rename := false curname := "" newname := "" if nstat.Type != ^uint16(0) && nstat.Type != ostat.Type { return errors.New("it is illegal to modify type") } if nstat.Dev != ^uint32(0) && nstat.Dev != ostat.Dev { return errors.New("it is illegal to modify dev") } if nstat.Mode != ^protocol.FileMode(0) && nstat.Mode != ostat.Mode { // TODO Ensure we don't flip DMDIR if user != ostat.UID { return errors.New("only owner can change mode") } ostat.Mode = ostat.Mode&protocol.DMDIR | nstat.Mode & ^protocol.DMDIR } if nstat.Atime != ^uint32(0) && nstat.Atime != ostat.Atime { return errors.New("it is illegal to modify atime") } if nstat.Mtime != ^uint32(0) && nstat.Mtime != ostat.Mtime { if user != ostat.UID { return errors.New("only owner can change mtime") } needWrite = true ostat.Mtime = nstat.Mtime } if nstat.Length != ^uint64(0) && nstat.Length != ostat.Length { if ostat.Mode&protocol.DMDIR != 0 { return errors.New("cannot set length of directory") } if nstat.Length > ostat.Length { return errors.New("cannot extend length") } ostat.Length = nstat.Length } if nstat.Name != "" && nstat.Name != ostat.Name { if parent != nil { curname = ostat.Name newname = nstat.Name ostat.Name = nstat.Name rename = true } else { return errors.New("it is illegal to rename root") } } if nstat.UID != "" && nstat.UID != ostat.UID { // NOTE: It is normally illegal to change the file owner, but we are a bit more relaxed. ostat.UID = nstat.UID needWrite = true } if nstat.GID != "" && nstat.GID != ostat.GID { ostat.GID = nstat.GID needWrite = true } if nstat.MUID != "" && nstat.MUID != ostat.MUID { return errors.New("it is illegal to modify muid") } if needWrite { x, err := e.Open(user, protocol.OWRITE) if err != nil { return err } x.Close() } // Try to perform the rename if rename { if err := parent.Rename(user, curname, newname); err != nil { return err } } return e.WriteStat(ostat) }