func (*NopSrv) Wstat(req *go9p.SrvReq) { // log.Printf("wstat: %p", req) // req.RespondError(errors.New("wstat: ...")) req.RespondRwstat() }
// Wstat updates file info. func (fs *fileSystem) Wstat(req *go9p.SrvReq) { aux := req.Fid.Aux.(*Aux) if err := aux.stat(); err != nil { req.RespondError(err) return } // Add to writeset. fs.addToWriteset(aux.rootID, aux.path) 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 } } err := os.Chmod(aux.path, os.FileMode(mode)) if err != nil { req.RespondError(toError(err)) 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 { var err error uid, err = lookupUser(dir.Uid) if err != nil { req.RespondError(err) return } gid, err = lookupGroup(dir.Gid) if err != nil { req.RespondError(err) return } } if uid != go9p.NOUID || gid != go9p.NOUID { err := os.Chown(aux.path, int(uid), int(gid)) if err != nil { req.RespondError(toError(err)) return } } if dir.Name != "" { // if first char is / it is relative to root, else relative to cwd. var destpath string if dir.Name[0] == '/' { destpath = path.Join(fs.path, dir.Name) fmt.Printf("/ results in %s\n", destpath) } else { auxdir, _ := path.Split(aux.path) destpath = path.Join(auxdir, dir.Name) fmt.Printf("rel results in %s\n", destpath) } err := syscall.Rename(aux.path, destpath) fmt.Printf("rename %s to %s gets %v\n", aux.path, destpath, err) if err != nil { req.RespondError(toError(err)) return } aux.path = destpath } // Set file size, if specified. if dir.Length != 0xFFFFFFFFFFFFFFFF { if err := os.Truncate(aux.path, int64(dir.Length)); err != nil { req.RespondError(toError(err)) return } } // If either mtime or atime need to be changed, then we must change both. if dir.Mtime != ^uint32(0) || dir.Atime != ^uint32(0) { mtime := time.Unix(int64(dir.Mtime), 0) atime := time.Unix(int64(dir.Atime), 0) mtimeChanged := (dir.Mtime == ^uint32(0)) atimeChanged := (dir.Atime == ^uint32(0)) if mtimeChanged || atimeChanged { st, err := os.Stat(aux.path) if err != nil { req.RespondError(toError(err)) return } else if mtimeChanged { mtime = st.ModTime() } } if err := os.Chtimes(aux.path, atime, mtime); err != nil { req.RespondError(toError(err)) return } } req.RespondRwstat() }