func (*Ufs) Wstat(req *srv.Req) { fid := req.Fid.Aux.(*Fid) err := fid.stat() if err != nil { req.RespondError(err) return } dir := &req.Tc.Dir if dir.Mode != 0xFFFFFFFF { mode := dir.Mode & 0777 if req.Conn.Dotu { if dir.Mode&go9p.DMSETUID > 0 { mode |= syscall.S_ISUID } if dir.Mode&go9p.DMSETGID > 0 { mode |= syscall.S_ISGID } } e := os.Chmod(fid.path, os.FileMode(mode)) if e != nil { req.RespondError(toError(e)) return } } uid, gid := go9p.NOUID, go9p.NOUID if req.Conn.Dotu { uid = dir.Uidnum gid = dir.Gidnum } // Try to find local uid, gid by name. if (dir.Uid != "" || dir.Gid != "") && !req.Conn.Dotu { uid, err = lookup(dir.Uid, false) if err != nil { req.RespondError(err) return } // BUG(akumar): Lookup will never find gids // corresponding to group names, because // it only operates on user names. gid, err = lookup(dir.Gid, true) if err != nil { req.RespondError(err) return } } if uid != go9p.NOUID || gid != go9p.NOUID { e := os.Chown(fid.path, int(uid), int(gid)) if e != nil { req.RespondError(toError(e)) return } } if dir.Name != "" { path := fid.path[0:strings.LastIndex(fid.path, "/")+1] + "/" + dir.Name err := syscall.Rename(fid.path, path) if err != nil { req.RespondError(toError(err)) return } fid.path = path } if dir.Length != 0xFFFFFFFFFFFFFFFF { e := os.Truncate(fid.path, int64(dir.Length)) if e != nil { req.RespondError(toError(e)) return } } // If either mtime or atime need to be changed, then // we must change both. if dir.Mtime != ^uint32(0) || dir.Atime != ^uint32(0) { mt, at := time.Unix(int64(dir.Mtime), 0), time.Unix(int64(dir.Atime), 0) if cmt, cat := (dir.Mtime == ^uint32(0)), (dir.Atime == ^uint32(0)); cmt || cat { st, e := os.Stat(fid.path) if e != nil { req.RespondError(toError(e)) return } switch cmt { case true: mt = st.ModTime() default: at = atime(st.Sys().(*syscall.Stat_t)) } } e := os.Chtimes(fid.path, at, mt) if e != nil { req.RespondError(toError(e)) return } } req.RespondRwstat() }